索引、IndexMany、IndexAsnyc、IndexManyAsync 与 NEST

Index, IndexMany, IndexAsnyc, IndexManyAsync with NEST

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

    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: 当我通过迭代每个对象来使用 Index 选项时,虽然速度很慢,但它运行顺利。

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

2) IndexAsync:这毫无例外地工作,但它并不比 snyc 迭代和 less documents 已编入索引。

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

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

"System.Net.WebException: The underlying connection was closed: A connection that its continuation was expected, has been closed by the server ..     at System.Net.HttpWebRequest.GetResponse ()"

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

"2016-01-14

10:21:49,567][WARN ][http.netty ] [Microchip] Caught exception while handling client http traffic, closing connection [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][WARN ][http.netty ] [Microchip] Caught exception while handling client http traffic, closing connection [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 content length exceeded 104857600 bytes.

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

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

关于 IndexIndexMany,始终建议使用后者以利用批处理并避免客户端和 Elasticsearch 之间的 request/response 循环过多。也就是说,您不能简单地在单个请求中索引如此大量的文档。异常消息非常清楚地表明您的批处理索引请求已超过 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 个项目为单位为您的整个列表编制索引。