ElasticSearch教程——批量处理(mget和bulk)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gwd1154978352/article/details/82858120

ElasticSearch汇总请查看ElasticSearch教程——汇总篇

本博客所有操作均基于Kibana,基础详情见ElasticSearch教程——Kibana简单操作ES

批量查询

优点:能够大大减少网络的请求次数,缩减网络开销。

(1)自定义设置index、type以及document id

GET /_mget
{
   "docs" : [
      {
         "_index" : "ecommerce",
         "_type" :  "product",
         "_id" :    1
      },
      {
         "_index" : "ecommerce",
         "_type" :  "product",
         "_id" :    2
      }
   ]
}

返回结果如下

id为1的没有查到(found为false)

{
  "docs": [
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "1",
      "found": false
    },
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "2",
      "_version": 2,
      "found": true,
      "_source": {
        "name": "jiajieshi yagao",
        "desc": "youxiao fangzhu",
        "price": 25,
        "producer": "jiajieshi producer",
        "tags": [
          "fangzhu"
        ]
      }
    }
  ]
}

(2)在对应的index、type下进行批量查询

注意:在ElasticSearch6.0以后一个index下只能有一个type,否则会报错

GET /ecommerce/product/_mget
{
    "ids": [2, 3]
}

或者

GET /ecommerce/product/_mget
{
   "docs" : [
      {
         "_id" :    2
      },
      {
         "_id" :    3
      }
   ]
}

返回结果

{
  "docs": [
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "2",
      "_version": 2,
      "found": true,
      "_source": {
        "name": "jiajieshi yagao",
        "desc": "youxiao fangzhu",
        "price": 25,
        "producer": "jiajieshi producer",
        "tags": [
          "fangzhu"
        ]
      }
    },
    {
      "_index": "ecommerce",
      "_type": "product",
      "_id": "3",
      "_version": 1,
      "found": true,
      "_source": {
        "name": "zhonghua yagao",
        "desc": "caoben zhiwu",
        "price": 40,
        "producer": "zhonghua producer",
        "tags": [
          "qingxin"
        ]
      }
    }
  ]
}

基于bulk的增删改

bulk语法

  1. delete:删除一个文档,只要1个json串就可以了
  2. create:PUT /index/type/id/_create,强制创建
  3. index:普通的put操作,可以是创建文档,也可以是全量替换文档
  4. update:执行的partial update操作

 

注意点

1.bulk api对json的语法有严格的要求,除了delete外,每一个操作都要两个json串,且每个json串内不能换行,非同一个json串必须换行,否则会报错;

2.bulk操作中,任意一个操作失败,是不会影响其他的操作的,但是在返回结果里,会告诉你异常日志;

创建文档index

未指定id时,系统会自动创建id

POST /_bulk
{ "index": { "_index": "ecommerce", "_type":"product"}}
{ "name": "test yagao", "desc": "youxiao fangzhu"}

返回结果

{
  "took": 19,
  "errors": false,
  "items": [
    {
      "index": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "KXfSFWYBBoLynJN1TUPo",
        "_version": 1,
        "result": "created",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 9,
        "_primary_term": 2,
        "status": 201
      }
    }
  ]
}

强制创建文档create

POST /_bulk
{ "create": { "_index": "ecommerce", "_type": "product", "_id": "4" }}
{ "test_field":    "test12" }

返回结果

{
  "took": 88,
  "errors": false,
  "items": [
    {
      "create": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_version": 1,
        "result": "created",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 6,
        "_primary_term": 2,
        "status": 201
      }
    }
  ]
}

修改文档update

POST /_bulk
{ "update": { "_index": "ecommerce", "_type": "product", "_id": "4","retry_on_conflict" : 3 }}
{ "doc" : {"test_field" : "test update"} }

返回结果

{
  "took": 1,
  "errors": false,
  "items": [
    {
      "update": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_version": 2,
        "result": "noop",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "status": 200
      }
    }
  ]
}

删除文档delete

POST /_bulk
{ "delete": { "_index": "ecommerce", "_type": "product", "_id": "4"}} 

返回结果

{
  "took": 12,
  "errors": false,
  "items": [
    {
      "delete": {
        "_index": "ecommerce",
        "_type": "product",
        "_id": "4",
        "_version": 3,
        "result": "deleted",
        "_shards": {
          "total": 2,
          "successful": 1,
          "failed": 0
        },
        "_seq_no": 8,
        "_primary_term": 2,
        "status": 200
      }
    }
  ]
}

bulk api奇特的json格式

目前处理流程

  1. 直接按照换行符切割json,不用将其转换为json对象,不会出现内存中的相同数据的拷贝;
  2. 对每两个一组的json,读取meta,进行document路由;
  3. 直接将对应的json发送到node上去;

换成良好json格式的处理流程

  1. 将json数组解析为JSONArray对象,这个时候,整个数据,就会在内存中出现一份一模一样的拷贝,一份数据是json文本,一份数据是JSONArray对象;
  2. 解析json数组里的每个json,对每个请求中的document进行路由;
  3. 为路由到同一个shard上的多个请求,创建一个请求数组;
  4. 将这个请求数组序列化;
  5. 将序列化后的请求数组发送到对应的节点上去;

奇特格式的优缺点

缺点:可读性差;

优点:不需要将json数组解析为一个JSONArray对象,形成一份大数据的拷贝,浪费内存空间,能够尽可能地保证性能;

例如:

bulk size最佳大小一般建议说在几千条,大小在10MB左右。假设说现在100个bulk请求发送到了一个节点上去,然后每个请求是10MB,100个请求,就是1000MB = 1GB,然后每个请求的json都copy一份为jsonarray对象,此时内存中的占用就会翻倍,就会占用2GB的内存,甚至还不止。因为弄成jsonarray之后,还可能会多搞一些其他的数据结构,2GB+的内存占用。

占用更多的内存可能就会积压其他请求的内存使用量,比如说最重要的搜索请求,分析请求,等等,此时就可能会导致其他请求的性能急速下降。
另外的话,占用内存更多,就会导致java虚拟机的垃圾回收次数更多,跟频繁,每次要回收的垃圾对象更多,耗费的时间更多,导致es的java虚拟机停止工作线程的时间更多。

猜你喜欢

转载自blog.csdn.net/gwd1154978352/article/details/82858120