当前位置: 首页 > 科技观察

面试官:你遇到过Redis故障吗,怎么解决的?

时间:2023-03-21 16:38:33 科技观察

1故障转移后重启和部分重新同步从Redis4.0开始,当一个实例在故障转移后提升为master时,它仍然可以与旧master的Replica部分重新同步。为此,Replica会记住旧master的旧复制ID和复制偏移量,以便即使询问旧复制ID,也可以将部分复制缓冲区提供给连接的Replica。但是升级后的Replica的新复制ID会有所不同,因为它构成了不同的数据集历史。例如,master可以返回available并在一段时间内继续接收写命令,那么在提升的Replica中使用相同的replicationID会违反一对replicationID和offset只能标识一个dataset的规则。在replica关闭并重启后,它可以在RDB文件中存储需要的信息,以便与master重新同步。这在升级时很有用。必要时最好使用SHUTDOWN命令对Replica进行保存退出操作。2主从数据不一致很明显,这是由于主从网络延迟造成的。2.1master重新同步越来越多的slave。它可以通过命令PSYNCmaster_run_idoffset来执行。2.2Masterless,slaves多,fullcopy,overwrite。这是因为Replica处于读写模式,所以:关闭Replica的读写模式或者删除Replica的数据,从Master重新全量拷贝3Delay写外部程序监控主从节点的replicationoffset,当延迟较大时发出告警或通知客户端切换到Master或其他节点。设置Replica:slave-serve-stale-data=no除了INFO和SLAVOF命令之外的任何请求都将返回错误“SYNCwithmasterinprogress”。当Replica与Master失去连接或仍在复制时,Replica可以执行以下操作:如果replica-serve-stale-data为yes(默认值),Replica仍将回复客户端请求,可能带有过期数据,或者,如果此是第一次同步,数据集可能只是空的如果replica-serve-stale-data设置为no,Replica将返回错误“SYNCwithmasterinprogress”:INFO,REPLICAOF,AUTH,PING,SHUTDOWN,REPLCCONF,ROLE,CONFIG,SUBSCRIBE,UNSUBSCRIBE,PSUBSCRIBE,PUNSUBSCRIBE,PUBLISH,PUBSUB,COMMAND,POST,HOST,LATENCY4脏数据4.1脏数据产生原因4.1.1Redis删除策略读取过期数据,读取过期数据是由于Redis删除策略:lazydeleteMaster每次读取命令都会检查K是否超时。如果超时,执行del命令删除K,然后异步del命令同步到Replica,保证数据复制的一致性。请记住Replica永远不会主动删除超时数据。定期删除RedisMaster。里面有个定时任务,会循环采样一定数量的K。当发现采样的K已经过期,会执行del,然后同步到各个Replica。当主动删除当前使用的内存超过maxmemory的限制时,触发主动清理策略。active设置的前提是设置maxMemory的值。注意:如果大量数据超时,主节点采样速度跟不上过期速度,主节点没有读取过期key,则从节点无法接收del命令。此时从节点读取数据已经超时。4.1.2从节点可写如果从节点(默认读模式)处于读写模式,从节点的数据可能会被误写入,以后会变成脏数据。4.2解决方案4.2.1忽略12306剩余支票、双十一闪购等库存,会发现数据经常不一致。因为你查询得到的数据,需要允许写错。4.2.2选择性读取master但实际下单扣库存时,必须保证数据的正确性。如果选择强读master,slave会间接成为一个backupserver(某业务)。4.2.3Slave节点是只读的,防止slave写脏数据。4.2.4Redis自优化Redis3.2版本解决了Redis删除策略导致的过期数据。在这个版本中,slave在读取数据之前,会检查K的过期时间来决定是否返回数据。5数据安全5.1关闭master节点的持久化为了提高Redis的性能,一般会关闭Master的持久化功能(这样所有的数据都会持久化到slave中),因为master-master时master会bgsaverdb奴隶是同步的。但是这样也会带来复制的安全问题。在使用Redis复制功能时的设置中,建议在master和slave中开启持久化。Master自动重启应该在不可能时禁用,例如由于磁盘性能非常低而导致的延迟问题。风险场景关闭Master的持久化设置,Replica1和Replica2从Master上复制数据。Master只有内存数据,没有磁盘数据。Master宕机时由于自动重启机制重启,但重启后由于持久化关闭,Master数据集为空!重启后Master发现runId变了,也会重新和Slave节点建立连接。两个Slave节点会发起复制请求,从Master上复制数据,但是此时Master的数据集是空的,所以复制的结果,会破坏它们之前的数据副本,变成一个空的数据集。图5.1.1该方案牺牲了性能,开启了Master的持久化功能。为了性能,如果还是选择关闭,那就让master节点不要自动重启,比如不要有Docker或者脚本之类的自动重启机制。本文转载自微信公众号「JavaEdge」,可通过以下二维码关注。转载本文请联系JavaEdge公众号。