4. 数据复制技术:同步复制、异步复制、半同步复制、日志传送
数据复制,说白了就是怎么把数据从A点搬到B点,还要保证B点能用。这听起来简单,但真做起来,坑多得很。我这些年见过的复制方案,少说也有几十种,但核心原理就那么几个。今天咱们就把这四种最基础、也最常用的复制技术掰开揉碎了讲清楚。
4.1 同步复制:强一致性的代价
同步复制,就是主库写完,必须等从库也写完,才给客户端返回成功。你想想看,这就像你去银行存钱,柜员必须等后台系统确认入账了,才告诉你“办好了”。
核心特征:强一致性,但性能受网络延迟影响极大。
我在项目中遇到过这样一个场景:金融交易系统,要求数据不能丢。当时我们用的就是同步复制。每次写操作,主库要等至少一个从库确认写入,才返回成功。这样做的好处很明显——主库挂了,从库直接顶上,数据零丢失。
但代价呢?我举个例子:
# 伪代码:同步复制流程
1. 客户端发起写请求
2. 主库写入本地事务日志
3. 主库将日志发送给所有从库
4. 主库等待从库返回ACK
5. 所有从库返回ACK后,主库提交事务
6. 主库返回成功给客户端
这里有个关键点:只要有一个从库没回应,主库就得一直等。网络抖动一下,整个系统的写入延迟就上去了。我记得有一次,机房光纤被挖断了,从库延迟飙到几百毫秒,主库的写入队列直接爆了。嗯,从那以后,我对同步复制的网络要求就特别敏感。
| 特性 | 同步复制 |
|---|---|
| 数据一致性 | 强一致,主从数据实时相同 |
| 写入性能 | 受网络延迟影响,通常较慢 |
| 适用场景 | 金融、交易、账务等强一致性要求 |
| 容灾能力 | 主库故障,从库可立即接管,数据零丢失 |
4.2 异步复制:性能优先的选择
异步复制就完全不一样了。主库写完本地,立马返回成功,然后后台慢慢把数据同步给从库。说白了,就是“我先答应你,后面再补手续”。
这样做的好处很明显——性能极高。主库不用等任何人,写入延迟就是本地磁盘的写入时间。我见过很多互联网公司,用户量上亿,用的就是异步复制。为什么?因为用户发个帖子,延迟几毫秒和几十毫秒,体验差别太大了。
我的建议:如果业务能接受秒级甚至分钟级的数据丢失,异步复制是最经济的选择。比如日志系统、用户行为分析、非关键配置同步。
但代价呢?主库挂了,没来得及同步的数据就丢了。你想想看,如果主库在写入后、同步前突然宕机,那部分数据就永远消失了。我曾经帮一个电商平台复盘过事故:双十一大促,主库压力太大,异步复制的延迟从几秒飙到了几分钟。结果主库挂了,这几分钟的订单数据全丢了。嗯,那个场景,我到现在还记得。
# 伪代码:异步复制流程
1. 客户端发起写请求
2. 主库写入本地事务日志
3. 主库立即返回成功给客户端
4. 后台线程异步将日志发送给从库
5. 从库收到日志后写入本地
6. 主库不等待从库ACK
4.3 半同步复制:折中的艺术
半同步复制,就是同步和异步的折中方案。主库写完本地,等至少一个从库确认,就返回成功。其他的从库,异步同步就行。
为什么会这样?我解释一下:同步复制要等所有从库,太慢;异步复制不等任何人,太危险。半同步复制只等一个,既保证了数据不丢,又不会太影响性能。
注意:半同步复制不是万能的。如果那个被等的从库挂了,主库会自动降级为异步模式。这时候如果主库也挂了,数据还是会丢。所以,半同步复制只是降低了风险,并没有完全消除。
我记得在MySQL的MGR(Group Replication)方案中,默认就是半同步复制。很多生产环境也推荐用这个模式。为什么?因为大多数场景下,只要有一个从库确认了,数据就安全了。你想想看,两个机房,主库在A机房,从库在B机房。只要B机房的从库确认了,就算A机房整个挂了,数据也不会丢。
| 特性 | 半同步复制 |
|---|---|
| 数据一致性 | 至少一个从库与主库一致 |
| 写入性能 | 比同步快,比异步慢 |
| 适用场景 | 大多数生产环境,兼顾性能与安全 |
| 容灾能力 | 主库故障,至少一个从库有完整数据 |
4.4 日志传送:最朴素的方案
日志传送,说白了就是把数据库的事务日志(比如MySQL的binlog、PostgreSQL的WAL)定期拷贝到从库,然后从库重放这些日志。这不像同步复制那样实时,而是定时批量传送。
我最早接触日志传送,是在做SQL Server的容灾方案时。那时候网络带宽有限,实时复制太奢侈。我们就用日志传送,每15分钟把日志文件拷贝到灾备机房。这样做的好处是:对网络要求低,带宽占用小,而且日志文件可以压缩传输。
# 伪代码:日志传送流程
1. 主库定期生成事务日志文件
2. 将日志文件压缩(可选)
3. 通过网络拷贝到从库服务器
4. 从库解压日志文件
5. 从库重放日志,恢复数据
6. 清理已重放的日志文件
但日志传送有个明显的缺点:数据延迟大。如果传送间隔是15分钟,那主库挂了,最多会丢15分钟的数据。而且,从库在重放日志时,是不能提供查询服务的(或者只能提供只读服务)。
适用场景:日志传送最适合那些对实时性要求不高,但需要低成本容灾的场景。比如数据仓库的源数据同步、离线分析系统的数据备份。
4.5 四种方案的对比与选择
说了这么多,到底怎么选?我画了一张图,把四种方案的核心逻辑放在一起对比:
最后,我总结一下我的个人经验:
- 同步复制:适合数据一致性要求极高的场景,但要做好网络延迟的监控和告警。
- 异步复制:适合高并发、低延迟要求的场景,但必须接受数据丢失的风险。
- 半同步复制:大多数生产环境的首选,兼顾了性能和安全性。
- 日志传送:低成本容灾方案,适合对实时性要求不高的场景。
避坑指南:我曾经在项目中犯过一个错误——只用了异步复制,没有做任何延迟监控。结果主库挂了,丢了半小时的数据。从那以后,我养成了一个习惯:不管用哪种复制方案,必须监控复制延迟,设置告警阈值。一旦延迟超过阈值,要么自动切换,要么人工介入。千万别等到出事了才想起来看监控。