4. 数据复制技术:同步复制、异步复制、半同步复制、日志传输技术对比
数据复制,说白了就是怎么把数据从A点搬到B点,还要保证B点能用。这听起来简单,但里面的门道可不少。我见过太多项目,就是因为选错了复制方式,最后灾备切换时出了大问题。
今天咱们就把这几种复制技术掰开揉碎了讲清楚。同步、异步、半同步,还有日志传输,它们到底有什么区别?各自适合什么场景?
核心观点:没有最好的复制技术,只有最合适的。选型的关键在于——你能容忍丢多少数据,以及你能接受多大的性能损耗。
4.1 同步复制:数据零丢失,但性能代价高
同步复制的逻辑很直白:主库写数据,必须等备库确认写成功了,才告诉客户端“写完了”。
流程大概是这样的:
- 客户端发起写请求到主库
- 主库写入本地,同时把数据发给备库
- 备库写入完成,回复确认
- 主库收到确认,才回复客户端“成功”
你想想看,这意味着什么?每次写操作都要等网络往返。如果主备库在同一个机房,延迟还能接受。但如果跨城市,哪怕只有5毫秒的延迟,整个系统的写性能就肉眼可见地往下掉。
我曾经踩过的坑:有一次帮客户做金融核心系统的灾备方案,客户坚持要同步复制,说“一分钱数据都不能丢”。结果上线后,业务部门投诉说系统变慢了。一查,主备库相距800公里,网络延迟12毫秒,写性能直接掉了60%。最后没办法,只能改成半同步复制。
适用场景:
- 金融交易系统、账务系统(数据零容忍)
- 主备库在同一机房或同城(延迟 < 1ms)
- 写并发不高,但对一致性要求极高
不适用场景:
- 跨地域灾备(延迟太高)
- 高并发写入场景(性能瓶颈明显)
- 网络不稳定的环境(频繁超时)
4.2 异步复制:性能最好,但可能丢数据
异步复制就洒脱多了。主库写完本地就直接告诉客户端“成功了”,然后把数据扔给备库慢慢同步。备库啥时候写完,主库不管。
这样做的好处很明显——性能几乎不受影响。但坏处也很要命:如果主库在数据还没同步到备库时挂了,那这部分数据就丢了。
我个人的习惯是,在非核心业务系统上用异步复制。比如日志系统、报表系统、缓存层,这些丢了还能重新生成,问题不大。
避坑指南:异步复制不是“完全不管”。我建议你监控主备库之间的同步延迟。如果延迟超过阈值(比如30秒),就要告警。否则你以为数据都同步过去了,其实备库还差一大截。
适用场景:
- 日志、监控、报表等非核心业务
- 跨地域灾备(延迟几百毫秒甚至更高)
- 读多写少的系统
不适用场景:
- 金融、交易、账户等核心系统
- 对RPO(恢复点目标)有严格要求的场景
4.3 半同步复制:性能和安全的折中方案
半同步复制,你可以把它理解为“同步复制”和“异步复制”的中间态。它的逻辑是:主库写完本地后,至少等一个备库确认写成功,才回复客户端。
这样做的好处是:
- 比同步复制快(不用等所有备库)
- 比异步复制安全(至少有一个备库有数据)
MySQL 5.7 之后默认的复制模式就是半同步。我个人非常推荐在大多数业务系统中使用这种模式。
关键参数:半同步复制有一个超时机制。如果备库在规定时间内没回复,主库会自动降级为异步复制。这个超时时间要设置合理,我一般设成5-10秒。
适用场景:
- 大多数在线业务系统
- 同城双活或主备架构
- 对RPO要求 < 1秒的场景
4.4 日志传输技术:数据库层面的复制基石
前面说的同步、异步、半同步,其实都是“策略”。而日志传输,是这些策略的底层实现方式。
以MySQL为例,它的复制就是基于binlog(二进制日志)的。主库把数据变更写成binlog,备库拉取binlog并回放。Oracle的Data Guard用的是Redo Log,SQL Server用的是事务日志。
日志传输的核心优势是:
- 增量传输:只传变更,不传全量数据
- 异步解耦:主库写日志和备库拉日志是独立的
- 可回溯:日志可以用于时间点恢复
我曾经遇到的问题:有一次MySQL主库的binlog文件损坏,导致备库同步中断。从那以后,我养成了一个习惯——给binlog做双份备份,一份在本地,一份在远程存储。别等到出事了才后悔。
4.5 四种技术对比总表
为了方便你选型,我把这四种技术放在一起对比:
| 对比维度 | 同步复制 | 异步复制 | 半同步复制 | 日志传输 |
|---|---|---|---|---|
| 数据一致性 | 强一致 | 最终一致 | 接近强一致 | 取决于策略 |
| 性能影响 | 高(延迟叠加) | 低(几乎无影响) | 中(等一个备库) | 低(异步传输) |
| 数据丢失风险 | 零 | 高(可能丢一批) | 低(最多丢一个事务) | 取决于策略 |
| 典型RPO | 0 | 秒级到分钟级 | 接近0 | 秒级 |
| 典型RTO | 分钟级 | 分钟级 | 分钟级 | 分钟级 |
| 网络要求 | 低延迟、高稳定 | 普通网络即可 | 中等 | 中等 |
| 适用距离 | 同机房/同城 | 跨地域 | 同城/异地 | 不限 |
| 典型实现 | MySQL Group Replication | MySQL Async Replication | MySQL Semi-Sync | Binlog/Redo Log |
4.6 核心逻辑框架图
下面这张图展示了四种复制技术的核心逻辑和关系:
4.7 选型建议
说了这么多,到底该怎么选?我根据实际经验给你几个建议:
- 核心交易系统:用半同步复制,配合日志传输。既保证数据安全,又不会太影响性能。
- 跨地域灾备:用异步复制。别想着同步,网络延迟会让你崩溃的。
- 同城双活:可以用同步复制,但前提是网络延迟 < 1ms。
- 日志归档:用日志传输技术,配合异步复制。把binlog或redo log实时传到异地存储。
我的个人习惯:不管用哪种复制技术,我都会在备库上开启“只读模式”。这样既能分担读压力,又能防止误操作写入备库导致数据不一致。你想想看,如果备库被写入了,主备切换时数据对不上,那可就麻烦了。