You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch与.NET重新索引时滚动上下文超限及Scroll_id获取咨询

解决Elasticsearch重索引时滚动上下文超限问题

你遇到的Trying to create too many scroll contexts错误,本质是一次性启动了太多异步重索引任务,每个任务都会在ES内部打开scroll上下文;而你调用的ClearScrollAsync(c => c.ScrollId(default))只会清理已过期的scroll,对正在运行的重索引任务的scroll完全无效。另外,你没法直接拿到每个重索引任务对应的scroll id——因为Reindex后台任务的scroll是ES内部维护的,不会暴露给客户端。

给你几个可行的解决办法:

1. 控制重索引任务的并发数

用SemaphoreSlim限制同时运行的任务数量,避免一次性打开太多scroll上下文,数量建议略小于ES的search.max_open_scroll_context默认值(比如设为400),留足余量:

// 初始化信号量,限制并发数为400
var semaphore = new SemaphoreSlim(400);
foreach( var destIndice in indiceDictionary.Keys )
{
    await semaphore.WaitAsync();
    try
    {
        var reIndexResponse = await this._elasticSearchClient.Value.ReindexOnServerAsync(r => r
            .Source(src => src.Index(indiceDictionary[destIndice].ToArray()))
            .Destination(dest => dest.Index(destIndice))
            .WaitForCompletion(false)
        );

        var taskId = reIndexResponse.Task;
        this.logger.LogInformation("TriggerReorganization Reindex for dest {destinationIndice} with {numberOfSrcIndice} source indices has a Task with id : {taskId}"
        , destIndice, indiceDictionary[destIndice].Count, taskId);
    }
    finally
    {
        semaphore.Release();
    }
}

2. 等待单个任务完成后再启动下一个

如果业务对执行效率要求不高,可以在启动重索引任务后,调用WaitForTaskAsync等待任务完成,这样每个任务的scroll上下文会在任务结束后被ES自动清理,不会积累:

foreach( var destIndice in indiceDictionary.Keys )
{
    var reIndexResponse = await this._elasticSearchClient.Value.ReindexOnServerAsync(r => r
        .Source(src => src.Index(indiceDictionary[destIndice].ToArray()))
        .Destination(dest => dest.Index(destIndice))
        .WaitForCompletion(false)
    );

    var taskId = reIndexResponse.Task;
    this.logger.LogInformation("TriggerReorganization Reindex for dest {destinationIndice} with {numberOfSrcIndice} source indices has a Task with id : {taskId}"
    , destIndice, indiceDictionary[destIndice].Count, taskId);

    // 等待任务完成,确保scroll上下文被自动清理
    await this._elasticSearchClient.Value.WaitForTaskAsync(taskId);
}

3. 临时调整ES参数(不推荐长期使用)

如果上述方法暂时无法实施,可以临时调高search.max_open_scroll_context参数,缓解当前问题,但这只是权宜之计,长期来看还是要控制任务并发,避免ES资源过载:

PUT /_cluster/settings
{
  "persistent": {
    "search.max_open_scroll_context": 1000
  }
}

注意:不要尝试手动清理正在运行的重索引任务的scroll,这会直接导致任务失败。ES会在重索引任务完成(无论成功或失败)后自动清理对应的scroll上下文,所以核心思路是控制同时运行的任务数量,避免超过限制。

内容的提问来源于stack exchange,提问作者Maxime Dousselaere

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 22:58:13