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);
}