基于sentinel的redis集群的客戶端:RedisSentinelClient

jopen 9年前發布 | 58K 次閱讀 Redis NoSQL數據庫 RedisSentinelClient

基于sentinel的redis集群的客戶端, 支持自動主從切換, 采用ketama作為一致性hash算法
</div>

介紹

sentinel-client使用Redis做單節點的數據存儲,Sentinel做高可用服務的K-V存儲集群。

高可用方案簡介

高可用方案是基于Redis官方提供的Sentinel實現的.Sentinel的作用是對Redis實例的監控、通知、容災備份,是Redis集群的管理工具。在一個Redis集群中Sentinel作為中心監控各個節點的工作狀態,提升系統的高可用性。詳細的官方文檔見:http://redis.io/topics/sentinel

一致性Hash

數據的分布式存儲采用的是一致性Hash算法,這里做了些改動,對于客戶存儲的key,實際在redis中存儲的結構是bid_key bid 是應用程序按照業務來做的邏輯劃分 key 是客戶存儲的key

環境依賴

1.CentOS release 6.5
2.libssl.so
3.依賴的redis的配置項databases的值設置為1024

Log

在程序的執行目錄下會生成log文件(./redis_client_log.txt)
    使用libkvdb.so出問題時請先查看./redis_client_log.txt

Install All

```編譯c++, java, python tar -zxvf sentinel-client.tar.gz cd sentinel-client make 完成后在sentinel-client目錄下生成libkvdb.so(c++), kvdb.jar(java) pykvdb.so(python)

## Install c++
```編譯c++
    tar -zxvf sentinel-client.tar.gz
    cd sentinel-client/cpp
    make
    完成后在sentinel-client/cpp目錄下生成libkvdb.so
    將libkvdb.so的目錄加入到環境變量LD_LIBRARY_PATH中

Install java

tar -zxvf sentinel-client.tar.gz
    cd sentinel-client/cpp && make
    cd sentinel-client/java/jni && make
    cd sentinel-client/java && ant
    完成后在sentinel-client/java目錄下生成kvdb.jar
    由于kvdb.jar需要在/tmp目錄下寫臨時的so文件,因此需要將/tmp目錄加入環境變量LD_LIBRARY_PATH中
    export LD_LIBRARY_PATH=/tmp:${LD_LIBRARY_PATH}

Install python

tar -zxvf sentinel-client.tar.gz
    cd sentinel-client/cpp && make
    cd sentinel-client/python && make
    完成后在sentinel-client/python目錄下生成libkvdb.so和pykvdb.so
    將libkvdb.so和pykvdb.so的目錄加入到環境變量LD_LIBRARY_PATH和PYTHON_PATH中

TestAll

```test all cd sentinel-client make test 注:需要將sentinel-client/cpp/3party目錄加入到環境變量LD_LIBRARY_PATH中

## TestC++
```test c++
    cd sentinel-client/cpp
    make test
    注:需要將sentinel-client/cpp/3party目錄加入到環境變量LD_LIBRARY_PATH中

TestJava

```test java cd sentinel-client/java ant -f buildtest.xml java -jar kvdbtest.jar

## C++ Demo
```c++
// 實例化客戶端
#include "RedisClient.h"
RedisClient client = RedisClient("{{sentinel ip list}}", "{{business id}}");
// 方法1:使用封裝好的接口
// GET
string value = client.get("my_key");
// SET
bool valid = client.set("test_key", "test_value")

// 方法2:使用自定義命令的接口
Reply reply = client.RedisCommand(Command("GET")("my_key"));
if (reply.error()) {
  // 處理獲取失敗的邏輯 
}
string value = reply.str();

Member functions of Reply

Reply
    \_type()      #獲取返回值類型 
    \_str()       #獲取字符處返回值 
    \_integer()   #獲取整形返回值
    \_elements()  #獲取list類型返回值 
    \_error()     #命令是否執行失敗

Python Demo

import pykvdb
client = pykvdb.newClient('{{sentinel ip list}}','{{your business id}}')
pykvdb.set(client, 'mykey', 'myvalue')
print pykvdb.get(client, 'mykey')

備注

ae事件庫中使用的zmalloc和Python的Impot_Module不兼容,使用時需要將zmalloc、zfree替換為malloc和free

Java Demo

import com.redis.sentinel.client.RedisClient;

RedisClient client = new RedisClient("127.0.0.1:26379", "item");
boolean ret = client.set("kkk", "vvv");
String v = client.get("kkk");

Proxy

cd sentinel-client/proxy/
make
vi etc/kvproxy.ini
./bin/bfdproxy &

備注

1.proxy是基于kvproxy擴展的對redis的支持 2.proxy內部調用redis-sentinel-client的cpp客戶端 3.proxy支持原生的redis協議 4.由于redis-sentinel-client的cpp客戶端的使用了 business_id,所以如果使用proxy訪問以前通過redis-sentinel-client寫入的數據,則需要用戶自己處理business_id. 例:

  1.之前通過redis-sentinel-client寫入數據:

     RedisClient client("127.0.0.1:16379", "item");
     client.set("kk", "vv");


     現在通過hiredis訪問proxy獲取數據:

     string business_id = "item_";
     string key = business_id + "kk";
     string command = string("GET ") + key;
     redisReply *reply = (redisReply *)redisCommand(cc,command.c_str());

    2.之前通過redis-sentinel-client寫入數據:
     RedisClient client("127.0.0.1:16379");
     client.set("kk", "vv");    
     RedisClient 的構造函數的第二個參數的默認值為"item", 訪問proxy時仍然需要對key加上 "item_"前綴

項目主頁:http://www.baiduhome.net/lib/view/home/1440420567575

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!