使用jedis操作redis cluster,我們需要建立jediscluster物件,再通過jediscluster物件例項運算元據,**一般如下:
// 初始化所有節點(例如6個節點)
setjedisclusternode = new hashset() };
// 初始化commnon-pool連線池,並設定相關引數
genericobjectpoolconfig poolconfig = new genericobjectpoolconfig();
// 初始化jediscluster
jediscluster jediscluster = new jediscluster(jedisclusternode, 1000, 1000, 5, poolconfig);
下面我們詳細了解下jediscluster的建立邏輯,其建構函式核心功能為建立connectionhandler例項,jedisclusterconnectionhandler的建構函式如下:
public jedisclusterconnectionhandler(setnodes,
final genericobjectpoolconfig poolconfig, int connectiontimeout,
int sotimeout, string password, string clientname,
boolean ssl, sslsocketfactory sslsocketfactory, sslparameters sslparameters,
hostnameverifier hostnameverifier, jedisclusterhostandportmap portmap)
其中重點需要關注的是initializeslotscache方法,該方法主要初始化集群中槽和節點的對映關係,下面簡單介紹下redis cluster的資料分割槽和路由方案。
redis cluster使用虛擬槽資料分割槽方案,每個節點維護部分槽和資料,當需要讀取資料時,使用"crc16(key) & 16383"雜湊演算法得到key所在的槽,redis cluster本身會維護節點和槽的資訊。
當你使用dummy型客戶端(例如redis-cli)在某個不具備該槽的節點上執行讀取指令時,redis cluster會返回"moved"重定向資訊,告訴我們該槽所在節點的ip和埠資訊,然後就可以到相應的節點上執行命令讀取資料。該型別的客戶端需要我們自行進行重定向操作,相對不方便。
而jedis等smart型客戶端本身就維護了槽和節點的對映關係,通過"crc16(key) & 16383"雜湊演算法得到key所在的槽後,就可以通過對映關係找到對應的節點,然後直接給該節點傳送指令返回資料。
下面為initializeslotscache方法原始碼:
private void initializeslotscache(setstartnodes,
int connectiontimeout, int sotimeout, string password, string clientname,
boolean ssl, sslsocketfactory sslsocketfactory, sslparameters sslparameters, hostnameverifier hostnameverifier)
if (clientname != null)
cache.discoverclusternodesandslots(jedis);
break;
} catch (jedisconnectionexception e) finally
}}}
需要注意的是,由於discoverclusternodesandslots內使用了writelock寫鎖,因此保證了只有乙個連線會初始化節點和槽的對映關係。
重點分析下discoverclusternodesandslots方法:
public void discoverclusternodesandslots(jedis jedis)
//解析出所負責的的所有槽
listslotnums = getassignedslotarray(slotinfo);
// hostinfos
/*** 解析主節點和從節點資訊,構建槽和節點的對映關係:
* 1. 新增nodes元素,key為":",value為該節點對應的jedispool連線池
* 2. 新增slots元素,key為"slotnum",value為該槽對應節點的jedispool連線池
*/int size = slotinfo.size();
for (int i = master_node_index; i < size; i++)
//獲取節點ip埠資訊
hostandport targetnode = generatehostandport(hostinfos);
//設定nodes,map.entry結構為//從節點和主節點都會進行儲存
setupnodeifnotexist(targetnode);
if (i == master_node_index) }}
} finally
}
維護節點和槽的對映關係主要通過jedisclusterinfocache裡面的兩個map型別的變數:
private final map nodes = new hashmap();該方法的主要流程如下:private final map slots = new hashmap();
1. 清空nodes和slots資料,並關閉關聯的jedispool。
2. 使用"cluster slots"指令獲取cluster節點和槽的對映關係,其返回結構如下:
127.0.0.1:6379> cluster slots
1) 1) (integer) 5462 . -- 起始槽
2) (integer) 10922 . -- 終止槽
3) 1) "127.0.0.1" . -- 主節點ip
2) (integer) 6380 -- 主節點埠
3) "85371dd3c2c11dbb1cd506ed028de10bb7fa2816" -- 主節點runid
4) 1) "127.0.0.1" . -- 從節點ip
2) (integer) 6383 -- 從節點埠
3) "01740d2eb2c9f89014e2b8b673d444753d0685cd" -- 從節點runid
2) 1) (integer) 10923
2) (integer) 16383
3) 1) "127.0.0.1"
2) (integer) 6381
3) "aacad0a5a2b37d4e11f2253849263575adb78740"
4) 1) "127.0.0.1"
2) (integer) 6384
3) "5e099198bba08597d695f6e2e3db2d6ec1494534"
3) 1) (integer) 0
2) (integer) 5461
3) 1) "127.0.0.1"
2) (integer) 6379
3) "672cc8350bb1ac1d94e9c511ea234f6b7f86cab1"
4) 1) "127.0.0.1"
2) (integer) 6382
3) "6bab67c3619c4b9cbdfd247ff3e446308a0c6326"
3. 解析出所負責的的所有槽,**如下:
private listgetassignedslotarray(listslotinfo)
return slotnums;
}
slotnums的數量即為該主節點所負責的槽的數量。
4. 解析主節點和從節點資訊,構建槽和節點的對映關係。
值得注意的是,nodes裡面會儲存主節點和從節點的資訊,但是slots裡面槽只對應主節點的連線池jedispool,從節點並需要設定。
最後值得一提的是,jedis連線sentinel時,連線的是sentinel集群,通過「mastername」引數獲取sentinel集群監控的主節點連線,後續的操作也是通過該主節點連線執行。但連線cluster時,其實連線的是每個redis例項,讀取資料時會根據jedis維護的槽和節點對映關係去對應的節點上讀取。
jediscluster關閉**如下:
jediscluster.close();其關閉原始碼邏輯主要呼叫jedisclusterinfocache類的reset方法,該方法關閉了所有集群節點的連線,並將nodes和slots資料清空。
//binaryjediscluster類
@override
public void close()
}//jedisclusterconnectionhandler類
@override
public void close()
//jedisclusterinfocache類
public void reset()
} catch (exception e)
}nodes.clear();
slots.clear();
} finally
}
Jedis事務詳解
1 正常執行的事務 編碼測試 package com.haiyang import com.alibaba.fastjson.jsonobject import redis.clients.jedis.jedis import redis.clients.jedis.transaction publ...
jedis操作詳解 List
在redis 中,list 型別是按照插入順序排序的字串鍊錶。和資料結構中的普通鍊錶一樣,我們可以在其頭部 left 和尾部 right 新增新的元素。在插入時,如果該鍵並不存在,redis 將為該鍵建立乙個新的鍊錶。與此相反,如果鍊錶中所有的元素均被移除,那麼該鍵也將會被從資料庫中刪除。list ...
jedis 連線池配置詳解
最大活動物件數 redis.pool.maxtotal 1000 最大能夠保持idel狀態的物件數 redis.pool.maxidle 100 最小能夠保持idel狀態的物件數 redis.pool.minidle 50 當池內沒有返回物件時,最大等待時間 redis.pool.maxwaitmi...