redis的集群方案和常见问题

本文详细解释了Redis集群的主从复制机制,包括全量同步和增量同步;介绍了哨兵模式在保证高可用和故障恢复中的作用,以及脑裂问题的解决方案;最后讨论了分片集群的原理,如何处理海量数据和高并发写的问题。
摘要由CSDN通过智能技术生成

redis集群有主从复制、哨兵模式、分片集群
在讲解之前,先抛出以下几个问题:
1.redis主从数据同步的流程是什么?
2.怎么保证redis的高可用?
3.redis分片集群中数据是怎么存储和读取的?
4.redis集群脑裂,该怎么解决呢?

一.主从复制

单节点的redis的并发能力是有上限的,要进一步提高redis的并发能力,就需要搭建主从集群,实现读写分离,如下图所示,一般采用一主多从的方式,主节点负责写数据,从节点负责读数据,当有数据写入主节点时,就需要将数据同步到从节点,保证主从数据的一致性。主从数据的同步有全量同步和增量同步,下面将详细描述两者的原理和流程:
在这里插入图片描述
主节点将数据同步给从节点的同步流程是什么?

1.1 全量同步

在这里插入图片描述
全量同步的步骤:
1.从节点执行replicaof命令,建立连接;
2.从节点请求数据同步;
3.主节点判断是否是第一次同步;
4.是第一次,主节点的数据版本信息发送给从节点;
5.从节点保存版本信息;
6.主节点执行bgsave,fork一个子进程,生成RDB文件,并发送给从节点;
7.主节点发送RDB文件给从节点;
8.从节点清空本地数据,加载RDB文件;
9.在主节点生成RDB文件的过程中,可能又有新的数据,此时主节点会记录生成RDB文件期间的所有命令,为repl_baklog;
10.主节点发送repl_baklog中的命令;
11.从节点执行接收到的命令。
上面的过程会有以下疑问?
主节点是怎么判断是否是第一次同步?
在讲解这个问题之前,有一个以下的概念:
replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集,每一个master都有唯一的replid,slave则会继承master节点的replid。
如下图示所示:当从节点请求数据同步的时候,会把replid传给主节点,如果主从节点的replid不相同,则代表是第一次同步,主节点会把replid发给从节点,从节点记录新的replid。如果相同,则不是第一次同步,直接就执行步骤10,主节点将repl_baklog发送给从节点执行。
在这里插入图片描述

思考一个问题,当不是第一次同步,从节点执行repl_baklog中的命令是怎么保证刚好执行的数据就是从节点需要的数据呢?
在弄清楚这个问题之间,有一个以下的概念:
offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

1.2 增量同步

增量同步一般发生在slave重启或后期数据变化。
在这里插入图片描述
增量同步执行流程:
1.从节点执行命令,建立连接,给主节点发送replid、offset等信息;
2.主节点判断replid是否一致,一致,代表不是第一次;
3.主节点去repl_baklog中获取offset后的数据,发送offset后的命令;
4.从节点执行命令。

redis主从集群模式的缺点是保证不了redis的高可用,假如主节点挂掉,就丧失了写数据的能力。

二. 哨兵模式

Redis提供了哨兵(Sentinel)机制来实现主从集群的自动故障恢复。哨兵的结构和作用如下:
1.监控:Sentinel会不断检查master和slave是否按预期工作;
2.自动故障恢复:如果master发生故障,sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主。
3.通知:sentinel充当redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给redis的客户端(比如redisTemplate)
在这里插入图片描述
如上图所示,一般哨兵都要至少部署3台。

2.1 哨兵监控的原理和故障之后的选主(主节点)规则

Sentinel基于心跳机制检测服务状态,每隔1秒向集群的每个实例发送ping命令:
• 主观下线:如果某一个sentinel节点发现某redis实例未在规定时间相应,则认为该实例主观下线,主观下线还不是真正的下线。
• 客观下线:如果超过指定数量(quorum)的sentinel都认为该reids实例主观下线,则该实例客观下线。quorum值最好超过sentinel实例数量的一半,比如sentinel为3个,那么quorum设置为2。
在这里插入图片描述
那我们思考一个问题,当一个主节点发生故障,那sentinel是怎么在从节点中重新选一个当主节点呢?
哨兵的选主规则如下:
1.首先判断主与从节点断开时间长短,如果超过指定值就排该节点;
2.然后判断从节点的slave-priority值,值越小,优先级越高;
3.如果slave-prority一样,则判断slave节点的offset值,越大优先级越高
4.最后判断从节点的运行id大小,越小优先级越高。

2.2 reids集群(哨兵模式)脑裂问题及解决方案

首先思考什么是脑裂问题?什么情况下会出现脑裂问题?
如下图所示:
在这里插入图片描述
假如 sentinel哨兵和master不在同一个网络片区,由于网络问题,哨兵监测不了主节点,只能监测到从节点,这时哨兵就会以为主节点客观下线了,此时就重新选择一个从节点为主节点,但旧主节点实际是没有挂掉的,这时就出现了2个主节点,这就是脑裂的问题。假如在脑裂的过程中,还是有客户端在向旧主节点写入数据,当网络恢复之后,哨兵会把旧主节强制降为从节点,并数据清空,从新的主节点同步数据过来,此时就会出现在脑裂过程中新写的数据不存在了,如下图所示:
在这里插入图片描述
那如何解决脑裂问题呢。
我们可以通过配置redis中的两个参数来解决上面的问题:

min-replicas-to-write 1 # 表示最少的salve节点为1个,就是客户端在向主节点写入数据的时候,至少有一个从节点;
min-replicsa-max-lag 5 # 表示数据复制和同步的延迟不能超过5s

如果达不到上面的2个要求,就拒绝客户端的请求。

三. 分片集群

前面讲的主从和哨兵可以解决高可用、高并发读的问题。但是依然有两个问题没有解决:
• 海量数据存储问题
• 高并发写的问题

3.1 分片集群的基本特征

在这里插入图片描述

我们可以使用分片集群来解决上面的问题,分片集群的特征,如上图所示:
• 集群中有多个master,每个master保存不同的数据,解决了并发写的问题;
• 每个master都可以有多个slave节点,也能解决并发读的问题;
• master 之间通过ping(心跳)监测彼此健康状态,如果多个master都标记某一个master主观下线了,那么这个master就客观下线了,此时就会做主从切换了;
• 客户端请求可以访问集群任意节点,最终都会被转发到正确节点,具体怎么转发到不同节点的,下面将讲解其中的原理:

3.2 分片集群结构数据读写原理

Redis分片集群引入了哈希槽的概念,redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定存储在哪个槽,集群的每一个节点负责一部分的哈希槽。
如下图所示,为写命令的执行过程:
在这里插入图片描述
1.使用CRC16计算name的hash值,假如为66666;
2.使用66666对16384取模余11306,则放在第三个主节点上。
读数据和写数据一样,也是先计算key的hash值,在余16384取模,在对应的从节点获取数据。

  • 14
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代号diitich

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值