编程知识 cdmana.com

Redis Cluster为什么选哈希槽不选一致性哈希?

目录

一、Redis Cluster简介

二、Redis Cluster哈希槽

三、一致性哈希

四、哈希槽和一致性哈希对比


一、Redis Cluster简介

        Redis Cluster也就是Redis集群,redis是基于内存的缓存数据库,由于单台节点的内存是有限的,为了扩展单节点的存储能力,Redis Cluster问世,需要注意的是Redis Cluster不保证Redis的高可用,真正的高可用是主从+哨兵模式。

优势:

  • Redis Cluster能够自动分割数据到不同的节点上;
  • 整个集群的部分节点失败或不可用的情况下,能够继续处理命令。

二、Redis Cluster哈希槽

        Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么节点 A 包含 0 到 5500号哈希槽,节点 B 包含5501 到 11000 号哈希槽,节点 C 包含11001 到 16384号哈希槽。master节点的slave节点不分配槽,只拥有读权限。但是注意在代码中redis cluster执行读写操作的都是master节点,并不是读是从节点,写是主节点。

        使用哈希槽进行扩缩容就会很方便,如果我们想要新添加个节点D, 我们只需要从之前的节点分部分哈希槽到节点D上。 如果我想移除某个节点,只需要将该节点中的哈希槽移到另外两个节点上,然后将该节点从集群中移除即可。从一个节点将哈希槽移动到另一个节点并不会停止服务(渐进式rehash),所以无论添加或是删除节点都不会造成集群的不可用,这样就实现了动态扩缩容。

为什么是16384个槽?

        集群中的各节点在握手成功后,两个节点之间会定期发送ping/pong消息,交换数据信息,在redis节点发送心跳包时需要把所有的槽信息放到这个心跳包里,以便让节点知道当前集群信息,在发送心跳包时使用char进行bitmap压缩后是2k(16384÷8÷1024=2kb),也就是说使用2k的空间创建了16k的槽数。虽然使用CRC16算法最多可以分配65535(2^16-1)个槽位,65535=65k,压缩后就是8k(8 * 8 (8 bit) * 1024(1k) = 8K),也就是说需要需要8k的心跳包,作者认为这样做不太值得;并且一般情况下一个redis集群不会有超过1000个master节点,所以16k的槽位是个比较合适的选择。如果槽位为65536,发送心跳信息的消息头达8k,发送的心跳包过于庞大。redis的集群主节点数量基本不可能超过1000个。集群节点越多,心跳包的消息体内携带的数据越多。如果节点过1000个,也会导致网络拥堵。因此redis作者,不建议redis cluster节点数量超过1000个。槽位越小,节点少的情况下,压缩率高,Redis主节点的配置信息中,它所负责的哈希槽是通过一张bitmap的形式来保存的,在传输过程中,会对bitmap进行压缩,但是如果bitmap的填充率slots / N很高的话(N表示节点数),bitmap的压缩率就很低。如果节点数很少,而哈希槽数量很多的话,bitmap的压缩率就很低。

三、一致性哈希

        一致性哈希用于解决分布式缓存系统中的数据选择节点存储问题和数据选择节点读取问题以及在增删节点后减少数据缓存的消失范畴,防止雪崩的发生。它是一个0到2的32次方的闭合环型结构,占用4个字节,拥有2的32次方个桶空间,每个桶空间可以存储很多数据。

一致性哈希是采用的是如下步骤:

  1. 对节点进行hash,通常使用其节点的ip或者是具有唯一标示的数据进行hash(ip),将其值分布在这个闭合圆上。
  2. 将存储的key进行hash(key),然后将其值要分布在这个闭合圆上。
  3. 从hash(key)在圆上映射的位置开始顺时针方向找到的一个节点即为存储key的节点。如果到圆上的0处都未找到节点,那么0位置后的顺时针方向的第一个节点就是key的存储节点。

添加节点:如果在节点A和节点C中间增加一个节点D,那么在节点A和节点C之间的部分数据要存储的节点就会有所变化,在节点C到节点D之间的数据会从节点A转移到节点D。

删除节点:如果删除一个节点,就会把当前节点所有数据加到它的下一个节点上。这样会导致下一个节点使用率暴增,可能会导致挂掉,如果下一个节点挂掉,下下个节点将会承受更大的压力,最终导致集群雪崩。

节点太少:可能会造成数据倾斜,假设只有俩节点,可能会造成大量数据存放在node A节点上,而node B节点存储很少的数据。

解决办法:

        为了解决雪崩现象和数据倾斜现象,提出了虚拟节点这个概念。就是将真实节点计算多个哈希形成多个虚拟节点并放置到哈希环上,定位算法不变,只是多了一步虚拟节点到真实节点映射的过程。

四、哈希槽和一致性哈希对比

  • 一致性哈希的节点分布基于圆环,无法很好的手动设置数据分布,比如有些节点的硬件差,希望少存一点数据,这种很难操作。而哈希槽可以很灵活的配置每个节点占用哈希槽的数量
  • 一致性哈希的某个节点宕机或者掉线后,当该机器上原本缓存的数据被请求时,会从数据源重新获取数据,并将数据添加到失效机器后面的机器,这个过程被称为 "缓存抖动" ,而使用哈希槽的节点宕机,会导致一定范围内的槽不可用,只能通过主从复制加哨兵模式保证高可用。
  • 真是基于一致性哈希的特点,当某台机器宕机时,极易引起雪崩,如上述介绍中删除节点。
  • Redis Cluster的槽位空间是可以用户手动自定义分配的,类似于 windows 盘分区的概念,可以手动控制大小。
  • 相对于哈希槽,一致性哈希算法更复杂

 

版权声明
本文为[局外人Inside]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_42189550/article/details/126990798

Scroll to Top