基于sentinel的redis集群的客戶端:RedisSentinelClient
介紹
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_"前綴