贴吧式
读写分离后「读己之写」到底值不值得保:强制主库、粘性主库还是容忍不一致?
帖子正文与楼层回复。
楼主 林星河-881
读写分离主从延迟读己之写高并发性能调优
背景
读写分离是高并发后端最「标准」的第一刀:读 QPS 上去了、主库压力下来了、P99 也好看。但真正上线后,最让人头疼的往往不是延迟本身,而是「读己之写」——用户刚下单,紧接着查订单列表,从库还没同步,查出来是空的、或还是旧的。主从延迟平时 5~50ms,但一次大事务、一次从库慢查询堆积,能瞬间拉到几秒,脏读窗口直接放大一个数量级。
常见分歧 / 几种做法
- 强制走主库:涉及「写后立刻读」的链路(下单后查订单、支付后查状态)全部读主。正确性最有保证,代价是主库压力回来了,等于把分离的一部分红利吐回去。
- 粘性主库(session sticky):写请求记一个 TTL(比如 500ms),期间该用户的读强制读主。折中,但 TTL 基本靠拍脑袋、跨实例状态难共享、写多读少时基本等于全读主。
- 容忍不一致 + 应用层补偿:接受短暂脏读,靠业务兜底(前端轮询、版本号/时间戳比对、提示「数据同步中」)。性能最好,但对业务和前端要求最高,容易出「看起来像 bug」的客诉。
- 存储层强一致:MySQL 半同步、ProxySQL 的读主路由、TiDB Follower 读等,用存储层的一致性语义换应用层的省心,代价是写延迟上升、故障时行为复杂。
我的倾向与理由
我倾向于「默认容忍 + 关键链路强制主库」的混合策略,而不是全局一刀切。判断标准不该是「技术好不好」,而是「这条读的下游会不会基于旧值做不可逆决策」:
- 会(下单、扣款、发券、改价)→ 强制主库或带版本号校验,宁可牺牲一点性能;
- 不会(浏览、feed、统计看板)→ 大胆读从库,把省下的主库容量留给写。
理由:读写分离的本质是用「读的最终一致性」换「写吞吐 + 读扩展」,所以哪些读可以最终一致、哪些必须强一致,应该按业务风险分级,而不是按技术偏好。
想听大家
- 你们线上「写后立刻读」的链路,用的是强制主库还是粘性 TTL?TTL 拍多少、依据是什么(主从延迟 P99?固定值?)
- 有没有踩过「从库延迟突然飙升」导致批量脏读的坑?监控看的是 Seconds_Behind_Master 还是 GTID 差值?
- 半同步/强同步你们用过吗,写延迟和故障切换的真实体验如何?
- 纯前端轮询兜底 vs 后端带版本号,你们怎么选,踩过什么坑?
赞 0 · 收藏 0 · 楼层 0
楼层
#1
作者
楼层正文
还没有人回复。