ElasticSearch的Reindex

时间:2022-07-23
本文章向大家介绍ElasticSearch的Reindex,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

前言

ES在BI应用中常常仅仅只作为全文检索库,数据的加工在数据库中进行,数据如何同步到ES中?一般的思路有增量和全量,对于超大数量的场景,如千万、亿+,全量的同步会非常慢,如何进行增量呢?ES支持在内部reindex,其包含哪些场景?给索引增、删、改一列或某些列是否可以单独只同步修改的列?

使用场景

使用查询过滤文档Reindex

POST _reindex
{
  "source":{
    "index":"es_succbidw_ztxx",
    "query":{
      "term":{
        "HYDM.keyword":"L0000"
      }
    }
  },
  "dest":{
    "index":"reindex_001"
  }
}

//返回响应体
{
  "took" : 181,
  "timed_out" : false,
  "total" : 862,
  "updated" : 0,
  "created" : 862,
  "deleted" : 0,
  "batches" : 1,
  "version_conflicts" : 0,
  "noops" : 0,
  "retries" : {
    "bulk" : 0,
    "search" : 0
  },
  "throttled_millis" : 0,
  "requests_per_second" : -1.0,
  "throttled_until_millis" : 0,
  "failures" : [ ]
}

dest索引不存在时会自动创建(根据数据采用动态映射进行mapping)

使用max_docs限定Reindex的文档数

POST _reindex
{
  "source":{
    "index":"es_succbidw_ztxx",
    "query":{
      "term":{
        "HYDM.keyword":"L0000"
      }
    }
  },
  "dest":{
    "index":"reindex_001"
  }
}

//
{
  "took" : 89,
  "timed_out" : false,
  "total" : 1,
  "updated" : 0,
  "created" : 1,
  "deleted" : 0,
  "batches" : 1,
  "version_conflicts" : 0,
  "noops" : 0,
  "retries" : {
    "bulk" : 0,
    "search" : 0
  },
  "throttled_millis" : 0,
  "requests_per_second" : -1.0,
  "throttled_until_millis" : 0,
  "failures" : [ ]
}

从多个源Reindex

POST _reindex
{
  "source":{
    "index":["reindex_001","reindex_003"]
  },
  "dest":{
    "index":"reindex_004"
  }
}

Reindex API不会处理ID冲突,以最后写入的文档为准,但顺序通常不可预测,因此依靠这种行为不是一个好主意。相反,请使用脚本确保ID唯一。

从源中切块Reindex

POST _reindex
{
  "source":{
    "index":"es_succbidw_ztxx",
    "_source":["QYNBXH","QYMC"]
  },
  "dest":{
    "index":"reindex_005"
  }
}

此思路可以用来删除ES索引中的部分字段

改变源index中字段Reindex

POST my-index-000001/_doc/1?refresh
{
  "text": "words words",
  "flag": "foo"
}

POST _reindex
{
  "source": {
    "index": "my-index-000001"
  },
  "dest": {
    "index": "my-new-index-000001"
  },
  "script": {
    "source": "ctx._source.tag = ctx._source.remove("flag")"
  }
}

Reindex期间修改文档

POST _reindex
{
  "source": {
    "index": "my-index-000001"
  },
  "dest": {
    "index": "my-new-index-000001",
    "version_type": "external"
  },
  "script": {
    "source": "if (ctx._source.foo == 'bar') {ctx._version++; ctx._source.remove('foo')}",
    "lang": "painless"
  }
}

从远程ES中Reindex

POST _reindex
{
  "source": {
    "remote": {
      "host": "http://otherhost:9200",
      "username": "user",
      "password": "pass"
    },
    "index": "my-index-000001",
    "query": {
      "match": {
        "test": "data"
      }
    }
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}

零停机重建索引Reindex

重建索引的问题是必须更新应用中的索引名称,即Reindex的目标索引与源索引名是不同的,对应用端会产生影响。解决办法是有的,可以通过索引别名在运行的ES中无缝从一个索引切换到另一个索引。代价是应用端在使用索引时用的时索引别名。

ES提供了两种api来管理索引别名:_alias用于单个操作,_aliases用于执行多个原子级操作。

无缝切换过程如下:

//1、在创建索引时便给索引创建一个别名,应用端始终使用索引的别名
PUT /es_succbidw_ztxx/_alias/ztxx

//2、Reindex索引

POST _reindex
{
  "source":{
    "index":"es_succbidw_ztxx"
  },
  "dest":{
    "index":"es_succbidw_ztxx1"
  }
}

//3、索引别名重定向,别名切换两个操作需要原子化,使用_aliases
POST /_aliases
{
    "actions": [
        { "remove": { "index": "es_succbidw_ztxx", "alias": "ztxx" }},
        { "add":    { "index": "es_succbidw_ztxx1", "alias": "ztxx" }}
    ]
}

性能优化

有些参数可以用来在Reindex种优化重建的效率

1、source下的size

网上说该参数默认值为1000,官方文档中没有说明清楚,可适当调大该参数

2、slices

Reindex支持Sliced Scroll以并行化重建索引过程。 这种并行化可以提高效率,并提供一种方便的方法将请求分解为更小的部分。一般设置为自动模式,通过url来传递slices参数,ES能自动处理分片并发

POST _reindex?slices=5&refresh
{
  "source": {
    "index": "twitter",
    "size": 5000
  },
  "dest": {
    "index": "new_twitter"
  }
}

slices的值最好为索引的分片数,即number_of_shards:

get  /es_succbidw_ztxx/_settings

{
  "es_succbidw_ztxx" : {
    "settings" : {
      "index" : {
        "creation_date" : "1597910982409",
        "number_of_shards" : "1",
        "number_of_replicas" : "1",
        "uuid" : "BgqJJBXBQ8GKlvhSSzkVsA",
        "version" : {
          "created" : "7050099"
        },
        "provided_name" : "es_succbidw_ztxx"
      }
    }
  }
}

总结

1、为了索引能在ES内部reindex,需要使用别名机制,应用端始终使用ES的别名

2、reindex的性能需要调试size和slices进行确定

参考

1、https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-reindex.html

2、https://www.cnblogs.com/hyhy904/p/11098546.html

3、https://blog.csdn.net/laoyang360/article/details/81589459

4、https://www.jianshu.com/p/afae616bdef5

5、https://www.elastic.co/guide/cn/elasticsearch/guide/current/index-aliases.html

6、https://www.cnblogs.com/gmhappy/p/11864054.html