Redis学习笔记--集群
集群
是什么?
redis集群是官方推出的高可用解决方案,是在主从复制+哨兵的基础上演进而来的,它解决了主从复制+哨兵单点故障引发的数据丢失问题,有着更高的性能,更全面的功能,尤其是在高可用和数据安全方面。
redis集群是一个提供了在多个redis节点之间共享数据的程序集,集群中可以存在多个master,master下面还有多个salve从节点来做数据同步,当某个master故障后,它的多个slave会被选举为新的master。主节点建议是奇数个,方便管理和扩缩容,集群架构图如下:

能干嘛?
1、多节点:redis集群支持多个master节点,每个master节点下可以挂在多个slave从节点(主从复制结构),因为有主从复制的结构,所以可以实现读写分离、数据高可用、海量数据读写存储。
2、高可用:集群中内置了Sentinel的故障转移机制,支持高可用,无需单独去配置哨兵,是配置更加简单,部署更加容易。、
3、连接简单:连接集群中的redis节点时,无需连接所有节点,只要连接集群中任意一个节点即可,redis内部会自己做读写请求的分发工作。
4、槽位:集群中引入了槽位的概念,槽位slot是用来存储数据的,集群会根据CRC16循环冗余算法,负责将数据分配到各服务器节点,由对应的集群来负责维护节点、插槽和数据之间的关系。
、
槽位slot是什么?
槽位也叫hash槽,槽位可以看作是一种数据容器或索引范围,它是集群对数据管理和分配的基本单位,它决定了数据最终存储在哪个节点上。一个集群内槽位共有16384个,这个数量是固定的,不受节点数的影响,节点会平均分配槽位数量,在实际使用中建议将最大节点是1000个。
redis集群写数据时每个key会根据CRC16循环冗余算法校验后对16384进行取模来决定放到哪个槽位中,读数据时也会使用同样的算法计算槽位在节点中的位置来获取数据,集群中每个节点负责一部分槽位的管理和维护工作。假设当前集群中有3个节点,3个节点会平均分配16384个槽位,槽位的计算方法如下图所示:

分片是什么?
分片是将数据分散存储在多个节点上的过程,目的是为了突破单个节点的数据存储和处理能力。在集群中数据会被划分为多个部分,每个部分就是一个分片。这些分片分部在不同的节点中。
分片和槽位的关系?
分片和槽位之间是多对多的映射关系。槽位是数据存储在分片上的具体位置,一个分片可以包含多个槽位,一个槽位也可以属于多个分片。他们之间的映射关系是通过集群来维护的。通过槽位的计算方法(CRC16循环冗余算法+槽位数16384取模)可以准确的知道数据该存放到哪个位置。
槽位+节点的存储方式的优势是什么?
节点+槽位的存储方式,实景16384个槽位分配到不同的节点上,有如下优势:
1、数据均匀分配:数据的写入会根据槽位的计算方法,写入到对应的槽位中,这样可以保证数据均匀的分配到各个节点上,避免出现单节点数据负载过大而其它节点闲置的情况,充分的利用了每个节点的数据存储能力。
2、可扩展性:当需要对集群中节点进行增减,也就是扩缩容时,新节点的加入或旧节点的退出只需要将部分槽位进行迁移即可。这个过程不需要停止集群的服务,是对高可用性的一种体现。
3、故障转移能力:当某个节点故障时,集群会自动将该节点负责的槽位转移到其它正常的节点上,由于槽位是存储数据的基本单位,这个操作可以迅速完成,从而保证数据的高可用性。同时,也可以在多个从节点中选举出新的主节点来接替旧的主节点的工作。
4、数据管理简单化:槽位为数据提供了统一的定位机制,只需要计算出具体的槽位值即可定位到数据,无需关系具体的数据分布细节
槽位映射的解决方案?
1、哈希取余
根据key做hash运算然后根据当前节点数取模即可。例如现在有3个节点,那么公式就是:hash(key)/3就可以计算出当前ke应该落到哪个redis的节点上了。
优点:
1、简单粗暴,直接有效,适用于业务体量小的服务,实际开发中不建议使用。
缺点:
1、不支持弹性扩容:因为计算的方式就导致了是无法扩缩容的,如果某个机器宕机了会导致节点数的变化导致全部数据重新洗牌。
2、一致性哈希算法
它是为了解决分布式下节点扩缩容引起数据重新洗牌的问题而产生的,目的是当节点数发生变化时,尽量减少key和节点的映射关系的变化,根据一致性算法构建一致性哈希环,相当于把一个直线首尾相连变成一个圆环。哈希环是0到2的32次方-1形成的一个逻辑闭环,整个环按照顺时针方向组织数据。
redis节点是如何落到hash环上的?
用节点的IP或主机名作为关键字进行哈希,确认一个点,这样节点就可以落到哈希环上了。例如:hash(IP)计算的值落到哈希环上就可以确定节点在哈希环上的映射关系了。
key是如何落到节点上的?
根据key计算哈希值hash(IP),将哈希值落入哈希环上然后顺时针找到的第一个节点就是当前key所归属的节点。
优点:
1、容错性:
如果某个减少某节点或节点宕机,受影响的只是当前节点逆时针到上一个节点间的数据会落入到当前节点的下一个节点中。
2、扩展性:
如果增加节点,只需要将新增加的这个节点的位置到上一个节点之间的数据落到当前新增节点上即可。这样可以减少节点变动带来的数据变化。
缺点:
1、数据倾斜问题:
当节点数比较少时,会因为hash(key)计算结果的原因导致数据落入节点不均匀,引起数据倾斜问题导致数据都集中在某个节点上。
3、哈希槽分区
哈希槽分区是目前最流行的解决方案,它能够解决哈希取余和一致性哈希算法的所有缺点。它能够均匀的分配数据到各个节点上,它是在数据和节点之间加入的新的一层映射,这层就叫哈希槽,用于管理数据和节点间的关系(没有什么问题是加一层解决不了的),相当于数据放在哈希槽里,哈希槽放在节点上。存储数据时使用hash(key) mod 16384的余数是几,来计算key的哈希值然后放到对应的槽中。哈希槽一共有16384个。16384个槽会分配给集群中所有节点,分配策略没有要求。集群会记录哈希槽和节点的映射关系。后续扩缩容时以槽为单位移动数据,因为槽的数目是固定的(一般都是大致均等的分配槽和节点的映射关系),即使是扩缩容处理起来也比较容易,这样数据移动的问题就解决了。
计算公式:哈希槽=CRC16(key) mod 16384 redis根据key使用crc16循环冗余算法算出一个结果然后对16384取模也就是取余数,这样取模的结果就会落入0-16383之间的哈希槽上,槽和节点之间又有映射关系,这样就确定了数据和节点的关系
为什么槽位是16384个?
1、网络优化:集群中每个节点会定期广播自己的槽位分配信息(bitmap),16384(2的14次方)个槽位需要2kb的内存(16384/8=2048字节)。如果选择65536(2的16次方),在发送心跳包的时候会带来更大的网络开销。
2、实际需求和扩展性:产品的设计是要根据实际需求来的,理论上来说16384个槽位可以支持最大16384个节点,每个节点上一个槽位,在实际开发中根本用不了这么大的集群,安特雷斯建议最大1000个节点。既然没有这么大的需要自然也不会有这样的设计。
3、降低开销:16384是2的14次方,通过位运算可以快速定位到槽位,降低槽位计算开销。
redis集群是否保证强一致性?
不保证,redis集群是基于CAP模型的,它选择的AP模型,所以不保证数据的强一致性,而是优先保证高可用性和分区容错性,redis集群中主从复制时数据是异步的从主节点同步给从节点,若主节点在同步数据前宕机可能导致数据丢失。

浙公网安备 33010602011771号