对于读占比较高的场景可以通過把一部分流量分摊导出从节点(salve) 来减轻主节点(master)压力,同时需要主要只对主节点执行写操作如下图:
当使用从节点响应读请求时,业務端可能会遇到以下问题:
Redis 复制数的延迟由于异步复制特性是无法避免的延迟取决于网络带宽和命令阻塞情况,对于无法容忍大量延迟場景可以编写外部监控程序监听主从节点的复制偏移量,当延迟较大时触发报警或者通知客户端避免读取延迟过高的从节点实现逻辑洳下图:
1) 监控程序(monitor) 定期检查主从节点的偏移量,主节点偏移量在info replication 的master_repl_offset 指标记录从节点 偏移量可以查询主节点的slave0 字段的offset指标,它们的差值僦是主从节点延迟的字节 量
2)当延迟字节量过高时,比如超过10M监控程序触发报警并通知客户端从节点延迟过高。可以采用Zookeeper的监听回调機制实现客户端通知
3) 客户端接到具体的从节点高延迟通知后,修改读命令路由到其他从节点或主节点上当延迟回复后,再次通知客戶端回复从节点的读命令请求。
这种方案成本较高需要单独修改适配Redis的客户端类库。
当主节点存储大量设置超时的数据时如清理微信缓存的后果数据,Redis内部需要维护过期数据删除策略删除策略主要有两种:惰性删除和定时删除。
惰性删除:主节点每次处理读取命令時都会检查键是否超时,如果超时则执行del命令删除键对象那个之后del命令也会异步 发送给 从节点
需要注意的是为了保证复制的一致性,從节点自身永远不会主动删除超时数据如上图。
Redis主节点在内部定时任务会循环采样一定数量的键当发现采样的键过期就执行del命令,之後再同步给从节点如下图
如果此时 数据的大量超时,主节点采样速度跟不上过期速度且主节点没有读取过期键的操作那么从节点将无法收到del命令,这时在从节点 上可以读取到已经超时的数据Redis在3.2 版本解决了这个问题,从节点 读取数据之前会检查键的过期时间来决定是否返回数据可以升级到3.2版本来规避这个问题。
对于从节点故障问题需要在客户端维护可用从节点列表,当从节点故障时立刻切换到其他從节点或主节点上
建议大家在做读写分离时,可以考虑使用Redis Cluster等分布式解决方案