MySQL 同步 ES 的 5 种主流方案(2025~2026 年大厂面试高频题,基于最新实践总结)
MySQL 作为事务存储,ES 作为全文检索/聚合引擎,二者数据同步是几乎所有搜索类、中后台系统的必备能力。
下面是目前业界公认的 5 种方案(来自 2025 年多篇技术文章的共识),从简单到复杂、从侵入到无侵入排序:
方案对比总览(面试必背表格)
| 方案名称 | 实时性 | 数据一致性 | 系统复杂度 | 业务侵入性 | 性能影响 | 适用场景 | 推荐指数 |
|---|---|---|---|---|---|---|---|
| 1. 双写方案 | 高 | 难保证 | 低 | 高 | 高 | 小型项目、数据量小 | ★☆☆☆☆ |
| 2. 定时任务 | 低 | 最终一致 | 低 | 低 | 中 | 报表类、非实时场景 | ★★☆☆☆ |
| 3. MQ 异步 | 中 | 最终一致 | 中 | 中 | 低 | 中大型分布式系统 | ★★★☆☆ |
| 4. 自研 Binlog | 高 | 最终一致 | 高 | 低 | 低 | 需要极致定制的场景 | ★★☆☆☆ |
| 5. Canal | 高 | 最终一致 | 中 | 低 | 低 | 主流推荐(中大型实时搜索) | ★★★★★ |
额外进阶(面试加分):Flink CDC / Debezium + Kafka、Logstash JDBC、go-mysql-elasticsearch、Tapdata 云服务等变体,核心思路均基于 CDC(Change Data Capture)。
1. 双写方案(Double Write)—— 最简单但最容易出问题
原理:业务代码中同时写 MySQL + ES(通常包裹在同一事务里)。
优点:实时性极高,实现最简单。
缺点:ES 挂了或超时会导致 MySQL 回滚失败;分布式事务难保证一致性;业务代码严重侵入。
适用:数据量 < 百万,日变更 < 万级的小项目。
典型代码(Spring Boot):
@Transactional
public void save(User user) {
userMapper.insert(user); // MySQL
elasticsearchClient.index(...); // ES
}
面试官追问:ES 失败了怎么办?(答:本地消息表 + 重试、或降级为异步)
2. 定时任务方案(Scheduled Task / Cron)
原理:每隔几分钟/小时扫描 MySQL 中有变更的记录(靠 update_time 或版本号),批量写 ES。
优点:完全不改业务代码,实现简单。
缺点:实时性差(延迟 = 调度周期);全表扫描压力大;容易漏数据或重复。
适用:搜索不需要实时更新(如后台管理系统、日报数据)。
常用工具:Spring @Scheduled + MyBatis 增量查询。
3. MQ 异步双写(Message Queue)
原理:业务只写 MySQL,成功后发 MQ 消息,消费者监听消息再写 ES。
优点:解耦强、MQ 可持久化+重试、高可用、可水平扩容。
缺点:有一定延迟(秒级);需处理消息幂等、顺序性、死信。
适用:中大型系统,已有 Kafka/RabbitMQ/RocketMQ 基础设施。
流程:
MySQL → 业务代码发 MQ → Consumer → ES(Bulk API 批量写入)
4. 自研 Binlog 方案(自定义 Binary Log 解析)
原理:MySQL 开启 row 格式 Binlog,应用直接连接解析 Binlog 事件(INSERT/UPDATE/DELETE),转换为 ES 操作。
优点:实时性高、无侵入、不影响 MySQL 性能。
缺点:实现极复杂(要处理 Binlog 格式、位点、故障恢复、主从切换);生产极少自研。
适用:极少数需要深度定制的团队。
常用库:mysql-binlog-connector-java。
5. Canal 方案(阿里巴巴开源 CDC 神器)—— 生产主流推荐
原理:Canal 伪装成 MySQL Slave,订阅 Binlog,解析后通过 Canal Client 投递给下游(直接写 ES 或经 Kafka)。
优点:
- 实时性毫秒级
- 对业务零侵入
- 支持过滤、批处理、HA
- 社区成熟,阿里/字节/腾讯大量在用
缺点:需要部署 Canal Server + 开发 Client(或用 canal-adapter)。
经典架构(Canal + Kafka + ES):
MySQL Binlog → Canal Server → Kafka → Flink/Consumer → ES
配置核心(canal.properties):
canal.instance.master.address=127.0.0.1:3306
canal.instance.filter.regex=.*\..* # 监听所有表
面试加分:现在常用 Canal + Kafka + Logstash 或 Flink CDC 一键同步,延迟 < 1s。
一句话总结(面试 30 秒回答版)
“MySQL 同步 ES 主流有 5 种方案:双写(简单但侵入高)、定时任务(非实时)、MQ 异步(解耦好)、自研 Binlog(复杂)、Canal(生产首选,基于 Binlog 的 CDC,无侵入实时同步)。实际项目中 80% 以上中大型系统都选 Canal 或 Canal + Kafka 组合,既保证最终一致性,又做到毫秒级延迟。”
面试官最爱追问:
- 如何保证数据不丢不重?(位点管理 + 幂等 + 死信)
- 全量 + 增量怎么结合?(先 Logstash JDBC 全量,后 Canal 增量)
- Canal 挂了怎么办?(HA 模式 + Kafka 缓冲)
- ES 写入慢怎么办?(Bulk API + 异步 + 限流)
需要我给你:
- 每种方案的完整配置 + GitHub 实战代码
- Canal 最新部署教程(2026 版)
- Flink CDC 一键 SQL 同步示例
- 性能压测对比数据
随时说,这套答案在字节、阿里、腾讯面试里直接拿满分!🚀