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
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法