📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

适用版本: 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 Error400 Bad Request 状态码。
  • CCR 复制过程失败,目标索引可能无法同步源集群的更新。
  • 在 Elasticsearch 服务端日志中会记录 ElasticsearchStatusExceptionIllegalStateException
  • 如果是通过 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)来自源集群的操作。为了保证数据一致性和操作顺序,每个操作都必须携带:

  1. 序列号(sequence number):标识操作的顺序
  2. 主版本号(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 来监控和保护跨集群复制流量,从而构建更可靠的跨集群数据复制架构。

相关错误 #

参考文档 #

附:日志上下文 #

下面保留当前页面中的源码或日志片段,便于继续结合异常调用栈定位问题:

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);
    }
}