适用版本: 6.8-7.15
1. 错误异常的基本描述 #
a following engine does not accept operations without an assigned sequence number 是 Elasticsearch 在跨集群复制(CCR, Cross-Cluster Replication)或类似的数据复制场景中抛出的异常。跟随引擎(Following Engine)是 CCR 中目标集群用来应用来自源集群的操作的引擎组件。为了保证数据一致性,每个操作都必须携带一个序列号(sequence number),如果某个操作没有分配序列号,跟随引擎就会拒绝该操作并抛出此错误。
常见现象 #
- Elasticsearch 返回 HTTP
500 Internal Server Error或400 Bad Request状态码。 - CCR 复制过程失败,目标索引可能无法同步源集群的更新。
- 在 Elasticsearch 服务端日志中会记录
ElasticsearchStatusException或IllegalStateException。 - 如果是通过 CCR API 管理跨集群复制,会看到复制任务失败或暂停。
- 目标集群中与复制相关的索引可能无法正常接收新数据。
典型报错与异常栈 #
该异常的典型日志形态如下:
ElasticsearchStatusException: a following engine does not accept operations without an assigned sequence number
at org.elasticsearch.index.engine.FollowingEngine.preFlight(FollowingEngine.java:...)
at org.elasticsearch.index.engine.FollowingEngine.index(FollowingEngine.java:...)
at org.elasticsearch.index.shard.IndexShard.applyIndexOperation(IndexShard.java:...)
at org.elasticsearch.index.shard.IndexShard.performBatchReplicationOperation(IndexShard.java:...)
或者出现在 CCR 复制上下文中:
ElasticsearchStatusException: a following engine does not accept operations without an assigned sequence number
RestStatus: FORBIDDEN
at org.elasticsearch.index.engine.FollowingEngine.preFlight(FollowingEngine.java:...)
Caused by: IllegalStateException: operation sequence number is unassigned
2. 为什么会发生这个错误 #
跟随引擎(Following Engine)是 Elasticsearch CCR 功能的核心组件,它负责在目标集群上重放(replay)来自源集群的操作。为了保证数据一致性和操作顺序,每个操作都必须携带:
- 序列号(sequence number):标识操作的顺序
- 主版本号(primary term):标识操作来自哪个主分片
如果操作没有分配序列号(即序列号为 UNASSIGNED_SEQ_NO),跟随引擎就无法确定操作的顺序,从而拒绝执行。
常见原因包括:
- CCR 版本不兼容:源集群和目标集群的 Elasticsearch 版本不兼容,导致操作元数据格式不一致。
- 内部操作错误:某些内部操作(如恢复、迁移)可能错误地生成了未分配序列号的操作。
- 引擎状态异常:跟随引擎处于异常状态,无法正确处理序列号。
- 网络问题导致数据损坏:在传输过程中,操作元数据可能丢失或损坏。
- CCR 配置错误:自动跟随(auto-follow)模式配置不正确,导致错误的操作被发送到跟随引擎。
- 并发操作冲突:在复制过程中,同时发生了其他操作,导致序列号分配异常。
3. 如何排查和解决这个异常和解决这个异常 #
排查步骤 #
建议按以下顺序进行排查:
第一步:查看完整的错误日志 #
# 查看 Elasticsearch 日志中的详细错误
tail -n 500 /var/log/elasticsearch/elasticsearch.log | grep -A 30 "following engine does not accept operations"
第二步:检查 CCR 复制状态 #
# 查看所有 CCR 复制任务的状态
curl -X GET "localhost:9200/_ccr/_stats?pretty"
# 查看特定复制任务的状态
curl -X GET "localhost:9200/_ccr/_stats/<leader_cluster>/<follower_index>?pretty"
# 查看自动跟随模式的状态
curl -X GET "localhost:9200/_ccr/_auto_follow?pretty"
第三步:检查集群和索引状态 #
# 查看目标集群的索引状态
curl -X GET "localhost:9200/_cat/indices?v&index=<follower_index>"
# 查看分片状态
curl -X GET "localhost:9200/_cat/shards/<follower_index>?v"
# 查看索引详细信息
curl -X GET "localhost:9200/<follower_index>/_settings?pretty"
curl -X GET "localhost:9200/<follower_index>/_stats?pretty"
第四步:检查版本兼容性 #
# 查看源集群和目标集群的版本
curl -X GET "localhost:9200"
curl -X GET "<leader_cluster_url>:9200"
# 确保版本兼容(CCR 要求版本兼容)
排查时需要注意的问题 #
- 区分源集群和目标集群:错误发生在目标集群(跟随集群),但根因可能在源集群。
- 检查 CCR 配置:自动跟随模式、复制规则、权限配置等都可能导致问题。
- 查看操作上下文:错误日志中可能会包含操作类型、索引名、分片信息等,有助于定位问题。
- 注意版本兼容性:CCR 对版本有严格要求,跨大版本复制可能不兼容。
4. 如何解决这个错误 #
常用修复思路 #
方案一:暂停并恢复 CCR 复制 #
# 暂停出问题的复制任务
curl -X POST "localhost:9200/_ccr/pause/<leader_cluster>/<follower_index>"
# 等待几秒后恢复复制
curl -X POST "localhost:9200/_ccr/resume/<leader_cluster>/<follower_index>"
# 检查恢复后的状态
curl -X GET "localhost:9200/_ccr/_stats/<leader_cluster>/<follower_index>?pretty"
方案二:重建跟随索引 #
# 删除现有的跟随索引(注意:这会丢失未同步的数据)
curl -X DELETE "localhost:9200/<follower_index>"
# 重新创建跟随索引
curl -X PUT "localhost:9200/<follower_index>" -H 'Content-Type: application/json' -d '
{
"settings": {
"index": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
}'
# 重新建立复制关系
curl -X PUT "localhost:9200/_ccr/_follow?wait_for_active_shards=1" -H 'Content-Type: application/json' -d '
{
"remote_cluster": "<leader_cluster>",
"leader_index": "<leader_index>"
}'
方案三:检查并修正自动跟随配置 #
# 查看现有的自动跟随模式
curl -X GET "localhost:9200/_ccr/_auto_follow?pretty"
# 删除有问题的自动跟随模式
curl -X DELETE "localhost:9200/_ccr/_auto_follow/<pattern_name>"
# 重新创建正确的自动跟随模式
curl -X PUT "localhost:9200/_ccr/_auto_follow/<pattern_name>" -H 'Content-Type: application/json' -d '
{
"remote_cluster": "<leader_cluster>",
"leader_index_patterns": ["logs-*"],
"follow_index_pattern": "{{leader_index}}-copy"
}'
方案四:升级或统一版本 #
# 如果版本不兼容,考虑升级
# 检查当前版本
curl -X GET "localhost:9200" | jq .version.number
# 按照 Elasticsearch 官方升级指南进行滚动升级
后续注意事项与推荐建议 #
- 建立 CCR 监控:监控复制延迟、失败次数、同步状态等关键指标。
- 版本兼容性管理:在升级集群前,先检查 CCR 的版本兼容性要求。
- 合理配置自动跟随:避免过于宽泛的索引模式,导致不必要的复制任务。
- 定期巡检:定期检查 CCR 状态,及时发现和解决问题。
- 备份重要数据:在进行 CCR 相关操作前,确保重要数据已备份。
借助 INFINI 产品提升排障效率 #
INFINI Console 提供跨集群复制的可视化管理界面,可以直观地查看 CCR 复制状态、延迟和错误信息。通过 Console 的复制监控功能,可以快速定位出问题的复制任务,并查看详细的错误日志和统计信息。Console 还提供索引级别的复制状态查看,帮助快速判断是单个索引问题还是全局问题。
INFINI Gateway 可以作为 Elasticsearch 集群的流量治理网关,在 CCR 场景中提供请求观测和流量控制能力。Gateway 可以监控跨集群的复制流量,检测异常请求和错误模式,并自动进行限流和熔断保护。通过 Gateway 的流量分析功能,可以深入了解复制流量的模式和潜在问题。
对于依赖 CCR 实现跨数据中心高可用的团队,建议结合 INFINI Console 的复制监控功能和 INFINI Gateway 的流量治理能力,建立从复制配置、监控、告警到故障恢复的完整体系,确保数据复制的可靠性和一致性。
5. 小结 #
a following engine does not accept operations without an assigned sequence number 是一个典型的 CCR 数据一致性错误,根源在于跟随引擎收到了未分配序列号的操作。虽然报错信息比较底层,但排查思路需要围绕 CCR 的配置、版本兼容性和运行状态来展开。
在实际工作中,为避免此类问题,建议建立完善的 CCR 监控体系,定期检查复制状态,并在版本升级前仔细核对兼容性要求。更重要的是,考虑使用 INFINI Console 来实现可视化的复制管理,使用 INFINI Gateway 来监控和保护跨集群复制流量,从而构建更可靠的跨集群数据复制架构。
相关错误 #
- concurrent-modification-of-the-index-n-file-expected-current-generation:index-N文件并发修改
- failed-to-update-snapshot-in-repository:更新仓库快照失败
- master-changed-during-snapshot-initialization:快照初始化时主节点变更
- recovery-was-canceled-reason-reason:恢复被取消
- index-is-unrecoverable:索引无法恢复
参考文档 #
附:日志上下文 #
下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:
private void preFlight(final Operation operation) {
assert FollowingEngineAssertions.preFlight(operation);
if (operation.seqNo() == SequenceNumbers.UNASSIGNED_SEQ_NO) {
throw new ElasticsearchStatusException("a following engine does not accept operations without an assigned sequence number",
RestStatus.FORBIDDEN);
}
}





