Redis Sharding(分片)技術學習
1.redis cluster介紹
redis cluster在3.0版本或者以上版本提供,採用sharding技術。Sharding採用slot(槽)的概念,一共分成16384個槽。對於每個進入Redis的鍵值對,根據key進行雜湊,分配到這16384個slot中的某一箇中。使用的hash演算法也比較簡單,就是CRC16後16384取模。Redis叢集中的每個node(節點)負責分攤這16384個slot中的一部分,也就是說,每個slot都對應一個node負責處理。當動態新增或減少node節點時,需要將16384個槽做個再分配,槽中的鍵值也要遷移。當然,這一過程,在目前實現中,還處於半自動狀態,需要人工介入。
2.redis sharding技術
2.1.在redis3.0版本之前的版本,通過redis客戶端做sharding分片,比如jedis
過程如下:
- 採用一致性雜湊演算法(consistent hashing),將key和節點name同時hashing,然後進行對映匹配,採用的演算法是MURMUR_HASH。採用一致性雜湊而不是採用簡單類似雜湊求模對映的主要原因是當增加或減少節點時,不會產生由於重新匹配造成的rehashing。一致性雜湊隻影響相鄰節點key分配,影響量小。
為了避免一致性雜湊隻影響相鄰節點造成節點分配壓力,ShardedJedis會對每個Redis節點根據名字(沒有,Jedis會賦予預設名字)會虛擬化出160個虛擬節點進行雜湊。根據權重weight,也可虛擬化出160倍數的虛擬節點。用虛擬節點做對映匹配,可以在增加或減少Redis節點時,key在各Redis節點移動再分配更均勻,而不是隻有相鄰節點受影響。
ShardedJedis支援keyTagPattern模式,即抽取key的一部分keyTag做sharding,這樣通過合理命名key,可以將一組相關聯的key放入同一個Redis節點,這在避免跨節點訪問相關資料時很重要。
2.2.jedis sharding程式碼示例
public ShardedJedisPool shardedJedisPool() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(1000 * 10);
List<JedisShardInfo> shardInfoList = new ArrayList<>(3);
JedisShardInfo shardInfo0 = new JedisShardInfo(host0, port0);
JedisShardInfo shardInfo1 = new JedisShardInfo(host1, port1);
JedisShardInfo shardInfo2 = new JedisShardInfo(host2, port2);
shardInfoList.add(shardInfo0);
shardInfoList.add(shardInfo1);
shardInfoList.add(shardInfo2);
return new ShardedJedisPool(jedisPoolConfig, shardInfoList,
Hashing.MURMUR_HASH, Sharded.DEFAULT_KEY_TAG_PATTERN);
}