《Elasticsearch:权威指南》Document APIs -- Bulk API

Bulk API,能够在一个请求中调用执行多个 index/delete操作。这可以大大提高索引速度。

该 REST API 以 /_bulk结尾,它遵循JSON结构:

action_and_meta_data\n      //第一行为action 和 meta_data参数
optional_source\n           //第二行为source参数
action_and_meta_data\n
optional_source\n
....
action_and_meta_data\n
optional_source\n

从上面能够看到,两行数据构成了一次操作,第一行是action(操作类型)可以是 indexcreateupdate,或者delete,第二行就是我们的可选的数据体,使用这种方式批量插入的时候,我们需要设置的它的Content-Type为application/x-ndjson

注意:数据的最终行必须以换行符结束\n。每个换行符前面都可以有一个回车符\ r

针对不同的操作类型,第二行里面的可选的数据体是不一样的,如下:

  • action值为 indexcreate时期望下一行是source数据体,支持op_type API 语法。(默认如果文档不存在就创建他,但如果文档存在就覆盖之)

阅读 Index API Operation type ( 操作类型 )章节 了解更多

简单来说批量处理逻辑和单条处理逻辑一致,op_type参数也可以配置在批处理场景,用于改变一些默认操作行为。

默认情况下的新增操作,如果指定id,存在相同的Index、type和id时,es会执行修改操作,version属性递增;如果不指定id,每次自动生成id,并作为新数据插入库。

  • action值为delete时不需要第二行作为源(只要能匹配到数据被删除即可,不需要body),并与 delete API 中具有相同的语义。

  • update第二行可以是 partial docupsert或者是script

我们可以将我们的操作直接写入到一个文本文件中,然后使用curl命令把它发送到服务端,必须使用 --data-binary的标志,而不是 -d。后者不保留换行符。例:

新建一个requests文件,每一行都是Json形式的数据。

$ cat requests
{ "index" : { "_index" : "test", "_type" : "_doc", "_id" : "1" } }
{ "field1" : "value1" }
$ curl -s -H "Content-Type: application/x-ndjson" -XPOST localhost:9200/_bulk --data-binary "@requests"; echo

执行结果:

{"took":7, "errors": false, "items":[{"index":{"_index":"test","_type":"_doc","_id":"1","_version":1,"result":"created","forced_refresh":false}}]}

代码中的echo是为了换行

因为这种格式使用 \n作为分隔符,请确保 JSON actionsource 没有被格式化(必须是无空格,每行表示action或source,不能随意换行)。这里是一个正确的 bulk 命令使用的例子:

POST _bulk
{ "index" : { "_index" : "test", "_type" : "_doc", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_type" : "_doc", "_id" : "2" } }
{ "create" : { "_index" : "test", "_type" : "_doc", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_type" : "_doc", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

没有找到如何通过curl直接发送json形式的方法,有可能只有先写入数据至文件,再导入了

执行结果:

{
   "took": 30,
   "errors": false,
   "items": [
      {
         "index": {
            "_index": "test",
            "_type": "_doc",
            "_id": "1",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 201,
            "_seq_no" : 0,
            "_primary_term": 1
         }
      },
      {
         "delete": {
            "_index": "test",
            "_type": "_doc",
            "_id": "2",
            "_version": 1,
            "result": "not_found",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 404,
            "_seq_no" : 1,
            "_primary_term" : 2
         }
      },
      {
         "create": {
            "_index": "test",
            "_type": "_doc",
            "_id": "3",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 201,
            "_seq_no" : 2,
            "_primary_term" : 3
         }
      },
      {
         "update": {
            "_index": "test",
            "_type": "_doc",
            "_id": "1",
            "_version": 2,
            "result": "updated",
            "_shards": {
                "total": 2,
                "successful": 1,
                "failed": 0
            },
            "status": 200,
            "_seq_no" : 3,
            "_primary_term" : 4
         }
      }
   ]
}

bulk请求的路径有三种:

  • /_bulk
    需要在action中提供index和type
  • / {index} / _bulk
    需要在action中提供type
  • {index} / {type} / _bulk
    不需要在action中提供index和type

关于格式的注释。 这里的想法是使处理速度尽可能快。 由于某些action将重定向到其他节点上的其他分片,因此仅action_meta_data在接收节点侧进行解析。

使用此协议的客户端库应尝试并努力在客户端执行类似的操作,并尽可能减少缓冲。

针对 bulk action 的响应是一个大的 Json 结构,包含着每个 action 执行后的结果。单一的 action 故障不会影响其余的操作。

在单个批量调用中没有“正确”的操作数量。 您应该尝试不同的设置,以找到适合您特定工作负载的最佳大小。

如果使用HTTP API,请确保客户端不发送HTTP块,因为这会减慢速度。

什么是HTTP 块?

乐观并发控制

批量API调用中的每个索引和删除操作都可以在其各自的操作和元数据行中包含if_seq_noif_primary_term参数。 根据对现有文档的最后修改,if_seq_noif_primary_term参数控制如何执行操作。 有关更多详细信息,请参见乐观并发控制。

版本控制

每个bulk 条目 都可以使用“version ”字段显示版本值。 它基于_version映射自动遵循索引/删除操作的行为。 它还支持version_type(请参阅版本控制)。

路由

每个批量处理的条目 都可以使用routing字段。 它基于_routing映射自动遵循索引/删除操作的行为。

Waiting For Active Shards

当创建 bulk call 时,您可以设置 wait_for_active_shards 参数,在开始 bulk 请求之前要求活跃分片副本的最低数量。请参见这里进一步的详细信息和使用示例。

刷新

控制何时可以看到此请求所做的更改。 请参阅刷新。

刷新将仅影响接收批量请求的分片。 想象一个_bulk?refresh = wait_for请求,其中有三个文档,恰好被路由到具有五个分片的索引中的不同分片上。 该请求将仅等待这三个分片刷新。 组成索引的其他两个分片根本不参与_bulk请求。

Update

当使用 update操作,_retry_on_conflict可以被用作在 action 本身,指定了在一个版本冲突的情况下多少次更新可以被重试。

更新 action的负载,支持下列选项:doc(部分文档),upsertdoc_as_upsertscriptparams(脚本), lang(脚本)和_source。见更新文档的详细信息。更新 action 的Curl 例子如下:

POST _bulk
{ "update" : {"_id" : "1", "_type" : "_doc", "_index" : "index1", "retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"} }
{ "update" : { "_id" : "0", "_type" : "_doc", "_index" : "index1", "retry_on_conflict" : 3} }
{ "script" : { "source": "ctx._source.counter += params.param1", "lang" : "painless", "params" : {"param1" : 1}}, "upsert" : {"counter" : 1}}
{ "update" : {"_id" : "2", "_type" : "_doc", "_index" : "index1", "retry_on_conflict" : 3} }
{ "doc" : {"field" : "value"}, "doc_as_upsert" : true }
{ "update" : {"_id" : "3", "_type" : "_doc", "_index" : "index1", "_source" : true} }
{ "doc" : {"field" : "value"} }
{ "update" : {"_id" : "4", "_type" : "_doc", "_index" : "index1"} }
{ "doc" : {"field" : "value"}, "_source": true}
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页