Elasticsearch 数据同步与运维¶
要点卡¶
30 秒回答
Elasticsearch 应作为可重建的搜索投影,数据库或事件日志才是事实源。同步通常是 snapshot + CDC + MQ + bulk writer:先确定快照高水位,再无缝接增量;每条文档携带源版本/位置, 防止旧事件覆盖新状态。Bulk HTTP 200 仍可能有 item 失败,必须逐项分类重试,全部安全落地后 才提交消费位点;删除/tombstone、对账、重建和 alias 切换都要进入状态机。
3 分钟展开
_id=业务主键只解决重复目标,不解决乱序;使用可比较的源版本、external versioning 或条件脚本阻止旧更新覆盖新文档。- batch 按文档数、字节、内存与目标延迟联合调节并做背压;429/局部失败只重试失败 item,毒数据进入可审计停车区。
- 搜索可见性受 refresh 影响,写入成功不等于立即可搜;业务读己之写可回源或使用明确策略,不能承诺固定秒数。
- 新 mapping 用新索引回填、shadow 校验,再用一次 aliases API 操作切读写;原子切别名不代表 schema/query 一定兼容。
| 记忆槽 | 内容 |
|---|---|
| 三个不变量 | ES 不是事实源;同 _id 不防乱序;Bulk 成功看每个 item |
| 手画图 | DB snapshot@W + CDC>W → MQ → version-aware bulk → ES alias |
| 项目落点 | 风控/Agent 检索讲可重建 projection、lag、DLQ、范围 checksum 和双索引升级 |
| 一个取舍 | 更频繁 refresh 提高可见性但增加资源成本;更大 bulk 提升吞吐却增加内存和失败重放范围 |
错误表达
- ❌ “同
_idupsert 就能保证 CDC 幂等有序;Bulk 返回 200 就可以 commit offset。” - ✅ “重复与乱序是两件事;必须检查 item 结果并保存源版本/删除语义。”
自测追问:全量扫描期间发生 UPDATE/DELETE,如何保证切到增量后既不漏也不被旧快照覆盖?
10 分钟版(同步架构)¶
flowchart LR
MySQL[(MySQL)] -->|binlog| Canal[Canal / Debezium]
Canal --> MQ[Kafka/RocketMQ]
MQ --> Worker[Go ES Writer]
Worker --> ES[(Elasticsearch)]
| 方式 | 优点 | 缺点 |
|---|---|---|
| 双写 | 简单 | 不一致、难回滚 |
| CDC + MQ | 解耦、可重放 | 链路长 |
| Logstash JDBC | 配置快 | 增量能力弱 |
Go Consumer 要点
- Bulk 按 docs、bytes、内存与等待时间自适应;吞吐/可见性策略按 workload 压测,不背固定条数。
- 文档
_id使用稳定业务主键,并携带源版本/位点;以 external versioning 或条件更新拒绝旧事件。 - 逐项检查 Bulk
items[].status/error;只重试可重试 item,确认批内状态安全后再提交 offset。 - DELETE/tombstone 与 update 使用相同的版本顺序规则;poison item 进入带原始事件和错误原因的 DLQ。
与分库分表(见 S-DB-04)
- 跨片列表:ES 聚合检索
- 或 ES 存宽表冗余字段,避免 join
生产场景¶
- 商品库 MySQL,搜索走 ES;大促前 全量 reindex 预热
- 用一次 aliases API 操作切换读/写 alias;上线前验证 mapping、查询、排序、写兼容和回滚条件, 才能把它作为低停机迁移方案
排查与工具¶
_cat/shards未分配分片_cluster/allocation/explain- 同步延迟:MQ lag + ES 写入 TPS
架构取舍¶
| 方案 | 适用 |
|---|---|
| 可重建 ES | 接受丢索引从 MySQL 全量恢复 |
| 跨集群复制 CCR | 异地灾备 |
| 冷热架构 ILM | 日志历史降冷节点 |
深挖问答¶
- 同步丢消息? → MQ 持久化/可重放 + 至少一次 + version-aware projection;offset、DLQ 和源数据对账共同闭环。
- 删除怎么同步? → binlog DELETE 事件删 ES doc。
- mapping 变更? → 新 index + reindex + alias 切换。
- 集群红了? → 未分配副本、磁盘满、版本不兼容;先扩盘/删旧索引。
反模式与事故¶
- 双写无对账 → 搜索有货 DB 无货
- bulk 无背压或只看 HTTP 状态 → ES 过载 429,或 item 局部失败被当成整批成功
- 单 giant shard → 无法恢复、迁移慢