934 字
约 3 分钟
8
S13-A01 · MySQL → ES 同步:全量、增量与一致性
适用读者:要做"数据库 + 搜索"双存储的人。
前置:S11-A03、S13-B01。
覆盖旧文:429(MySQL 为什么同步到 ES,333 点)。
覆盖扩展:E-S13-010(同步三件套)。
上一篇:S13-J03 · 检索性能优化:从定位到规模化
下一篇:S13-A02 · 语义搜索与混合检索。
1. 一句话结论
ES 不是主存储:数据只从 MySQL 单向流入。同步的可靠性靠三件套——全量初始化、增量订阅(binlog/CDC)、定时对账。
| 阶段 | 手段 | 作用 |
|---|---|---|
| 全量 | 批量导入(关 refresh/副本) | 建立初始索引 |
| 增量 | binlog 订阅(Canal/Debezium) | 持续追平 |
| 对账 | 定时比对条数与抽样内容 | 发现漏同步 |
2. 为什么不让应用双写
| 问题 | 说明 |
|---|---|
| 写失败 | MySQL 成功、ES 失败 → 搜索里查不到 |
| 顺序错乱 | 并发写导致 ES 里是旧值 |
| 侵入 | 业务代码要管两套存储 |
这与 S11-A03/S12-J02 是同一个结论:"单一事实来源 + 变更驱动派生" 才是可靠路线。
3. 三件套的具体做法(E-S13-010)
3.1 全量
① 建索引(正确 mapping,B02)
② 关 refresh(-1)、副本(0)
③ bulk 分批(5–15 MB/批)
④ 恢复 refresh/副本
⑤ 记录"全量完成时间点"(作为增量起点)
3.2 增量
binlog(ROW 格式)→ Canal → MQ → 消费写入 ES
注意:必须能按主键幂等写入(_id = 业务主键),否则重复消费会造成重复文档。
3.3 对账
| 方式 | 频率 |
|---|---|
| 条数比对 | 每小时 |
| 抽样内容比对 | 每天 |
| 全量校验 | 每周/每月 |
4. 一致性边界
| 保证 | 能做到吗 |
|---|---|
| 实时一致 | ❌(秒级延迟) |
| 最终一致 | ✅(增量 + 对账) |
| 顺序一致 | ⚠️(需按主键分区消费) |
判据:"搜索结果的延迟能接受几秒?" 通常 1–5 秒可接受;要"写完立刻搜到" → 得在写入侧同步调用(牺牲可用性)。
5. 迁移与回滚
| 阶段 | 动作 | 回滚 |
|---|---|---|
| 建新索引 | 新 mapping + 别名指向旧索引 | 删新索引 |
| 全量导入 | 双跑(旧索引仍服务) | 别名切回 |
| 别名切换 | 原子切换 | 秒级切回 |
| 下线旧索引 | 观察 1 周 | 保留快照 |
铁律:别名切换是"可回滚"的关键——不要直接把索引名写进代码。
6. 五个误区
| 误区 | 真相 |
|---|---|
| "双写最省事" | 失败与顺序都难控 |
| "ES 能当主库" | 无跨文档事务 |
| "全量导入不用管 refresh" | 不关会慢十倍 |
| "有增量就不需要对账" | 漏消息很常见 |
| "索引名写死也行" | 无法无感切换 |
7. 自检(架构师版)
- 同步三件套分别解决什么?
- 为什么不让应用双写?
- 增量同步的两个前提(幂等、顺序)?
- 一致性边界在哪?
- 别名切换为什么是关键?
8. 下一篇
S13-A02 · 语义搜索与混合检索:BM25 + kNN
同步讲完,下一篇讲"搜索质量":关键词检索与向量检索怎么结合。
本篇属于系列《S13 · 搜索与文档存储》。旧文来源:A-429;扩展点 E-S13-010。
S13-A01 · MySQL → ES 同步:全量、增量与一致性
https://www.clxhxhhr.top/posts/5366/ 评论
0 条
还没有评论,先写一条吧。