基本概念
-
从库的作用
- 从库处理读请求,分担主库的压力
- 还能进行主从切换,提供可靠的服务
-
主从库存在的问题
- 主从数据不一致
- 读取过期时间
主从数据不一致
-
什么是主从数据不一致:从库读取的值与主库不一致
-
产生的原因:主从库间命令复制是异步进行的
- 主库接收到新的写命令,发送给从库
- 主库执行完命令后向客户端返回结果
-
造成从库同步命令滞后的原因:
- 主从库间的网络可能会有传输延迟
- 处理其他复杂度高的命令而阻塞
-
解决上述问题的办法
-
在硬件环境配置方面,我们要尽量保证主从库间的网络连接状况良好
-
开发一个外部程序来监控主从库间的复制进度
- 原理:利用Redis 的 INFO replication 命令分别查看主库接收写命令的进度信息 (master_repl_offset) 和从库复制写命令的进度信息 (slave_repl_offset)
- 具体实现:master_repl_offset 减去 slave_repl_offset大于一定的阈值后,停止读取该从库
-
\
读取过期数据
-
什么是读取过期数据:可以在从库读取到已经过期的数据
-
产生的原因:惰性删除策略+定期删除策略\
-
惰性删除策略
-
数据过期后,不会立即删除数据,而是等到再次读取后,判断其过期后删除\
-
减少删除操作对 CPU 资源的使用
-
-
定期删除策略
- Redis 每隔一段时间(默认 100ms),就会随机选出一定数量的数据,检查它们是否过期,并把其中过期的数据删除\
-
-
为什么读到过期数据
-
定期删除策略只会删除一小部分数据\
-
惰性删除下,必须再次访问才会删除
- 主库读到过期数据后会删除该数据
- 从库读到过期数据后,从库不会触发数据删除
-
3.2 之前的版本,那么,从库在服务读请求时,并不会判断数据是否过期,而是会返回过期数据
-
3.2 版本后,Redis 做了改进,如果读取的数据已经过期了,从库虽然不会删除,但是会返回空值,这就避免了客户端读到过期数据\
-
-
3.2 版本后仍然有概率读到过期数据\
-
设置过期时间指令
-
EXPIRE 和 PEXPIRE:它们给数据设置的是从命令执行时开始计算的存活时间(当从库执行时,会有延迟)\
-
EXPIREAT 和 PEXPIREAT:它们会直接把数据的过期时间设置为具体的一个时间点\
-
-
尽量使用EXPIREAT/PEXPIREAT 命令,避免从库执行延迟
-
不合理配置项导致的服务挂掉
-
protected-mode
-
作用:限定哨兵实例能否被其他服务器访问
-
yes 无法与其他服务器通信\
-
no 可以与其他服务器通信
-
-
-
cluster-node-timeout\
- 用于判断实例存活时间,建议设置大一点,避免主从切换导致下线误判
总结
-
主从数据不一致:通过监控主从的偏移量
-
读到过期数据,这是可以提前规避:使用EXPIREAT 和 PEXPIREAT\
-
slave-serve-stale-data 配置项设置了从库能否处理数据读写命令,你可以把它设置为 no(从库只能服务 INFO、SLAVEOF 命令)\
-
slave-read-only 设置为 yes 时,从库只能处理读请求,无法处理写请求\
- 不要双写,数据更加不一致