客户端sharding
Java redis客户端驱动jedis
,已支持Redis Sharding功能,即ShardedJedis以及结合缓存池的ShardedJedisPool, jedis的特点:
- 采用一致性哈希算法(consistent hashing),将key和节点name同时hashing,采用的算法是MURMUR_HASH。采用一致性哈希而不是采用简单类似哈希求模映射的主要原因是当增加或减少节点时,不会产生由于重新匹配造成的rehashing。一致性哈希只影响相邻节点key分配,影响量小。
- ShardedJedis支持keyTagPattern模式,即抽取key的一部分keyTag做sharding,这样通过合理命名key,可以将一组相关联的key放入同一个Redis节点,这在避免跨节点访问相关数据时很重要。
➤ Redis Sharding 方案:
- 通过客户端进行Sharding, 在Client侧做Sharding, 比如 Jedis 提供的 ShardedJedis:
- ShardedJedis特性:
- 使用虚拟节点, 使Key在Redis节点的分布更均匀, 如果一个节点挂掉, 不再是相邻的节点受影响. 每个实体节点默认有160个虚拟节点, ShardedJedis还支持权重, 虚拟节点个数 =
节点权重 x 160
- ShardedJedis使用了
MurMur Hash
做Hash函数,MurMur Hash
相比较一般Hash算法, 对于规律性较强的Key随机分布的表现更好. - 支持
keyTagPattern
模式, 只抽取Key的一部分做Hash, 通过合理命名Key, 可以将相关的Key放入同一个Redis节点.
- 使用虚拟节点, 使Key在Redis节点的分布更均匀, 如果一个节点挂掉, 不再是相邻的节点受影响. 每个实体节点默认有160个虚拟节点, ShardedJedis还支持权重, 虚拟节点个数 =
- 扩容问题 – presharding:
- 需要扩容时, 实际是把小的Redis实例数据复制到大的Redis实例, 复制完成后, 大的Redis实例替换小的Redis实例;
- 需要扩容的Redis设为主, 新Redis设置为从, 完成数据同步后, 原实例的Shard给新实例用
代理中间件(Tair/Codis)
上面分别介绍了多Redis服务器集群的两种方式,它们是基于客户端sharding的Redis Sharding
,和基于服务端sharding的Redis Cluster
。
Pre-Sharding方案实际上可以理解为预先分配一个相当大的集合,对Key哈希的结果落在这个集合中,集合的每个元素又与具体的物理节点存在多对一的路由映射关系,这张路由表由一个配置中心进行维护。
回过头来再细想下,一致性哈希中的虚拟节点,实际上也可以归类到Pre-Sharding方案中。换句话说,只要是key经过两次哈希,第一次Hash到虚拟节点,第二次Hash到物理节点,都可以算作Pre-Sharding。只不过区别在于,一致性哈希的第二次Hash其路由表是按照算法固定的,Tair/Codis的第二次Hash其路由表是第三方可配的。
扩容
详见: Redis集群的数据划分与扩容探讨 - Xueqiu Engineering Blog @Archived