动作部分的elasticsearch批量索引和冗余数据

elasticsearch bulk indexing and redundant data in action part

当使用 elasticsearch 的批量 API 索引数据时,这里是来自 site documentation

的示例 json
POST _bulk
{ "index" : { "_index" : "test", "_type" : "_doc", "_id" : "1" } }
{ "field1" : "value1" }
{ "index" : { "_index" : "test", "_type" : "_doc", "_id" : "2" } }
{ "field1" : "value2" }
{ "index" : { "_index" : "test", "_type" : "_doc", "_id" : "3" } }
{ "field1" : "value3" }

虽然 "preparing" 批量 API 使用的数据,但在第一行我必须指定操作,在下一行我将提供数据。每行上的一些冗余部分可能看起来很明显并且非常无害,但是当我索引数万亿行时,它不会增加延迟吗?是否有更好的方法通过在 header 指定索引名称和类型一次来推送所有行?特别是当我可以使用自动生成的 id 时,我可以避免生成数 TB 的数据,只是为了同一目的一次又一次地添加到每一行之前。

我相信我在这里遗漏了一些明显的东西,否则我相信 elastic 的那些人足够聪明,已经弄明白了,如果他们这样做了,应该有一些原因。但是什么?

这里有快捷方式:

POST /test/_doc/_bulk
{ "index": {} }
{ "field1" : "value1" }
{ "index": {} }
{ "field1" : "value2" }
{ "index": {} }
{ "field1" : "value3" }

很遗憾,您仍然需要重复 { "index": {} } 行,但索引名称和文档类型已在路径中指定。

请参阅 Cheaper in Bulk 文章中的更多选项。

好吧,就准备数据而言,没有更好的方法了。您唯一能做的就是以编程方式准备数据。

您可以简单地编写代码来构造所需的 json 并使用 _bulk API.

发送它

理想情况下,最好通过名为 indexer 的特定应用程序完成索引,这实际上会等到一批文档,例如50100 被收集,然后以编程方式执行 _bulk API。

或者不是那样的批处理,您可以逐个文档地处理它,即 event based 使用消息队列。 (在索引过程中最小化延迟的最佳方法)

另一种选择是使用简单的 java 程序或您使用的任何其他编程语言创建一个输入文件说 data.json(纯批处理),以编程方式附加您想要的所有文档并使用 CURL命令发送请求如下图:

$ curl -s -XPOST <host_name>:9200/_bulk --data-binary @data.json

因此对于此 indexer 应用程序,您可以添加日程安排和邮件通知,这样您就可以了解每项工作的状态 运行 并安排时间到 运行 everyday/week 取决于您的要求。

Otoh,你可以利用Logstash。抱歉,这不是最佳答案,但希望对您有所帮助。

中所述,您无能为力,而 Pyotr 提议的是最小占用空间。我认为有几个细节值得补充。

散装 API 有何帮助?

考虑批量 API 的主要原因是 tuning for indexing speed。此处性能的改进主要是由于在 Elasticsearch 端处理较少的 HTTP 连接而节省的费用。实际上,如果您设法不发送那些重复的 { "index": {} } 部分,您的集群将不会更快地索引文档。

如果网络带宽是瓶颈怎么办?

在这种情况下,我认为最好的办法是发送压缩数据,如下所示:

curl -v 'http://localhost:9200/my_index/doc/_bulk' \
    -H "Content-encoding: gzip"
    -H "content-type: application/json; charset=UTF-8"
    -X POST --data-binary @bulk_data.json.gz

为了说明这个想法,我生成了一个包含随机数据的文件,如下所示:

$ head bulk_data.json
{"index":{}}
{"request_id":"40485"}
{"index":{}}
{"request_id":"12417"}
{"index":{}}
{"request_id":"11945"}
{"index":{}}
{"request_id":"81722"}
{"index":{}}
{"request_id":"52613"}

使用GZip压缩后文件大小缩小10倍:

$ ls -l
-rw-r--r--  1 vasiliev  staff  358836 Nov 16 20:09 bulk_data.json
-rw-r--r--  1 vasiliev  staff   35744 Nov 16 19:41 bulk_data.json.gz

这在带宽有限的情况下可能会有很大帮助。

压缩也可以从客户端库中获得,例如 elasticsearch-py 库。

希望对您有所帮助!