本地怎么复现Redis脑裂问题,脑裂能完全杜绝吗

文章介绍了Redis在主从架构下可能出现的脑裂问题,当网络分区导致两个主节点并存,从而引起数据不一致。通过配置min-replicas-to-write和min-replicas-max-lag参数可以减少脑裂导致的数据丢失,但无法完全避免。文中还详细描述了如何模拟脑裂现象以及哨兵架构的搭建和验证过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本地怎么复现Redis脑裂问题,脑裂能完全杜绝吗

前言

单纯的主从架构不具有高可用性,主要起到数据备份的作用,当主节点故障时,客户端将不能写入数据,所以当不使用redis集群时,可以使用redis哨兵架构,也可以保证高可用性。哨兵不提供读写服务,只是用来做监测、通知、自动故障转移,如果主节点未按预期工作,哨兵l可以启动故障切换过程,将从节点升级为主节点,客户端将数据写入新的主节点,旧的主节点恢复时,会作为从节点同步新主节点的数据。但是redis哨兵架构也会有脑裂问题,下面我们着重介绍一下什么是脑裂?它是怎么发生的以及解决方案是什么,然后我们使用多台虚拟机模拟脑裂现象,验证解决方案是否真正可用。

什么是脑裂

当主节点与从节点之间的网络通信突然断了,这时将一个从节点选举了主节点,此时出现了两个主节点,那么不同客户端会往这个两个主节点存数据,两个主节点数据不一致,当网络恢复后,原来的主节点变为从节点,从当前主节点复制数据,原来的主节点数据会丢失。
在这里插入图片描述
解决办法:
在redis.conf配置文件中开启下面两配置

min-replicas-to-write 1   #最少有一个从节点写数据成功,默认为0,即关闭这种模式
min-replicas-max-lag 10   #从节点向主节点发送ACK最大延迟时间,默认10

写入主节点的同时,需要指定数量的从节点也写成功,客户端才算写成功,所以原来的主从节点网络断了,原来的主节点不能插入数据了,待网络恢复后,将新的主节点数据全量同步给原来的主节点(此时变为从节点了)。

接下来我们模拟一下脑裂问题

哨兵主从架构

为了验证脑裂问题,我们先搭建一个哨兵主从架构。
在这里插入图片描述
准备:
VMware:搭建3台Centos虚拟机
Redis:redis-5.0.14

主从架构

3台虚拟机分别下载安装Redis,在这里就不在赘余。下面分别启动3台Redis服务,首先需要修改redis.conf相关参数

#bind 127.0.0.1 #bing是为了指定哪些IP能访问,内网不需要指定,注释掉
protected-mode no #关闭保护模式,否则只能本地访问,没法搭建主从
port 6379 #指定redis服务端口,默认6379
daemonize yes #yes表示可以守护进程启动
pidfile "/var/run/redis_6379.pid" #守护进程启动时,用来记录pid
logfile "6379.log"   #指定日志文件名,默认日志只会在控制台输出,指定日志文件可以保持日志
dir "/usr/local/redis-5.0.14/data" #指定数据存储位置



#其它两台服务port和pidfile要重新指定
port 6380/6381
# 从节额外配置
replicaof 192.168.111.132 6379   # 从6379的redis服务复制数据
replica-read-only yes  # 配置从节点只读

启动3台服务Redis,最先启动的为主节点

src/redis-server redis.conf

哨兵

每台服务分别配置一个哨兵,也就是每台服务有一个redis节点和一个哨兵,下面分别启动3个哨兵节点,首先需要修改sentinel.conf相关参数

port 26379 #指定sentinel端口,默认26379
daemonize yes #守护进程启动
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.14/data"
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
sentinel monitor mymaster 192.168.111.132 6379 2

#其它两个sentinel注意要修改一下端口
  1. 分别启动三个哨兵
src/redis-sentinel sentinel.conf

启动成功后,sentinel.conf会追加下面的信息
节点192.168.111.132,监控显示主从服务的2个从节点及其它2个哨兵
在这里插入图片描述
节点192.168.111.133,监控显示主从服务的2个从节点及其它2个哨兵
在这里插入图片描述
节点192.168.111.134,监控显示主从服务的2个从节点及其它2个哨兵
在这里插入图片描述
当主从节点发生变化时,这些信息也会发生相应变化。

  1. 演示一下哨兵架构是否成功
    在3个redis服务分别登录客户端
src/redis-cli -p 6379/6380/6881

主节点6379写入数据成功
在这里插入图片描述
从节点6380读取数据成功
在这里插入图片描述
从节点6381读取数据成功
在这里插入图片描述
假如往从节点6380写数据
在这里插入图片描述
报错,所以从节点只能读数据,不能写数据
主从架构搭建成功!!

  1. 那么我们再验证一下哨兵是否正常
    假如我们把master节点停掉,看看是否会重新选取一个新的master节点
    可以通过sentinel.conf查看,6379变成了从节点,6380变成了主节点
    在这里插入图片描述
    6380写数据成功
    在这里插入图片描述
    6379写数据失败,说明变成了从节点
    在这里插入图片描述
    从上面可以看出哨兵能够正常运转

模拟脑裂

重点来了,我们模拟一下脑裂问题
基于上面哨兵架构的验证情况,现在6380为主节点,其它两个为从节点。我们将6380这台虚拟机进行断网操作,选中虚拟机-》右键-》设置-》网络适配器,如下图,将已连接取消。

在这里插入图片描述
断网后,6380仍然可以作为主节点写入数据
在这里插入图片描述
查看sentinel,发现现在主节点已经变为6379了
在这里插入图片描述
6379也可以成功写入数据,这时同时有两个主节点可以写入数据,那么脑裂问题出现了
在这里插入图片描述
网络重新连接后,6380变成了从节点,数据被6379覆盖,name由235变成了789,235数据丢失
在这里插入图片描述

解决脑裂

现在主节点为6379,我们将6379的redis.conf中配置如下

min-replicas-to-write 1   #最少有一个从节点写数据成功
min-replicas-max-lag 10   #从节点向主节点发送ACK最大延迟时间

按照上面的步骤,我们把6379断网,可以看出向6379写入失败,脑裂问题解决
在这里插入图片描述

注意

min-replicas-to-write和min-replicas-max-lag必须同时满足才能禁止写入数据,如果min-replicas-max-lag=10,理论上讲仍有10s内有数据写入的话仍然能写入成功,造成数据丢失,那有人说那岂不是越小越好,如果设置1s,那就得要求主节点1秒内把数据同步给从节点,这显示是不太合理的,因为万一遇到从节点卡顿或者网络稍微有点延迟,那就会造成写入数据失败,严重影响了高可用。

所以说脑裂的解决是处在一个平衡点上,尽量降低数据丢失,不能完全防止数据丢失。

### Redis 脑裂的原因 Redis 脑裂问题通常发生在主从复制架构中,当网络分区或其他异常情况发生时,可能导致多个主节点同时存在。具体来说,脑裂的根本原因是网络分区使得原主节点和新选主节点之间无法正常通信[^5]。这种情况下,客户端可能向不同的主节点写入数据,从而引发数据不一致或丢失。 在网络分区场景下,哨兵机制可能会错误判断原主节点不可用并选举新的主节点,而实际上原主节点仍能正常工作。这种情况下的脑裂会对系统的可靠性带来严重影响[^2]。 --- ### 解决方案概述 针对 Redis 脑裂问题,常见的解决方案可以从以下几个方面入手: #### 1. **配置 `min-slaves-to-write` 和 `min-slaves-max-lag` 参数** 通过设置这两个参数,可以在一定程度上减少脑裂的发生概率。如果主节点检测到连接的从节点数量不足或者延迟过高,则会自动禁用写操作,防止在假故障期间继续接受写请求[^3]。 #### 2. **优化哨兵配置** 合理调整哨兵的监控频率以及投票阈值,确保只有在真正确认主节点失效的情况下才触发切换逻辑。此外,可以通过增加仲裁节点的数量提高决策的一致性和准确性[^1]。 #### 3. **启用半同步复制模式** 虽然 Redis 默认采用异步复制方式,但在某些高可用需求较高的场景下,可以尝试引入半同步复制技术(需借助第三方插件实现),以增强主从间的数据一致性保障[^4]。 #### 4. **使用 Redis Cluster 或其他分布式存储替代品** 对于复杂业务场景而言,单纯依赖单机版 Redis 及其哨兵体系难以彻底规避脑裂风险。此时可考虑迁移到支持多分片管理且内置冲突处理机制的 Redis Cluster 版本;亦或是评估是否适合改用具备更强事务特性的数据库产品作为缓存层补充。 --- ### 实现代码示例 以下是基于 Python 的简单脚本用于验证上述部分策略效果之一——动态修改运行中的 Redis 配置项: ```python import redis def adjust_redis_config(host='localhost', port=6379, password=None): r = redis.StrictRedis(host=host, port=port, decode_responses=True, password=password) # 设置 min-slaves-to-write 和 min-slaves-max-lag 参数 r.config_set('min-slaves-to-write', 1) r.config_set('min-slaves-max-lag', 10) current_settings = { 'min-slaves-to-write': r.config_get('min-slaves-to-write')['min-slaves-to-write'], 'min-slaves-max-lag': r.config_get('min-slaves-max-lag')['min-slaves-max-lag'] } return current_settings if __name__ == "__main__": result = adjust_redis_config() print(f"Updated Redis Configurations: {result}") ``` 此脚本展示了如何远程更改目标实例上的关键保护选项值,帮助管理员快速响应潜在威胁环境变化带来的挑战。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值