1.主从同步数据不一致的问题?

        这个问题产生的原因有很多,假设从库开启了只读设置,slave-read-only = yes。主从数据不一致的原因主要是因为主从复制时异步的,

       第一种是因为网络抖动等原因导致的主从同步延时,导致请求到达从库时从库还没有接受到主库的命令。

       第二种是主从同步的命令到达从库时,从库正在进行阻塞操作比如bigkey的遍历,导致从库没有及时执行命令,而当此时主库又有该key的

更新时,从库此时数据不一致的情况会更加的严重。

解决方案:网络延时的问题,可以保持主从备份在同一机房,或者同一VPC的网络环境下,减少网络原因导致的主从数据不一致。另外不要将

网络io密集型的应用部署在redis主从环境中。另外我们可以额外开发监控程序,监控主从同步的进度。我们可以通过Info命令获取master上的主从

复制进度master_repl_offset值,然后遍历所有从库通过Info命令获取slave_repl_offset的值,做差diff = master - slave。我们设置一个合理的diff值

当这个值超过某个阈值时,我们就主动下线从库,当从库进度恢复时,我们又将从库拉上来。

 

2.读取过期数据


redis删除策略是两种,主动删除和惰性删除,主动删除是每次执行命令时都会判断当前key是不是已经过期了。惰性删除是redis每隔一段时间(100ms)会

随机选取一些看,如果有过期的就删除掉,之所以采取这种措施是在性能之间权衡后的选择。如果一次性删除所有Key又会导致主线程阻塞,所以为了折衷

选取这种策略。

读取过期数据的原因,主库同步的key到时间过期了,但是从库被读到了,这时候从库不会主动删除数据,如果是redis3.2版本之前会读取到删除数据,3.2版本

以后会返回空值。所以配置主从时,尽量选择3.2版本以上的

即使是3.2版本以后还是任然会读取的过期数据,这是因为我们在给键设置过期时间时主要有四种命令,EXPIRE、PEXPIRE、EXPIREAT、PEXPIREAT,当主库使用

EXPIRE、PEXPIRE两种命令设置过期时间时,这是根据当前时间设置ttl过期的,意思就是如果主库时12点01分00秒,设置EXPIRE 60时,表示60秒后键会过期。如果

是这种情况下,如果主从网络延迟两秒钟,那如果主库当时是12.01.00秒设置成功的,那么从库就是12.01.02设置的Key。所以当从库12.02.01能返回已经过期的key。另外

一种情况是假设Key是十秒过期的如果第九秒的时候主库重新设置了过期时间,而从库因为延迟或者因为执行阻塞命令的原因执行晚了。此时从库里的键就没有加时成功

这时候从库就没读取到正确的值。

为避免读取到过期的数据,我们可以使用另外的过期命令,是表示到某个时间点就过期,然后同时需要保持主从的时钟一致

 

3.不合理的配置导致主从问题

 

        如果我们主从设置并且设置了哨兵模式,如果此时配置有protected-mode=yes 时,此时,哨兵模式只支持本地访问,其他哨兵节点是无法访问当前节点的,此时就会导致哨兵集群

无法正常提供服务

        另一个参数是cluster-node-timeout 实例响应集群心跳的时间,集群的中为节点配置的一主一从机制,到主库宕机了,如果还因为网络延迟等原因导致心跳没有及时响应,就会导致

这个集群不可用。所以这里大佬们的建议是适当加大这个延迟时间一般设置10-20S.