缓存一致性问题之主从复制

文章基于redis缓存
缓存设计问题不讨论,感兴趣的同学可以入这个传送门:https://blog.csdn.net/u010597819/article/details/104220707
缓存一致性问题讨论主要讨论以下两个层次

  1. 主从一致性
  2. 缓存与数据库一致性

redis主从一致性问题

最终一致性

以哨兵模式为例说明,主从存在延迟,但保证最终一致性。简而言之主从同步的方案为

  1. 全量复制,redis fork一个子进程导出rdb文件,并同时记录之后的写命令至缓存(backlog)。rdb同步完成后再将缓存中的增量写同步至从节点
  2. 增量复制,基于缓存日志backlog增量同步

redis默认同步是异步的,无法保证强一致性。WAIT命令也无法保证强所有副本的强一致性,且强一致性依赖于从库持久化配置
Redis fsync 刷新数据至磁盘有三种方式:

  • 每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全
  • 每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
  • 从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。

redis推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
缓存一致性问题之主从复制_第1张图片

强一致性

有两种方案

  1. 基于Cache aside模式双写
  2. 主从同步复制,WAIT命令,但是不能设置多个从,WAIT不保障写命令已经全部到达从库才返回(类似mysql半同步复制,但是足以变相实现同步,一主一从方案),并且设置从库持久化配置为每次有新命令追加到 AOF 文件时就执行一次 fsync

两种方案可以说性能均不佳,但是如果想要兼得是不可能,CAP定理是无法打破的-_-!!!
当然其实可以选择redis 集群,对数据进行分片,降低影响范围,但是集群分片中的实例为了性能,主从复制采用异步模式,无法保障强一致性,官方有说明,也给出了承诺说后面会考虑强一致性方案的支持

读取请求的主从选择

  1. 强制读主库,保证强一致性,从库也失去了意义
  2. 选择性读主,对于刚刚写入的key读主,延迟一定时间后读从库,相当于让子弹飞一会儿,但是依然可能脏读。弱一致性

总结

对于redis的HA强一致性支持目前没有很好的方案,性能与强一致性是互斥的,只能根据实际场景来进行权衡决策。如果大家有很好的方案欢迎留言讨论啊
数据库主从一致性不展开讲,mysql本身支持异步同步以及半同步复制方案,半同步方案简而言之就是主节点数据同步阻塞至主数据复制到任意一个从节点(主节点收到任意一个从节点复制成功通知)

你可能感兴趣的:(缓存,redis,缓存,分布式,aof,rdb)