Redis集群方案及实战(二)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis集群方案及实战

4.哨兵模式实现原理

  1. 监控:当哨兵启动时,会监控所有的主从节点,并且保证哨兵集群能够正常通信,这个阶段称为监控阶段
  • ping:哨兵节点启动后所有哨兵每隔1S会互相发送ping心跳,来检测其他哨兵节点是否正常
  • info:哨兵节点启动后每隔10S会向所有的主节点发送info指令,得到runid、role、各个slave的详细信息。再根据slave信息发送info指令获取slave的详细信息,会得到runid、role、master_host、master_port、offset...
  • pub/sub:每个哨兵节点每隔2S会在一个指定频道发布当前节点保存的主节点信息,其他哨兵节点会订阅该频道获取信息
  1. 通知:当哨兵发现主节点或者从节点出现故障时,当前哨兵会通知其他哨兵,其他哨兵挨个发送ping命令来到出故障的redis节点,如果redis节点没有响应则哨兵集群认为此节点出现故障,我们把这个阶段称为哨兵通知阶段
  • 哨兵监控slave
  • 在哨兵集群中,如果某一个哨兵节点发现某个从节点出现故障后,会将其标记为+sdown,并发布订阅告知给其他哨兵节点,其他哨兵节点收到通知后会将次从节点剔除,并标记为+sdown,等到下次slave回复哨兵时,哨兵会将其从新变为从节点,并标记为-sdown

  • 哨兵监控master
  • 某个哨兵发现主节点出故障后,会将当前主节点标记为+sdown,也就是标记为主观下线,单个哨兵认为有问题可能是网络抖动问题
  • 后续如果其他哨兵节点也发现此主节点出现问题,当发现问题的哨兵数量大于quorym时,那么哨兵集群会认为此主节点出现故障,标记为odown状态,此时主节点被标记为客观下线

  1. 故障转移:当哨兵集群已经发现某个节点出现故障时,如果是从节点则直接剔除,如果是master节点出现故障,那么需要在多个从中推选出一个新的主节点,我们把这个阶段称为故障转移阶段
  • 哨兵leader选举:当主节点被标记为客观下线时,就要在哨兵集群中选出一个哨兵节点来完成后面的故障转移工作,每个哨兵节点都可以成为leader,选举流程如下
  • 主节点被标记为客观下线时,哨兵节点会向其他哨兵节点发送is-master-down-by-addr命令,表明自己想成为leader来处理master的故障转移
  • 当其他哨兵节点收到此命令时,可以同意或者拒绝它成为leader
  • 如果票数大于哨兵集群数量的一半时将成为领导者,如果没有大于,则继续开始下一轮选举,并且票数会类加
  • 故障转移实现流程:哨兵在监控阶段时就保存了主从节点信息,选举出leader哨兵后,哨兵要开始进行主从节点故障转移,从众多从节点中选举出一个主节点。主节点选举流程如下
  • 过滤掉已经下线的从节点
  • 优先级高的推选为主节点,默认都是100,可通过slave-priority参数进行设置,越小优先越高
  • 推选出offset最大的节点,offset大意味着和主节点数据越相近
  • 推选出runid最小的节点,因为runid越小代表越早加入集群,具有更多的复制数据,更适合成为主节点
  • 更新状态:当故障转移后,需要更新当前的主从状态,流程如下
  • 被选举出来的新master将执行slaveof no one 命令,断开与原master连接,将自己从从节点转换为主节点,并在其他的slave配置文件上加上slaveof命令
  • 将已经剔除的主节点设置为新主节点的从节点,后续恢复时,将其变为从节点,并在其配置文件中加上slaveof命令

5.主观下线和客观下线

  1. 名词说明
  • 主观下线:某个哨兵节点单方面的认为一个Redis节点不可用了
  • 客观下线:大部分哨兵节点都认为一个Redis节点不可用时,那么此节点就被认为是客观下线
  1. 原理
  • 哨兵进程会使用PING命令的方式来检测各个主库和从库的网络连接情况,用来判断实例状态
  • 如果哨兵发现主库或者从库响应超时(down-after-millisecond),那么哨兵会判定其为"主观下线"
  • 如果该节点是主节点,那么哨兵会进一步判断是否需要对其进行故障切换,这时候会发送命令(SENTINEL is-master-down-by-addr)询问其他哨兵节点是否认为该主节点是主观下线,当达到指定数量(quorum)时,哨兵就会认为此主节点是客观下线
  • 如果没有足够数量的哨兵同意主节点进入主观下线,主节点的主观下线状态就会被消除,若主节点重新向哨兵的PING命令返回有效回复,主节点的主观下线状态也会被消除
  • 哨兵误判:主库本身没有故障,但由于哨兵的误判,判断它为下线状态。一旦启动主从切换,后续的选举和通知操作都会带来额外的计算和通信开销。因此,为了不必要开销,我们要严格注意误判的情况。在哨兵集群中,判定主库是否处于下线状态,不是由一个哨兵来决定的,而是只有大多数哨兵认为主库已经"主观下线",主库才会标记为"客观下线"。这种判断机制为:少数服从多数。同时会触发故障转移
  • 关键属性

down-after-milliseconds:Redis Sentinel 配置文件中的一个属性,表示 Sentinel 发送 Ping 命令给实例之后,如果规定的时间内没有收到响应,就认为实例已经下线了,然后 Sentinel 就会开始判断实例的状态。这个属性的默认值为 30,000 毫秒 (30 秒)。可以通过修改配置文件的方式来更改该属性的值 SENTINEL is-master-down-by-addr:Redis Sentinel 提供的命令之一,用于向其它 Sentinel 节点询问某个主服务器是否已经下线。当一个 Sentinel 节点判定某个主服务器为主观下线后,会向其它 Sentinel 节点发送 SENTINEL is-master-down-by-addr 命令来确认这个主服务器是否已经客观下线,从而决定是否执行自动故障转移。这个命令需要提供主服务器的 IP 地址和端口号作为参数,响应内容则是一个字符串,表示主服务器的状态信息

quorum:哨兵模式中用来决定主节点是否被判定为客观下线的数量阈值。当有N个哨兵节点监控同一个主节点时,要求有至少N/2+1个哨兵节点判定该主节点为主观下线,此时才会被判定为客观下线,从而触发故障转移。这个数量阈值可以通过配置文件中的参数quorum来设置 SLAVEOF NO ONE:此命令是Redis用于将一个从节点转化为主节点的命令。执行该命令后,从节点会断开与其原来的主节点的连接,并开始独立工作,即成为一个新的独立的主节点 slaveof:此命令是Redis中用于配置主从复制关系的命令。它用于将一个Redis实例设置为另一个Redis实例的从服务器。这个命令在Redis的主从复制过程中是非常重要的,它让从服务器能够连接到主服务器,并且通过复制主服务器上的数据来保持与主服务器的数据一致性

6.哨兵模式优缺点

  1. 优点
  • 高可用性:哨兵模式可以自动检测节点的可用性,并实现主从节点的自动切换,从而提高了 Redis 的高可用性、健壮性
  • 灵活性:哨兵模式支持动态的添加、删除节点,可以根据需要扩展 Redis 的读写性能
  • 无需人工干预:哨兵模式不需要人工干预,可以自动实现故障转移和节点恢复
  1. 缺点
  • 延迟:哨兵模式需要检测节点的状态,判断主节点是否宕机,再进行故障转移,因此会增加一定的延迟
  • 配置复杂:哨兵模式需要配置多个哨兵节点,需要合理设置节点的数量和 quorum 值,对于不了解 Redis 的开发人员来说,配置较为复杂
  • 在线扩容复杂:Redis比较难支持在线扩容
  • 所有主从节点保存的都是全量数据,浪费内存空间,没有实现真正的分布式存储,数据量过大时,主从同步严重影响master性能
  • 故障转移时,在主节点选举结束之前,谁也不知道主从节点是谁,此时Redis会开启切换保护机制,禁止写操作,直到选举出新的主节点

3、RedisCluster模式

1.RedisCluster模式概述

  1. RedisCluster是Redis官方提供的分布式方案,适用于数据了特别大的场景,相对于哨兵模式,它具有以下优点
  • 高可用:多个主节点,每个主节点有对应多个从节点,主节点宕机RedisCluster机制会自动将某个从节点切换到主节点
  • 扩展性
  • 横向扩展:通过增加机器实现增加能力上限
  • 读写扩展:基于主从模式,通过读写分离,增加读写能力,避免单点故障
  • 分布式存储:RedisCluster采用分片技术将数据均匀分布到多个节点上,每个节点只保存部分数据,避免了单个节点存储数据过大的问题,提高了存储容量和性能
  • 自动数据迁移:RedisCluster支持自动数据迁移,当新增或删除节点时,会自动将数据迁移到其他节点上,保证数据均衡和数据完整性
  1. RedisCluster是什么
  • redis在3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,也就是说每台 Redis 节点上存储不同的数据。cluster模式为了解决Redis单节点容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,可受益于分布式集群高扩展性
  • RedisCluster是一种服务器Sharding技术,分片和路由都是在服务端实现,采用多主多从,每一个分区都是由一个Redis主节点和多个从节点组成,片区和片区之间是相互平行的。RedisCluster集群采用了P2P的网络拓扑架构,没有中心节点,所有节点通过Gossip协议通信,所有节点即存储数据也是控制节点
  • RedisCluster建议至少部署3个主节点和3个从节点,以保证数据的高可用性和负载均衡
  • 总结:RedisCluster是可以达到主从复制架构、读写分离、哨兵集群、高可用效果的集群架构

2.数据分布算法

  • 由于RedisCluster是将数据分布在不同的片区,所以需要数据分布算法,以下是几种数据分布算法的原理优缺点,RedisCluster采用的是HashSlot算法
  1. Hash寻址算法
  • 原理:对Key进行Hash运算,然后将值对主节点数量取模,最后得到的数值就是此数据应存储到的主节点
  • 优点:简单、快速、高效、适用于大规模快速查询
  • 缺点:
  • 数据分布不均匀:如果使用简单的Hash寻址算法,可能会出现数据倾斜的情况,导致某些节点负载过高,而某些节点负载过轻
  • 数据迁移困难:使用Hash寻址算法进行数据分布后,如果需要添加或删除节点,就需要重新计算每个数据对应的节点,然后将其迁移到新节点上,这个过程非常繁琐,而且需要暂停对集群的写操作
  • 扩展性受限:使用Hash寻址算法进行数据分布时,如果需要增加节点,那么需要将所有的数据重新计算分配,这样就会限制集群的扩展性
  • 大量缓存重建问题:主节点如果宕机,那么Hash运算时根据现有存活节点进行取模,得到的数值与原有存储数据时的数值不匹配,请求走不到原有路由节点上,从而导致大量的key瞬间全部失效

  1. 一致性Hash算法
  • 原理:将所有的主节点进行Hash运算,再将Hash值映射到一个固定的Hash环上面。然后对Key进行Hash运算,将此Hash值与圆环上的各个点进行对比,将Hash值落在圆环上后进行顺时针旋转去寻找距离自己最近的一个节点,数据的存储与读取都在此节点进行
  • 优点:保证任何一个主节点宕机,只会影响在之前那个主节点上的数据,此前的主节点宕机,查询时这部分数据会丢失,写入时沿着顺时针去到下一个主节点
  • 缺点
  • 数据丢失过大:在节点比较少的情况下, 丢失的数据量还是非常庞大的
  • 缓存热点问题:如果某些数据被频繁地访问,会导致热点数据集中在某个节点上,造成负载不均
  • 数据倾斜问题:节点数量较少时,由于数据分布不均,可能会导致某个节点负载过重,影响系统的性能。这是因为Hash函数的输出值在Hash环上并不是均匀分布的,而是有规律的。一致性哈希算法通过引入虚拟节点来解决这个问题,将每个物理节点映射到多个虚拟节点上,使得数据更加均匀地分布在环上
  • 一致性问题:由于节点的添加或删除会影响哈希值的计算,可能会导致数据分布不均,这个问题可以通过一些技术手段来解决,例如虚拟节点、数据复制等

  1. 带虚拟节点一致性Hash算法
  • 业界为了解决一致性Hash算法的问题,在一致性Hash算法的基础上增加了虚拟节点机制
  • 原理
  • 出现数据倾斜的原因就是因为节点的数量较少,那么我们可以通过对主节点Hash运算后,固定到Hash环上面,然后对该主节点进行多次Hash运算计算出几个虚拟节点,当Key进行Hash运算后如果顺时针找到虚拟节点,那么虚拟节点会映射到他真正的主节点,从而达到数据分散的效果
  • 实际运用中,通常将虚拟节点设置为32个以上,此时即便节点很少也可以做到尽可能的数据均匀分布
  • 举例
  • Hash("Neuronet") -> 虚拟节点1
  • 虚拟节点1 -> 主节点1

  1. 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的值,不多不少刚刚好

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
1天前
|
NoSQL 算法 Java
深入浅出Redis(八):Redis的集群模式
深入浅出Redis(八):Redis的集群模式
|
7天前
|
NoSQL Redis
透视Redis集群:心跳检测如何维护高可用性
Redis心跳检测保障集群可靠性,通过PING命令检测主从连接状态,预防数据丢失。当连接异常时,自动触发主从切换。此外,心跳检测辅助实现`min-slaves-to-write`和`min-slaves-max-lag`策略,避免不安全写操作。还有重传机制,确保命令无丢失,维持数据一致性。合理配置心跳检测,能有效防止数据问题,提升Redis集群的高可用性。关注“软件求生”获取更多Redis知识!
107 10
透视Redis集群:心跳检测如何维护高可用性
|
8天前
|
监控 NoSQL 算法
探秘Redis分布式锁:实战与注意事项
本文介绍了Redis分区容错中的分布式锁概念,包括利用Watch实现乐观锁和使用setnx防止库存超卖。乐观锁通过Watch命令监控键值变化,在事务中执行修改,若键值被改变则事务失败。Java代码示例展示了具体实现。setnx命令用于库存操作,确保无超卖,通过设置锁并检查库存来更新。文章还讨论了分布式锁存在的问题,如客户端阻塞、时钟漂移和单点故障,并提出了RedLock算法来提高可靠性。Redisson作为生产环境的分布式锁实现,提供了可重入锁、读写锁等高级功能。最后,文章对比了Redis、Zookeeper和etcd的分布式锁特性。
108 16
探秘Redis分布式锁:实战与注意事项
|
9天前
|
监控 NoSQL 算法
Redis集群模式:高可用性与性能的完美结合!
小米探讨Redis集群模式,通过一致性哈希分散负载,主从节点确保高可用性。节点间健康检测、主备切换、数据复制与同步、分区策略和Majority选举机制保证服务可靠性。适合高可用性及性能需求场景,哨兵模式则适用于简单需求。一起学习技术的乐趣!关注小米微信公众号“软件求生”获取更多内容。
41 11
Redis集群模式:高可用性与性能的完美结合!
|
10天前
|
监控 NoSQL Redis
|
11天前
|
存储 NoSQL Java
Spring Boot与Redis:整合与实战
【4月更文挑战第29天】Redis,作为一个高性能的键值存储数据库,广泛应用于缓存、消息队列、会话存储等多种场景中。在Spring Boot应用中整合Redis可以显著提高数据处理的效率和应用的响应速度。
26 0
|
14天前
|
存储 缓存 NoSQL
node实战——koa给邮件发送验证码并缓存到redis服务(node后端储备知识)
node实战——koa给邮件发送验证码并缓存到redis服务(node后端储备知识)
19 0
|
15天前
|
NoSQL Redis Docker
使用Docker搭建Redis主从集群
使用Docker搭建Redis主从集群
32 1
|
15天前
|
存储 缓存 NoSQL
Redis入门到通关之Redis缓存数据实战
Redis入门到通关之Redis缓存数据实战
21 0
|
15天前
|
存储 缓存 NoSQL
Redis实现延迟任务的几种方案
Redis实现延迟任务的几种方案