Index, IndexMany, IndexAsnyc, IndexManyAsync with NEST

本文关键字:with NEST IndexManyAsync IndexAsnyc IndexMany Index | 更新日期: 2023-09-27 18:30:32

我尝试使用 nest for ElasticSearch 来理解索引选项,我执行了它们中的每一个,这是我的结果:

    var node = new Uri("http://localhost:9200");
    var settings = new ConnectionSettings(node, defaultIndex: "mydatabase"); 
    settings.SetTimeout(1800000);             
    var client = new ElasticClient(settings);  
    var createIndexResult = client.CreateIndex("mydatabase");  
    var mapResult = client.Map<Product>(c => c.MapFromAttributes().SourceField(s=>s.Enabled(true));

1)索引:当我通过迭代每个对象来使用Index选项时,尽管速度很慢,但它工作流畅。

foreach (var item in Items)
{
  elasticClient.Index(item);
}

2)IndexAsync:这没有任何例外,但它并不比snyc迭代快,并且索引的文档更少

 foreach (var item in Items)
    {
      elasticClient.IndexAsync(item);
    }

3) IndexMany:我试过了,elasticClient.IndexMany(items);当然没有foreach,它比foreach -index选项运行得更快,但是不知何故,当我有很多数据(在我的例子中是500.000对象)时,它抛出并异常,说

"System.Net.WebException: 底层连接已关闭: A 预期其继续的连接已被 服务器。。     at System.Net.HttpWebRequest.GetResponse ()"

当我检查日志文件时,我只能看到

"2016-01-14

10:21:49,567][警告][http.netty ] [微芯片] 被抓住 处理客户端 HTTP 流量时出现异常,关闭连接 [ID: 0x68398975,

/0:0:0:0:0:0:0:1:57860 =>/0:0:0:0:0:0:0:1:9200]"

4)IndexManyAsync:elasticClient.IndexManyAsync(Items);尝试indexasnyc会抛出与snyc类似的异常,但我可以在日志文件中看到更多信息。

[

2016-01-14 11:00:16,086][警告][http.netty ] [微芯片]处理客户端 http 流量时捕获异常, 关闭连接 [id: 0x43bca172,/0:0:0:0:0:0:0:1:59314 => /0:0:0:0:0:0:0:1:9200] org.elasticsearch.common.netty.handler.codec.frame.TooLongFrameException: HTTP 内容长度超过 104857600 字节。

我的问题是确切的区别是什么? 在哪些情况下我们可能需要异步? 为什么 IndexMany 和 IndexmanyasNYC 选项都抛出这样的异常?看起来索引选项是最安全的。这样用就可以了吗?

Index, IndexMany, IndexAsnyc, IndexManyAsync with NEST

使用 syncasync 不会对 Elasticsearch 索引性能产生任何影响。如果您不想在索引完成时阻止客户端代码,则需要使用async,仅此而已。

来到 Index vs IndexMany ,始终建议使用后者来利用批处理并避免客户端和 Elasticsearch 之间过多的请求/响应周期。也就是说,您不能简单地在单个请求中索引如此大量的文档。异常消息非常清楚地表明您的批处理索引请求已超出 100MB 的 HTTP 内容长度限制。您需要做的是减少要使用IndexMany编制索引的文档数,以免达到此限制,然后多次调用IndexMany,直到完成对所有 500,000 个文档的索引。

indexManyindexManyAsync的问题在于您在一个请求中索引了太多数据。

这可以通过在列表的子集上执行多个indexMany调用来解决,但现在有一种更简单的方法来处理这个称为bulkAllObservable

var bulkAllObservable = client.BulkAll(items, b => b
    .Index("myindex")
    // how long to wait between retries
    .BackOffTime("30s") 
    // how many retries are attempted if a failure occurs
    .BackOffRetries(2) 
    // refresh the index once the bulk operation completes
    .RefreshOnCompleted()
    // how many concurrent bulk requests to make
    .MaxDegreeOfParallelism(Environment.ProcessorCount)
    // number of items per bulk request
    .Size(1000)
)
// Perform the indexing, waiting up to 15 minutes. 
// Whilst the BulkAll calls are asynchronous this is a blocking operation
.Wait(TimeSpan.FromMinutes(15), next =>
{
    // do something on each response e.g. write number of batches indexed to console
});

这将一次以 1000 个项目的块索引您的整个列表。