? ? ? ? 会导致redis集群写操作丢失的情况有:
? ? ? ? 1、主节点发生了宕机,并且宕机时,最新的写操作还没有复制到从节点。当某个从节点被提升为新的主节点之后,没来得及复制的那一部分数据就丢失了。
? ? ? ? 2、集群脑裂问题导致的写操作丢失。
????????下面来详细说明集群脑裂导致的写丢失。
? ? ? ? 什么是redis集群的脑裂问题呢?当我们部署了redis主从架构,并且部署了sentinel去监控主节点的状态,当因为网络波动等原因而导致sentinel收不到主节点的心跳时,这个主节点就被判定为下线,sentinel会将某个从节点提升为新的主节点继续提供服务,但原主节点并未真正下线,当网络恢复时,集群中就出现了两个主节点,而客户端不知道应该连接哪个主节点执行写操作,所以不同的客户端连接到了不同的主节点上去写数据。因为网络恢复,sentinel也再次收到了原主节点的心跳,发现集群中有两个节点存在,会将原主节点降为从节点,这个从节点在第一次连接到现在的新主节点时,会执行一次全量同步,经过全量同步之后,在脑裂期间被写到这个节点上的数据就被覆盖了,写丢失就发生了。
? ? ? ? 会引起redis集群脑裂问题的原因有:
? ? ? ? 1、网络原因。
? ? ? ? 2、redis主节点没有使用专用服务器,它所在的服务器上还部署了其他应用,尤其是比较消耗资源的应用,当其他应用大量占用着系统资源时,会导致redis主节点的主进程阻塞而无法正常地向sentinel发送心跳。
? ? ? ? 3、redis主节点自身原因导致的阻塞,比如,我们在主节点上开启了rdb持久化功能,虽然rdb文件的保存操作是由子进程去执行的,但是子进程是由主进程fork出来的,这个fork操作会阻塞主进程,当主节点的内存数据集很大时,fork过程会将主进程阻塞很久,从而导致主节点无法正常地向sentinel发送心跳。
? ? ? ? 那么怎么去避免redis集群脑裂问题的发生呢?
? ? ? ? 1、应该将sentinel与主从节点部署在同一个局域网中,以保证它们之间的连接的稳定性及数据传输的效率。
? ? ? ? 2、redis主节点应该使用专用服务器部署,这个服务器上不要部署其他的应用。
? ? ? ? 3、要避免redis自身原因所造成的阻塞,比如,如果有数据的持久化需求,持久化功能应该在某个从节点上开启,因为持久化方式我们无论选择的是rdb还是aof,都会在一定程度上阻塞主进程,在从节点上开启持久化功能时,要注意数据文件的备份。再比如,我们不要在主节点上执行会阻塞主进程的命令,如keys命令。
? ? ? ? 4、redis配置文件中有一个属性可以用来设置主节点的最小从连接数,我们可以在redis主节点上进行这个配置,以保证当有一定数量的从连接到这个主时,这个主才能对客户端提供写服务。这样即便是sentinel又提升了新的主节点出来,但因为sentinel去修改了其他从节点的slaveof,让其他从节点都去连接新的主节点了,所以原主节点因为达不到配置的从连接数而不再对客户端提供写服务。