2. 副本与复制:同步复制与异步复制的原理与对比
聊到多副本,绕不开的核心就是「复制」——怎么把一份数据同步到其他节点上去。这里有两个最基础的模式:同步复制和异步复制。不是哪个更好,而是看场景怎么选。我这几年做过的系统里,因为选错复制模式导致线上事故的,少说也有三四回了。
2.1 同步复制:强一致性的代价
同步复制的逻辑其实很直白:只有所有副本都写成功了,才算写成功。 客户端发起写请求,主节点必须等所有从节点都返回确认,再回复客户端「OK」。
核心特征:
- 强一致性:读写都是最新值
- 高延迟:最慢的节点决定响应时间
- 低可用:一个从节点挂了,写入就阻塞
我在做金融系统时,选的就是同步复制。交易记录少一条就是损失,不能用「最终一致」来糊弄。但代价也明显——有一次MySQL从节点磁盘打满,主库的写入请求直接全部超时,差点引发雪崩。
2.2 异步复制:性能优先的妥协
异步复制正好反过来:主节点写完了就马上告诉客户端「成功」,复制到从节点的操作放到后台去做。 客户端不管从节点是否写完。
核心特征:
- 最终一致性:短时间可能读到旧数据
- 低延迟:不受从节点性能影响
- 高可用:主节点不依赖从节点状态
大部分互联网业务用的是异步复制。比如发微博、点赞、评论,丢失几毫秒的数据,用户完全感知不到。但你想想看——万一主节点挂了,那部分还没同步的数据就彻底丢了。
我曾经… 遇到过一个案例:某团队做用户会话缓存,选了异步复制。主库宕机后,所有新登录的用户会话全部丢失,几千人同时被踢下线。痛点就是「丢了不可接受的数据」。
2.3 核心对比:一张表说清楚
| 对比维度 | 同步复制 | 异步复制 |
|---|---|---|
| 一致性 | 强一致性 | 最终一致性 |
| 写延迟 | 高(等待最慢节点) | 低(只写主节点) |
| 数据安全 | 主节点故障,数据不丢 | 主节点故障,可能丢数据 |
| 可用性 | 低(从节点故障影响写) | 高(从节点故障不影响写) |
| 适用范围 | 金融、交易、元数据 | 日志、缓存、社交、大数据 |
个人习惯:我通常会把这个表贴在团队的白板上。选复制模式时先问一句:「丢了最后几秒的数据,业务受不受得了?」受得了就异步,受不了就同步。
2.4 复制流程对比(SVG)
下面这张图把两种模式的核心流程画在一起,方便你对比理解。
简单解释一下这张图。左边同步复制:客户端等主节点,主节点等所有从节点,确认消息一条都不能少。右边异步复制:客户端只管写,从节点什么时候收到——那是主节点自己的事,后台慢慢推过去就行。
2.5 半同步复制:折中的方案
我个人习惯在「不能丢数据,但又受不了同步的高延迟」的场景下,用半同步复制。比如MySQL的semi-sync replication。
半同步的核心思路:主节点至少等一个从节点确认,就返回成功。 不要求所有从节点都写完。这样做的好处是:既保证了一定程度的数据安全,又不会让写入延迟被最慢的那个从节点拖死。
2.6 选型建议:我的实践经验
- 金融交易、库存、订单 → 同步复制或半同步。数据一致性高于一切。
- 日志、监控、大数据 → 异步复制。丢了无所谓,整体往前跑。
- 缓存、会话 → 异步复制,但得加一个兜底——比如Redis的主从故障时,丢掉的key可以从数据源重建。
我曾经… 在一家电商公司看到他们把所有MySQL都配了同步复制。结果大促时一个从节点慢查询导致全库写入超时。后来我强制要求:核心交易库用半同步,非核心库全部切异步。压测下来,写入RT直接降了60%。
记住一个原则:没有完美的复制模式,只有适合你业务的复制模式。同步换一致性,异步换性能,半同步就是那个「既要…又要…」的折中怪。