知识卡片
一致性优先于读写分离的业务判断
内容
Codis没有像很多分布式KV/缓存方案那样支持读写分离,这不是能力上做不到,而是一个主动的设计取舍:只要引入异步复制的从库来分担读流量,就必然要接受主从之间存在复制延迟窗口——一旦在这个窗口内发生Failover,最近异步复制的数据就可能丢失,而且没有办法预先知道到底丢了哪些数据。Codis团队认为这种”数据可能悄悄丢失且无法定位”的代价,对大多数使用Redis的业务来说是不可接受的,所以选择放弃读写分离带来的读性能提升,用[[Codis相比Redis Cluster的架构选择:无状态Proxy+可插拔存储]]里描述的水平扩展能力去覆盖读吞吐需求。这揭示了一条更通用的架构决策原则:性能与一致性之间的取舍不该由中间件单方面替业务做主,而应该反过来问——业务能不能容忍”数据丢失窗口”这种不确定性。能容忍的场景(如展示类缓存、可重建的统计数据)可以自己在业务层做读写分离和降级;不能容忍的场景(如涉及金额、库存、状态机流转的数据)应当直接使用强一致的主库读写,而不是依赖中间件提供的”看起来更快但边界不清”的读写分离特性。把”一致性代价谁来承担”这个问题想清楚,比单纯追求读性能更重要。
参考来源
- 位置:《高可用架构(第1卷)》第2章《高可用架构原理与分布式实践》"2.1 Codis作者细说分布式Redis架构设计"节,"2.1.2 Codis的核心设计"(源文件:_epub-src/OEBPS/Text/Chapter2_1_3.xhtml)
- 结论依据:原文说明Codis不支持读写分离是因为"如果做异步复制,那么就一定会存在数据不一致的情况……我们认为这种数据丢失是不可接受的",直接支撑本卡片"一致性优先于性能"的结论。
- 原始内容:Codis没有支持读写分离……如果做异步复制,那么就一定会存在数据不一致的情况,一旦发生failover,可能就会丢失部分数据,而且没有办法知道具体丢了哪些数据,这种情况是不可接受的。