与NEST的Index,IndexMany,IndexAsnyc,IndexManyAsync

时间:2016-01-14 10:36:40

标签: c# elasticsearch nest

我尝试使用嵌套来了解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   它的延续预期的连接已被关闭   服务器..   在System.Net.HttpWebRequest.GetResponse()“

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

  

“2016年1月14日

     
    

10:21:49,567] [警告] [http.netty] [Microchip]抓到了     处理客户端http流量时出现异常,关闭连接[id:     0x68398975,/ 0:0:0:0:0:0:0:1:57860 =&gt; / 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]   [Microchip]处理客户端http流量时发生异常,   关闭连接[id:0x43bca172,/ 0:0:0:0:0:0:0:1:59314 =&gt;   / 0:0:0:0:0:0:0:1:9200]   org.elasticsearch.common.netty.handler.codec.frame.TooLongFrameException:   HTTP内容长度超过104857600字节。

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

2 个答案:

答案 0 :(得分:5)

使用syncasync不会对Elasticsearch索引性能产生任何影响。如果您不希望在完成索引时阻止客户端代码,则可以使用async,这就是全部。

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

答案 1 :(得分:0)

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个项目。