在使用Redis主从架构作为系统缓存服务,配合上Sentinal(哨兵)组件的监控、故障转移等特性,基本上来说就能够大部分缓存系统的需求。那么在这样一套架构中,在主从切换,数据复制过程中,会不会出现数据丢失?什么情况下数据会丢失?如何尽量减少数据丢失?这是本文需要跟大家一起学习的内容。
从哲学的角度看,只要绝对都是伪命题,使用Redis主从架构+Sentinal(哨兵)组件,绝对不能够完全保证数据不丢失,那么在那种情况下会出现数据丢失呢?
数据丢失场景分析-异步复制
我们都知道,Redis主从架构中,客户端的数据写入主节点成功后,主节点就会立即返回写入成功给客户端,然后异步将数据复制到从节点。所以有可能因为网络延迟等原因,造成主从数据同步不及时,在主节点数据还未完全同步到从节点的时候,主节点突然宕机。
那么这种情况下,因为采用的是Sentinal(哨兵)模式+Redis主从复制这种部署架构,数据丢失的多寡就有两种可能:
- 主节点宕机后,在Sentinal(哨兵)未检测到并执行主从切换之前快速重启(如服务器上有自动重启程序,一旦发现Redis宕机立即重启进程),如主节点没有做数据持久化,那么主节点重启后,因为主节点run id发生变化,主从节点的数据将会全部丢失,如主节点做了数据持久化,那么主节点重启后,只会丢失宕机前没有持久化的那部分数据,只是所有的从节点都需要做一次全量复制。
- 主节点宕机后,Sentinal(哨兵)集群检测到了主节点宕机并且已经从从节点中选出了一个主节点,完成了主节点切换。宕机的节点重启后,Sentinal(哨兵)会自动将该节点强制转换为新选举出来的主节点的从节点,并从新的那个主节点同步数据,那么这种情况下,会丢失宕机前未复制到新的主节点(原来的一个从节点)上的那部分数据。
数据丢失场景分析-集群脑裂
什么是集群脑裂?:集群脑裂指的就是因为网络原因,主节点A与从节点、哨兵节点之间断开了链接,但是还在运行,但是哨兵节点与主节点A间已经失去了心跳,认为主节点A宕机,哨兵节点在所有从节点中进行故障恢复,选出了一个新的主节点B继续对外提供服务,导致整个集群中有两个主节点。连接到旧的主节点A的客户端还在继续向该节点写数据,连接到新的主节点B的客户端也持续向新的主节点B写数据。造成同一个集群,有两个写入节点的情况。
那么在集群脑裂的情况下,因为读写分离的设计,主节点负责写数据,从节点负责读数据,写入主节点A的数据,在从节点根本无法读出来。节点A重启之后,会成为节点B的从节点,那么从节点A与从节点、哨兵节点之间断开连接之后,写入节点A的数据就会丢失。
减少数据丢失解决方案
如下配置可以减少异步复制和脑裂导致的数据丢失:
min-slaves-to-write n
min-slaves-max-lag s
这组命令表达的是,至少要保证n个从节点从主节点复制数据的延迟不能超过s秒钟,如n设置为1,s设置为10,就表示集群中至少要有1个从几点从主节点复制数据的延迟不能超过10秒钟,一旦所有的节点,从主节点同步数据的时间延迟都超过10秒,主节点停止接收任何写请求。
这样就能保证,即使因为脑裂,还是一部复制数据延迟情况下,数据丢失最多就丢失s秒的数据。
故障转移步骤详解请参考:https://blog.csdn.net/miaomiao19971215/article/details/108567837