问题现象
Kibana 启动后控制台持续输出:
[version_conflict_engine_exception]:
[task:endpoint:user-artifact-packager:1.0.0]
[task:Alerting-alerting_telemetry]
[task:apm-telemetry-task]
version conflict, document already exists (current version [xx])
三个 “task” 前缀的索引反复报版本冲突。
什么是版本冲突(写给不熟悉 ES 的人)
ElasticSearch 是分布式系统,多个节点可能同时修改同一条数据。ES 使用乐观并发控制来协调:
每次对文档的任何修改,ES 都会给它一个递增的版本号。
Document A(version=1)
├── 节点A 尝试修改 → "基于 version=1 修改" → 成功 → version=2
└── 节点B 同时尝试修改 → "基于 version=1 修改" → 冲突!version 已经是 2 了
节点B 收到 version_conflict_engine_exception。
这和 Git 的冲突概念相似——你基于旧版本做的修改推不上去,因为别人先改了。
根因分析
Kibana 在升级或重新部署时,会尝试创建/更新 ES 中的内部索引(存仪表盘配置、告警规则、APM 数据等)。但旧的 Kibana 实例或残留的数据可能有不同的版本号。
具体到这几个 task: 前缀的索引,它们是 Kibana 的后台任务调度器内部使用的:
task:endpoint:user-artifact-packager— Endpoint 安全组件task:Alerting-alerting_telemetry— 告警遥测task:apm-telemetry-task— APM 监控遥测
升级路径中这些 task 索引的 mapping 或文档格式发生变化,旧的文档版本号与新写入冲突。
两种处置思路
可接受数据丢失:删除索引
# 查看冲突的索引
curl -X GET "localhost:9200/_cat/indices/task*?v"
# 删除
curl -X DELETE "localhost:9200/.kibana_task_manager_*"
Kibana 会在下次启动时重建这些索引。控制台配置、仪表盘存在其他索引中,不受影响。但告警历史、APM 配置可能丢失。
不能丢数据:升级流程
参考 ES 官方文档中的版本控制章节:
核心思路是用 version_type=external 参数强制执行:
curl -X POST "localhost:9200/.kibana_task_manager/_update/xxx?version=999&version_type=external" \
-H 'Content-Type: application/json' -d '{ ... }'
version_type=external 告诉 ES:只要我的版本号大于当前值就覆盖。这绕过了乐观锁。
从根源避免
Kibana 和 ES 的版本匹配很重要。Kibana 7.x 配 ES 7.x,版本号要一致(都是 7.10 或都是 7.17),跨大版本一定出问题。
问题排查方法论
从这个 bug 学到的最有价值的东西不是修复本身,而是搜索路径:
1. 官方文档(elastic.co/guide) ← 最快最准
2. GitHub Issue(elastic/elasticsearch) ← 有人遇到过同样的坑
3. Stack Overflow / 中文论坛 ← 最后的手段
官方文档对版本冲突有完整章节——英文阅读的障碍远小于用错误解决方案浪费时间。
☕ 如果这篇文章对你有帮助
欢迎请我喝杯咖啡支持一下
评论