支援叢集版 redis 的客戶端例子
據 redis 官方網站顯示,支援叢集版的 redis3.0 快要釋出了(現在已經到了redis3.0 rc4 版本),這樣使用者就不需要自己花很大力氣來針對 redis 進行分庫了,之前人們為了使單機版的 redis 能支援叢集方式,往往是在客戶端或通過加一箇中間的代理層(比如使用 tweaproxy)做很多工作,現在有了叢集版的 redis3.0 ,這些額外的操作都不再需要。
為了能夠支援叢集版的 redis 服務,另外增加了兩個主要的重定向指令需要客戶端能夠支援:MOVE, ASK。其中以 MOVE 指令為例,之所以增加此重定向指令,主要是考慮效率的因素,redis-server 叢集以雜湊槽的方式存放資料(目前最大是 16384 個雜湊槽),各個 redis-server 結點都會記錄著每個雜湊槽所在的最終結點的位置,所以當 redis 客戶端訪問一個 redis-server 時,如果該服務結點在計算完雜湊槽後發現該雜湊槽在別的服務結點上,則會給客戶端返回一個重定向指令(如:MOVE hash_slot ip:port),客戶端在獲得此重定向指令後會去連線最終的服務結點;另外,不了儘量減少重定向次數(有利於提高處理效率),官方協議文件中建議客戶端 應該快取住雜湊槽的儲存位置。
雖然叢集版本的 redis3.0 即將釋出,但目前主要的問題是缺乏客戶端的支援(目前據說可以支援的只有少數的幾個客戶端庫:象JAVA版的 jedis,ruby 版本),尤其是 C/C++ 客戶端庫更是匱乏,好訊息是 acl 庫中的 redis 客戶端模組已經很好地支援叢集 redis3.0 了,該庫不僅支援 redis 的重定向指令及雜湊槽的自動快取及自動更新功能,同時還支援 redis 服務結點自動釋出機制,即在初始 acl redis 客戶端庫時只需新增 一個或多個 redis 伺服器結點地址,在執行過程中會根據伺服器返回的重定向資訊動態新增新的 redis 伺服器結點。下面是使用 acl redis 庫叢集版本的例子:
#include "acl_cpp/lib_acl.hpp"
static void test_redis_string(acl::redis_string& cmd, const char* key)
{
acl::string val("test_value");
// 向 redis 叢集中新增一條字串型別的資料物件
// 對應的 redis 命令:SET key value
if (cmd.set(key, val.c_str()) == false)
{
printf("redis set error\r\n");
return;
}
else
printf("redis set ok\r\n");
// 清除緩衝區
val.clear();
// 重置 redis 客戶端命令的狀態,以便可以複用該操作物件
cmd.reset();
// 從 redis 叢集中獲取指定鍵值的資料
if (cmd.get(key, val) == false)
printf("get key error\r\n");
else
printf("get key ok, value: %s\r\n", val.c_str());
}
static void test_redis_key(acl::redis_key& cmd, const char* key)
{
// 查詢給定鍵在 redis 服務端是否存在
if (cmd_key.exists(key) == false)
printf("key not exists\r\n");
else
printf("key exists\r\n");
}
int main(void)
{
const char* redis_addr = "127.0.0.1:6379";
int conn_timeout = 10, rw_timeout = 10, max_conns = 100;
// 定義 redis 客戶端叢集管理物件
acl::redis_client_cluster cluster;
// 新增一個 redis 服務結點,可以多次呼叫此函式新增多個服務結點,
// 因為 acl redis 模組支援 redis 服務結點的自動發現及動態新增
// 功能,所以新增一個服務結點即可
cluster.set(redis_addr, max_conns);
// redis 字串類 (STRING) 操作物件
acl::redis_string cmd_string;
// redis 鍵值類(KEY) 操作物件
acl::redis_key cmd_key;
// 給 redis 操作物件繫結 redis 客戶端叢集物件
cmd_string.set_cluster(&cluster, max_conns);
cmd_key.set_cluster(&cluster, max_conns);
const char* key = "test_key";
// redis 叢集命令操作的測試過程
test_redis_string(cmd_string, key);
test_redis_key(cmd_key, key);
return 0;
}
參考:
1、acl 庫地址:https://github.com/zhengshuxin/acl
2、acl redis 標頭檔案地址:https://github.com/zhengshuxin/acl/tree/master/lib_acl_cpp/include/acl_cpp/redis
3、acl redis 原始檔地址:https://github.com/zhengshuxin/acl/tree/master/lib_acl_cpp/src/redis
4、acl redis 示例地址:https://github.com/zhengshuxin/acl/tree/master/lib_acl_cpp/samples/redis
5、acl QQ 群:242722074
6、微博:http://weibo.com/zsxxsz/
FROM: http://zsxxsz.iteye.com/blog/2190387