分布式专题——57 如何保证MySQL数据库到ES的数据一致性
1 业务场景介绍
1.1 需求分析
- 功能需求:用户可通过目的地、酒店名称、房型、价格范围等属性,对旅游优惠酒店进行全模糊搜索;
- 非功能需求(性能要求):
- QPS(每秒查询率):春季促销期间预计达到1000左右,需支撑高并发搜索;
- 响应时间:搜索响应需控制在500毫秒以内,保障用户体验;
- 数据一致性:确保搜索结果反映最新的酒店信息及可用性。
1.2 技术实现方案
-
假设底层用MySQL存储酒店数据,技术方案如下:
-
数据同步:利用MySQL的
binlog(二进制日志)或第三方工具(如Debezium、Canal),实时监听酒店数据的变更,并将变更同步到Elasticsearch(ES)中; -
索引构建:在Elasticsearch中,为目的地、酒店名称、房型、价格范围等字段建立合适的索引,以支持快速、高效的模糊搜索;
-
-
思考:如何保证MySQL数据库和ES的数据一致性?
2 业界常用数据一致性方案分析
- 在确保MySQL数据库和Elasticsearch(ES)数据一致性方面,业界有以下4种常见方案:
-
同步双写方案:代码中对数据库和ES进行双写操作,保证先更新数据库后更新ES,依赖事务回滚保证一致性
-
MQ异步双写方案:通过消息队列(如RocketMQ、Kafka)做中间件,应用更新数据库后发消息到MQ,由消费者异步更新ES
-
扫表定时同步方案:通过定时任务扫描数据库,将变更数据同步到ES
-
监听binlog同步方案:直接监听MySQL的binlog实现数据库和ES的实时同步
-
2.1 同步双写方案
-
实现思路:在数据写入MySQL的同时,直接将相同数据写入ES;

-
优点:
- 数据一致性:能保证MySQL和ES之间强一致性,数据库变更会同步反映到ES
- 实时性:数据实时同步,MySQL的操作会立即在ES中体现
- 易于实现:技术角度实现相对简单,只需在应用代码中添加双写逻辑
-
缺点:
- 代码复杂性:需在应用程序中添加额外代码处理双写,增加代码复杂度和维护难度
- 性能开销:每次数据库操作需执行两次(写MySQL+写ES),高并发场景下性能开销显著
- 数据不一致风险:若系统故障或网络延迟,可能出现“MySQL写入成功但ES写入失败”的不一致情况
-
应用场景
-
系统特点:旧系统年限长、单体架构且技术较落后,引入其他中间件治理成本很高
-
业务场景:用户量少、偏后台管理类的系统,对数据同步实时性要求很高(接近实时)
-
2.2 MQ异步双写方案
-
实现思路:使用消息队列(如RocketMQ、Kafka)作为中间件,应用程序更新数据库后发送消息到MQ,由MQ的消费者异步更新ES;

-
方案核心
-
生产者双写:生产者系统发送消息到MQ的同时,写入MySQL
-
消费者异步处理:消费者从MQ中读取消息,异步将处理结果写入ES
-
-
优点:
- 系统解耦:降低MySQL和ES之间的依赖性,提升系统可维护性和扩展性
- 高可用性:MQ提供消息持久化存储,即使系统故障,消息也不会丢失
- 容错性:某系统出现故障时,数据仍可通过其他系统恢复
-
缺点:
- 延迟:异步处理可能导致数据同步延迟,高负载或资源不足时更明显
- 复杂度:引入MQ和双写机制增加系统复杂度,开发和维护成本上升
- 补偿机制:需设计复杂补偿机制处理同步失败情况,进一步增加复杂度
-
应用场景:
-
系统特点:
- C端系统:面向最终用户(如移动应用、Web应用、桌面应用)
- 引入MQ中间件:系统架构已包含消息队列中间件,为异步处理提供基础
- 接口TPS性能要求:系统对接口吞吐量(TPS)有要求,需保证高并发场景下的性能
-
业务场景:
- 用户体量大,高并发场景:大量用户同时操作,系统面临高并发压力
- 业务变更少:业务逻辑变更相对少,数据同步需求较稳定
- 允许一定延迟:在保证用户体验的前提下,数据同步延迟在秒级范围内可接受
-
2.3 扫表定期同步方案
-
实现思路:通过定时任务定期扫描MySQL数据库,将变更的数据同步到ElasticSearch;

-
优点:
- 实现简单:借助定时任务调度框架,无需复杂开发工作
- 适合批量数据:批量处理可减少网络传输次数和ES写入压力,适用于大量数据迁移
- 对业务影响小:定时任务可在系统负载较低的时段运行,降低对在线业务的干扰
-
缺点:
- 实时性差:因定期执行,数据同步存在延迟,不适合实时性要求高的场景
- 性能影响:同步过程中(尤其是数据量大时)可能对MySQL和ES的性能产生短期影响
- 数据一致性风险:若同步周期内数据发生变化,可能导致ES与MySQL数据不一致
-
应用场景
-
系统特点:旧系统年限长、技术框架老旧,引入其他中间件治理成本很高
-
业务场景:用户体量小、偏报表统计类业务、对数据实时性要求不高的场景
-
2.4 监听binlog同步方案
-
实现思路:通过直接监听MySQL的binlog(二进制日志),实现数据库和ES之间的实时同步;
-
基础流程:酒店管理服务写入MySQL后,由
canal服务监听binlog变更,直接同步到ES
-
高并发优化:在高并发场景下,可引入Kafka作为缓冲层,暂时存储binlog事件,平滑数据流,避免ES瞬时高负载

-
-
优点:
- 业务无侵入:无需修改业务代码,数据同步准实时
- 业务解耦:不需要关注原系统的业务逻辑,系统间依赖性低
-
缺点:
- 系统复杂度高:构建Binlog监听系统(如部署canal、Kafka等组件)较为复杂
- 潜在延迟风险:若采用MQ(如Kafka)消费解析Binlog信息,会存在类似MQ异步方案的延迟风险
-
应用场景
-
系统特点:C端系统,可开放MySQL binlog日志监听,引入第三方canal中间件成本不高
-
业务场景:互联网公司、用户体量大、大型多中心组织、高并发场景,业务上允许一定延迟(秒级)的场景
-
