索引、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 选项是最安全的选项。这样使用它可以吗?
使用sync
或async
不会对Elasticsearch 索引性能产生任何影响。如果您不想在完成索引时阻止您的客户端代码,您会想要使用 async
,仅此而已。
关于 Index
与 IndexMany
,始终建议使用后者以利用批处理并避免客户端和 Elasticsearch 之间的 request/response 循环过多。也就是说,您不能简单地在单个请求中索引如此大量的文档。异常消息非常清楚地表明您的批处理索引请求已超过 100MB 的 HTTP 内容长度限制。您需要做的是使用 IndexMany
减少要索引的文档数量,这样您就不会达到此限制,然后多次调用 IndexMany
直到完成对所有 500,000 个文档的索引。
indexMany
和 indexManyAsync
的问题是您在一个请求中索引了太多数据。
这可以通过对列表的子集进行多次 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 个项目为单位为您的整个列表编制索引。
我尝试使用 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 选项是最安全的选项。这样使用它可以吗?
使用sync
或async
不会对Elasticsearch 索引性能产生任何影响。如果您不想在完成索引时阻止您的客户端代码,您会想要使用 async
,仅此而已。
关于 Index
与 IndexMany
,始终建议使用后者以利用批处理并避免客户端和 Elasticsearch 之间的 request/response 循环过多。也就是说,您不能简单地在单个请求中索引如此大量的文档。异常消息非常清楚地表明您的批处理索引请求已超过 100MB 的 HTTP 内容长度限制。您需要做的是使用 IndexMany
减少要索引的文档数量,这样您就不会达到此限制,然后多次调用 IndexMany
直到完成对所有 500,000 个文档的索引。
indexMany
和 indexManyAsync
的问题是您在一个请求中索引了太多数据。
这可以通过对列表的子集进行多次 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 个项目为单位为您的整个列表编制索引。