主从数据不一致
主从数据不一致大方向分为两种,主多从少和主少从多。
- 主多从少解决方案:部分重同步。可以通过命令 PSYNC master_run_id offset 执行。
- 主少从多解决方案:全量复制,覆盖。这种情况是因为从节点读写模式导致的,关闭从节点读写模式,或者删除从节点数据,重新从主节点全量复制。
数据脏读
脏数据产生的原因
1、读到过期数据
读到过期数据的原因是因为 Redis 的删除策略导致的,删除策略主要有以下几种:
惰性删除:master节点每次读取命令时都会检查键是否超时,如果超时则执行del命令删除键对象,之后异步把del命令slave节点,这样可以保证数据复制的一致性,slave节点是永远不会主动去删除超时数据的。
定时删除:Redis的master节点在内部定时任务,会循环采样一定数量的键,当发现采样的键过期时,会执行del命令,之后再同步个slave节点。
主动删除:当前已用内存超过maxMemory限定时,触发主动清理策略。主动设置的前提是设置了maxMemory的值
2、从节点可写
如果从节点是读写模式的话,可能误写入从节点的数据后期会成为脏数据。
解决方案:
- 忽略
- 选择性强制读主,从节点简介变为了备份服务器(某个业务)。
从节点只读 - Redis3.2版本中已经解决了 Redis 删除策略导致的过期数据,在此版本中slave节点读取数据之前会检查键过期时间来决定是否返回数据的。
数据延迟
Redis复制数据的延迟,是由于复制的异步特性导致的,因此无法避免。但是延迟主要是取决于网络带宽和命令阻塞的情况而定,比如master节点刚写入数据,在slave节点上是可能读取不到数据的。
编写外部监控程序
在大量延迟的场景下,可以编写外部程序监听主从节点的复制偏移量,延迟较大时发出报警或通知,实现方式如下:
- 对于具体延迟,监控程序可通过检查 info replication 的 offset 指标记录,从节点的偏移量可以查询主节点的offset指标,它们的差值就是主从延迟的字节量。
- 如果字节量过高,监控程序触发客户端通知。
- 客户端接收通知后,修改读命令路由到主节点或其他从节点上,当延迟恢复后,再通知客户端。
修改从节点参数配置
从节点的 slave-serve-stale-data 参数也与此有关,它控制这种情况下从节点的表现 当从库同主机失去连接或者复制正在进行,从机库有两种运行方式:
- 如果slave-serve-stale-data设置为yes(默认设置),从库会继续响应客户端的请求。
- 如果slave-serve-stale-data设置为no,除去INFO和SLAVOF命令之外的任何请求都会返回一个错误”SYNC with master in progress”。
数据安全性
在使用 Redis 复制功能时的设置中,强烈建议在 master 和在 slave 中启用持久化。当不可能启用时,例如由于非常慢的磁盘性能而导致的延迟问题,应该禁用主节点自动重启功能。
规避全量复制
复制积压缓冲区不足
master生成RDB同步到slave,slave加载RDB这段时间里,master的所有写命令都会保存到一个复制缓冲队列里(如果主从直接网络抖动,进行部分复制也是走这个逻辑),待slave加载完RDB后,拿offset的值到这个队列里判断,如果在这个队列中,则把这个队列从offset到末尾全部同步过来,这个队列的默认值为1M。而如果发现offset不在这个队列,就会产生全量复制。
解决办法:增大复制缓冲区的配置 rel_backlog_size 默认1M,我们可以设置大一些,从而来加大我们offset的命中率。这个值,我们可以假设,一般我们网络故障时间一般是分钟级别,那我们可以根据我们当前的QPS来算一下每分钟可以写入多少字节,再乘以我们可能发生故障的分钟就可以得到我们这个理想的值。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。