Redis为什么需要集群
1、Redis需要集群主要是为了解决以下几个问题
- 容量限制:单机Redis的容量是有限的,一旦数据量达到单机容量极限,就需要将数据存储到多台机器上进行扩容
- 高可用性:单机Redis存在单点故障的问题,如果单机Redis宕机,就会导致整个系统的服务中断,因此需要使用集群来实现高可用性和容错能力
- 并发性能:单机Redis的并发性能是有限的,一旦并发访问量达到一定程度,就会出现性能瓶颈和性能下降的问题,因此需要使用集群来提高并发性能
2、Redis集群通过数据分片和数据复制的方式来实现数据存储和高可用性,具有以下优点
- 数据自动分片:Redis集群将数据自动分片存储到多台机器上,实现了数据的横向扩展,可以支持更大规模的数据存储
- 数据自动复制:Redis集群通过数据复制机制来保证数据的高可用性,即将主节点上的数据自动复制到多个从节点上,实现数据的备份和容错
- 自动故障转移:Redis集群可以自动进行故障转移,即在主节点宕机时,自动选举一个从节点作为新的主节点,保证系统的持续运行和服务的可用性
- 增强并发性能:Redis集群通过分片机制来增强并发性能,即将数据分散到多个节点上进行处理,从而避免单机性能的瓶颈问题
3、Redis三种集群模式
1、主从复制模式是三种模式中最简单的一种,多台Redis实例,以一台实例作为主机,其余的实例作为备份机,主机和从机的数据完全一致,主从复制提高了Redis读请求的吞吐量。主机支持数据的读和写操作,而从机只支持读和数据同步,客户端将数据写入主机后,由主机自动的将数据写入到从机中
优点:
- 提高了Redis的可扩展性:通过使用Redis主从复制,可以将读操作分摊到从节点上,从而减轻主节点的压力,提高Redis的读性能,同时也增加了Redis的水平扩展能力
- 提高了Redis的可用性:通过将主节点的数据复制到多个从节点上,可以在主节点发生故障时,切换到某个从节点,从而保证Redis的高可用性
- 分离了读写操作:将读操作分离到从节点上,可以避免读写操作的冲突,提高Redis的并发处理能力和数据一致性
缺点: - 主节点宕机之后需要手动切换主机
- 多个从节点宕机恢复后,大量的SYNC同步操作会导致主节点IO压力倍增
- 延迟和数据不一致问题:Redis主从复制是异步复制,从节点与主节点之间存在一定的延迟,因此可能会存在数据不一致的问题,如主节点写入的数据还未同步到从节点,从节点就返回给客户端了
- 从节点的容错性较差:Redis从节点无法处理写操作,因此从节点发生故障时,只能选择重新启动或者重新配置,无法自动恢复
- 从节点数量的限制:Redis从节点数量的限制主要是由网络带宽和性能限制所限,因此从节点数量较多时,可能会导致网络拥塞和性能下降的问题
2、哨兵模式
- 主从复制模式当主节点宕机以后,需要手动将一台从节点切换到主节点,这个时候就需要人工干预,不仅麻烦还会造成一段时间内服务不可用,这时候就需要哨兵模式
- Redis哨兵模式是在Redis 2.8版本中引入的。在此版本之前,Redis只提供了主从复制来实现高可用性和数据备份。但是,主从复制存在单点故障的问题,当主节点宕机时整个系统将无法提供服务。因此,Redis引入了哨兵模式来解决这个问题,使得Redis服务具备更高的可用性和数据一致性
- 哨兵模式的核心还是主从模式,只不过在主从模式的基础上增加了一个竞选机制,如果主节点宕机了,那么从所有的从节点中选出新的主节点。竞选机制的实现依赖于在系统中启动一个sentinel进程
- sentinel会监控所有节点是否正常运行,通过发出命令返回监控节点的状态,在多sentinel模式下,sentinel之间也会互相监控
- 故障切换:当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让它们切换master。同时那台有问题的旧主也会变为新主的从,也就是说当旧的主即使恢复时,并不会恢复原来的主身份,而是作为新主的一个从。
优点:
- 高可用性:哨兵模式可以自动检测节点的可用性,并实现主从节点的自动切换,从而提高了 Redis 的高可用性、健壮性
- 灵活性:哨兵模式支持动态的添加、删除节点,可以根据需要扩展 Redis 的读写性能
- 无需人工干预:哨兵模式不需要人工干预,可以自动实现故障转移和节点恢复
缺点:
- 延迟:哨兵模式需要检测节点的状态,判断主节点是否宕机,再进行故障转移,因此会增加一定的延迟
- 配置复杂:哨兵模式需要配置多个哨兵节点,需要合理设置节点的数量和 quorum 值,对于不了解 Redis 的开发人员来说,配置较为复杂
- 在线扩容复杂:Redis比较难支持在线扩容
- 所有主从节点保存的都是全量数据,浪费内存空间,没有实现真正的分布式存储,数据量过大时,主从同步严重影响master性能
- 故障转移时,在主节点选举结束之前,谁也不知道主从节点是谁,此时Redis会开启切换保护机制,禁止写操作,直到选举出新的主节点
RedisCluster模式
RedisCluster是Redis官方提供的分布式方案,适用于数据了特别大的场景,相对于哨兵模式,它具有以下优点
高可用:多个主节点,每个主节点有对应多个从节点,主节点宕机RedisCluster机制会自动将某个从节点切换到主节点
扩展性:
- 横向扩展:通过增加机器实现增加能力上限
- 读写扩展:基于主从模式,通过读写分离,增加读写能力,避免单点故障
分布式存储:RedisCluster采用分片技术将数据均匀分布到多个节点上,每个节点只保存部分数据,避免了单个节点存储数据过大的问题,提高了存储容量和性能
自动数据迁移:RedisCluster支持自动数据迁移,当新增或删除节点时,会自动将数据迁移到其他节点上,保证数据均衡和数据完整性
redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决Redis单节点容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性
RedisCluster
- 是一种服务器Sharding技术,分片和路由都是在服务端实现,采用多主多从,每一个分区都是由一个Redis主节点和多个从节点组成,片区和片区之间是相互平行的。RedisCluster集群采用了P2P的网络拓扑架构,没有中心节点,所有节点通过Gossip协议通信,所有节点即存储数据也是控制节点
- RedisCluster建议至少部署3个主节点和3个从节点,以保证数据的高可用性和负载均衡
- 总结:RedisCluster是可以达到主从复制架构、读写分离、哨兵集群、高可用效果的集群架构
数据分布算法:
由于RedisCluster是将数据分布在不同的片区,所以需要数据分布算法,以下是几种数据分布算法的原理优缺点,RedisCluster采用的是HashSlot算法
Hash寻址算法
原理:对Key进行Hash运算,然后将值对主节点数量取模,最后得到的数值就是此数据应存储到的主节点
优点:简单、快速、高效、适用于大规模快速查询
缺点:
- 数据分布不均匀:如果使用简单的Hash寻址算法,可能会出现数据倾斜的情况,导致某些节点负载过高,而某些节点负载过轻
- 数据迁移困难:使用Hash寻址算法进行数据分布后,如果需要添加或删除节点,就需要重新计算每个数据对应的节点,然后将其迁移到新节点上,这个过程非常繁琐,而且需要暂停对集群的写操作
- 扩展性受限:使用Hash寻址算法进行数据分布时,如果需要增加节点,那么需要将所有的数据重新计算分配,这样就会限制集群的扩展性
- 大量缓存重建问题:主节点如果宕机,那么Hash运算时根据现有存活节点进行取模,得到的数值与原有存储数据时的数值不匹配,请求走不到原有路由节点上,从而导致大量的key瞬间全部失效
一致性Hash算法
原理:将所有的主节点进行Hash运算,再将Hash值映射到一个固定的Hash环上面。然后对Key进行Hash运算,将此Hash值与圆环上的各个点进行对比,将Hash值落在圆环上后进行顺时针旋转去寻找距离自己最近的一个节点,数据的存储与读取都在此节点进行
优点:保证任何一个主节点宕机,只会影响在之前那个主节点上的数据,此前的主节点宕机,查询时这部分数据会丢失,写入时沿着顺时针去到下一个主节点
缺点:
- 数据丢失过大:在节点比较少的情况下, 丢失的数据量还是非常庞大的
- 缓存热点问题:如果某些数据被频繁地访问,会导致热点数据集中在某个节点上,造成负载不均
- 数据倾斜问题:节点数量较少时,由于数据分布不均,可能会导致某个节点负载过重,影响系统的性能。这是因为Hash函数的输出值在Hash环上并不是均匀分布的,而是有规律的。一致性哈希算法通过引入虚拟节点来解决这个问题,将每个物理节点映射到多个虚拟节点上,使得数据更加均匀地分布在环上
- 一致性问题:由于节点的添加或删除会影响哈希值的计算,可能会导致数据分布不均,这个问题可以通过一些技术手段来解决,例如虚拟节点、数据复制等
HashSlot算法
Redis使用此算法的原因
- RedisCluster需要支持动态扩容和缩容,在一致性hash算法中,增加或删除一个节点会导致整个哈希环重新分布,这样会导致大量的数据迁移和节点负载的不均衡,而使用HashSlot算法则可以避免这个问题
- 此算法可以避免数据倾斜问题和虚拟节点带来的计算负担
原理:
- 在HashSlot算法中,取值范围是0~16383。Redis将整个key空间分成了16384个槽,也就是16384个slot,每个主节点负责一部分槽
- 客户端根据Key计算CRC16值,将值对16384取模,找到对应的槽,然后根据槽对应的主节点进行数据访问
- Redis中的每个主节点都对应一部分槽位。增加一个主节点时,只需要将其他主节点的槽位分配一部分到新槽位。删除一个主节点时,就将此主节点的槽位移动到其他的主节点上去。移动Hash槽的成本是非常低的
- HashSlot算法还可以将不同的数据类型映射到不同的槽中,以达到更好的负载均衡效果。同时,Redis还支持将相邻的多个槽划分到同一个节点,以便在某些场景下提高数据读取的效率
- 如果想确保一些Key总是被分配到同一个节点,那么您可以使用哈希标签(Hash Tag)功能来强制让这些键映射到同一个槽位。哈希标签是在 RedisKey 上使用大括号 "{}" 的一种特殊语法
例如:set mykey1:{100}和set mykey2:{100},它们的hash tag都是{100},那么它们就会被存储在同一个hash slot中
16384槽位由来:
- CRC16算法产生的Hash值有16bit,该算法可以产生65536个值。值是分布在0~65535之间,那么其实在做取模运算时,我们是可以取模65536的,但是Redsi作者采取了16384
- 作者的回答是:Redis集群节点数量如果超过1000个那么会造成网络拥堵,所以建议节点数量不超过1000个,那么1000个节点使用16384个槽位完全够用了。如果使用65536个槽位会导致主节点之间交互心跳包时,浪费带宽。槽位数量过少不够用,过多浪费带宽,所以作者通过实测计算得出一个16384的值,不多不少刚刚好

浙公网安备 33010602011771号