Jedis源碼分析共有四個章節,以下為各章連結:
- Jedis源碼分析(一)-Jedis介紹
- Jedis源碼分析(二)-Jedis類結構及實作
- Jedis源碼分析(三)- JedisCluster類結構及實作
- Jedis源碼分析(四)-JedisSentinel與ShardedJedis介紹
1 JedisSentinel
JedisSentinel常用方式有兩種:
1.使用哨兵單節點拿到主節點,從節點的資訊
//通過哨兵節點的資訊建立Jedis執行個體,然後拿到Master節點的資訊
Jedis j = new Jedis(sentinel);
List<Map<String, String>> masters = j.sentinelMasters();
//拿到master的address,**MASTER_NAME**
List<String> masterHostAndPort = j.sentinelGetMasterAddrByName(**MASTER_NAME**);
HostAndPort masterFromSentinel = new HostAndPort(masterHostAndPort.get(0),Integer.parseInt(masterHostAndPort.get(1)));
assertEquals(master, masterFromSentinel);
//通過哨兵節點,拿到從節點的資訊
List<Map<String, String>> slaves = j.sentinelSlaves(**MASTER_NAME**);
2.使用哨兵節點對象池
Set<String> sentinels = new HashSet<String>();
sentinels.add(new HostAndPort("localhost", 65432).toString());
sentinels.add(new HostAndPort("localhost", 65431).toString());
JedisSentinelPool pool = new JedisSentinelPool(MASTER_NAME, sentinels);
pool.destroy();
JedisSentinelPool
的結構清晰,内部使用對象池存放一個個
sentinel
執行個體。圖2-12和2-13分别為
JedisSentinelPool
的類結構和初始化流程。在使用時,我們先根據,host,port等資訊,初始化一個Jedis執行個體,然後可以通過
sentinelMasters()
,
sentinelGetMasterAddrByName(MASTER_NAME)
,
sentinelSlaves(MASTER_NAME)
等方法拿到這個哨兵節點監聽的MASTER節點資訊或對應的SLAVE節點資訊。
圖1.1 JedisSentinelPool 的類結構
圖1.2 JedisSentinelPool 的初始化流程
2 ShardedJedis
下文為建構Jedis分片的方法(單節點與對象池的模式),
- 單節點模式
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>(2);
//其中一個分片
JedisShardInfo shard1 = new JedisShardInfo(redis1);
shards.add(shard1);
//另一個分片
JedisShardInfo shard2 = new JedisShardInfo(redis2);
shards.add(shard2);
@SuppressWarnings("resource")
//建立ShardedJedis執行個體
ShardedJedis shardedJedis = new ShardedJedis(shards);
shardedJedis.set("a", "bar");
//通過key可以檢視存儲在哪個jedis
JedisShardInfo ak = shardedJedis.getShardInfo("a");
assertEquals(shard2, ak);
- 對象池模式
ShardedJedisPool pool = new ShardedJedisPool(new GenericObjectPoolConfig(), shards);
ShardedJedis jedis = pool.getResource();
jedis.set("foo", "bar");
assertEquals("bar", jedis.get("foo"));
圖2-1 ShardedJedis的類結構
圖2-2 ShardedJedis的初始化流程
圖2-1為ShardedJedis的類結構(其内部儲存一個對象池,與正常的JedisPool的不同之處在于,内部的
PooledObjectFactory
實作不同),分片資訊儲存在基類
Sharded
中,
Sharded
儲存了3個重要變量:
- nodes是一個TreeMap,儲存了每個分片節點和對應的hash值。
- algo是計算hash值的函數,預設是MurmurHash,可替換。
- resources是一個LinkedHashMap,存放着JedisShardinfo和一個Jedis執行個體的對應關系。
圖2-2為
ShardedJedis
的初始化流程,通過傳入待分片的節點資訊,初始化好上述3個變量。在使用時,先根據key計算出hash值,在
nodes
中找到對應的分片資訊,再在
resources
中找到對應的Jedis執行個體,然後通過這個Jedis執行個體才操作redis節點。