收到无法从_bulk重试的失败后,ElasticSearch Nest BulkAll停止

时间:2019-01-24 14:22:11

标签: c# elasticsearch nest

使用BulkAll()批量插入我收到此奇怪的错误

BulkAll halted after receiving failures that can not be retried from _bulk

但是,当我检查异常时,我仍然得到成功的答复:

Successful low level call on POST: /cf-lblogs-2019.01.23/cloudflareloadbalancinglogelasticentity/_bulk?

我在这里做错了什么?下面是代码片段:

var waitHandle = new CountdownEvent(1);

var bulk = _client.BulkAll(group.ToList(), a => a
                .Index(_index.Replace("*", string.Empty) + group.Key)
                .BackOffRetries(2)
                .BackOffTime("30s")
                .RefreshOnCompleted(true)
                .MaxDegreeOfParallelism(4)
                .Size(group.Count()));

bulk.Subscribe(new BulkAllObserver(
                onNext: response => _logger.LogInformation($"Indexed {response.Page * group.Count()} with {response.Retries} retries"),
                onError: HandleInsertError,
                onCompleted: () => waitHandle.Signal()
            ));

waitHandle.Wait();


private void HandleInsertError(Exception e)
    {
        var exceptionString = e.ToString(); 
        _logger.LogError(exceptionString);
    }

巢6.4.2。

弹性6.5.4。

3 个答案:

答案 0 :(得分:2)

就我而言,我已经解决了以下问题:

        List<string> errors = new List<string>();
        int seenPages = 0;
        int requests = 0;
        CancellationTokenSource tokenSource = new CancellationTokenSource();
        ConcurrentBag<BulkResponse> bulkResponses = new ConcurrentBag<BulkResponse>();
        ConcurrentBag<BulkAllResponse> bulkAllResponses = new ConcurrentBag<BulkAllResponse>();
        ConcurrentBag<items> deadLetterQueue = new ConcurrentBag<items>();
        BulkAllObservable<items> observableBulk = elasticClient.BulkAll(lst, f => f
                .MaxDegreeOfParallelism(Environment.ProcessorCount)
                .BulkResponseCallback(r =>
                {
                    bulkResponses.Add(r);
                    Interlocked.Increment(ref requests);
                })
                .ContinueAfterDroppedDocuments()
                .DroppedDocumentCallback((r, o) =>
                {
                    errors.Add(r.Error.Reason);
                    deadLetterQueue.Add(o);
                })
                .BackOffTime(TimeSpan.FromSeconds(5))
                .BackOffRetries(2)
                .Size(1000)
                .RefreshOnCompleted()
                .Index(indeksName)
                .BufferToBulk((r, buffer) => r.IndexMany(buffer))
            , tokenSource.Token);

        try
        {
            observableBulk.Wait(TimeSpan.FromMinutes(15), b =>
            {
                bulkAllResponses.Add(b);
                Interlocked.Increment(ref seenPages);
            });
        }
        catch (Exception e)
        {
            Console.WriteLine("Exxx => " + e.Message);
        }
        foreach (var err in errors)
        {
            Console.WriteLine("Error : " + err);
        }

我希望它可以对遇到此问题的其他人有所帮助。

答案 1 :(得分:1)

这意味着BulkAll可观察对象无法为由于无法重试的原因而失败的一个或多个文档建立索引。

默认情况下,无法索引的文档的重试谓词是针对某项返回HTTP响应状态代码429,即尝试同时索引多于群集无法处理的文档。

看看BulkAll()的设置有两件事:

  1. var bulk = _client.BulkAll(group.ToList(), a => a

    group.ToList()将立即评估所有文档,并将其缓存在内存中的List<T>中。为了提高效率,您通常想在批量索引时懒惰枚举大型集合。如果group是可以传递给IEnumerable<T>的{​​{1}},则只需传递它即可。

  2. BulkAll

    这将尝试在一个批量请求中发送所有文档。使用.Size(group.Count()));的想法是它将同时发送多个批量请求,并一直这样做,直到所有文档都被索引为止。

    对于每个请求,应将大小设置为合理的大小;您可以通过计算每个文档的平均字节数,然后从小于5MB的位置开始,以字节为单位计算合理的大小,或者您可能希望每个请求以1000个文档开始,并评估索引的速度是否足以满足您的需求或者您开始​​收到429条回复。当后者开始发生时,这很好地表明您已接近要建立索引的文档的群集的索引限制的阈值。

答案 2 :(得分:0)

我毫不怀疑Russ Cams的回答是正确的,但是在另一种情况下,可能会出现此错误。

如果您已使用类似方法在Elastic search中实现了API安全性

POST /_security/api_key
{
"name":"my-api-key",
"role_descriptors": {
   "admin": {
       "cluster":["all"],
       "index": [
          {
            "names":["my-index", "my-other-index"],
            "privileges": ["all"]
          }
        ]
     }
   }
}

并且您没有为这些索引使用正确的ApiKey,或者正在尝试使用生成的ApiKey来创建并将bulkAll插入另一个未为其定义ApiKey的索引。

在删除/创建呼叫期间不会收到错误消息。

await client.Indices.DeleteAsync(IndexName);
await client.Indices.CreateAsync(IndexName, MutateCreateIndexDescriptor);

您将得到在问题中指定的错误。

BulkAll halted after receiving failures that can not be retried from _bulk

使用堆栈跟踪将您错误地指向:

bulkAll.Wait(... , ...);

如果已定义。

这可能是NEST中的错误。经历过版本。 7.8.0希望这对任何偶然发现的人有所帮助。