ES索引重建reindex详解

简介: ES索引重建reindex详解

一、使用场景


1.分片数变更:当你的数据量过大,而你的索引最初创建的分片数量不足,导致数据入库较慢的情况,此时需要扩大分片的数量,此时可以尝试使用Reindex。

2. mapping字段变更:当数据的mapping需要修改,但是大量的数据已经导入到索引中了,重新导入数据到新的索引太耗时;但是在ES中,一个字段的mapping在定义并且导入数据之后是不能再修改的,所以这种情况下也可以考虑尝试使用Reindex。

3. 分词规则修改,比如使用了新的分词器或者对分词器自定义词库进行了扩展,而之前保存的数据都是按照旧的分词规则保存的,这时候必须进行索引重建。


二、_reindex


官方说明地址:reindex


ES提供了_reindex这个API。相比于我们重新导入数据肯定会快不少,实测速度大概是bulk导入数据的5-10倍。

reindex的核心做跨索引、跨集群的数据迁移。


Reindex 不会尝试设置目标索引。 它不会复制源索引的设置。 您应该在运行 _reindex 操作之前设置目标索引,包括设置映射、分片计数、副本等。


先根据复制源索引创建新的目标索引,然后执行reindex命令。

基础使用命令:


POST _reindex
{
  "source": {
    "index": "old_index"
  },
  "dest": {
    "index": "new_index"
  }
}


三、实战


1、覆盖更新

说明:

"version_type": "internal",internal表示内部的,省略version_type或version_type设置为 internal 将导致 Elasticsearch 盲目地将文档转储到目标中,覆盖任何具有相同类型和 ID 的文件。

这也是最常见的重建方式。


POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "internal"
  }
}


2、创建丢失的文档并更新旧版本的文档

说明:

"version_type": "external",external表示外部的,将 version_type 设置为 external 将导致 Elasticsearch 保留源中的版本,创建任何丢失的文档,并更新目标索引中版本比源索引中版本旧的任何文档。

id不存在的文档会直接更新;id存在的文档会先判断版本号,只会更新版本号旧的文档。

POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "version_type": "external"
  }
}

3、仅创建丢失的文档

要创建的 op_type 设置将导致 _reindex 仅在目标索引中创建丢失的文档,所有存在的文档都会引起版本冲突。

只要两个索引中存在id相同的记录,就会引起版本冲突。


POST _reindex
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}

4、冲突处理

默认情况下,版本冲突会中止 _reindex 进程。 “冲突”请求正文参数可用于指示 _reindex 继续处理有关版本冲突的下一个文档。 需要注意的是,其他错误类型的处理不受“冲突”参数的影响。

当"conflicts": "proceed"在请求正文中设置时,_reindex 进程将继续处理版本冲突并返回遇到的版本冲突计数。


POST _reindex
{
  "conflicts": "proceed",
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter",
    "op_type": "create"
  }
}


5、source中添加查询条件

POST _reindex
{
  "source": {
    "index": "twitter",
    "query": {
      "term": {
        "user": "kimchy"
      }
    }
  },
  "dest": {
    "index": "new_twitter"
  }
}

6、source中包含多个源索引

源中的索引可以是一个列表,允许您在一个请求中从多个源中复制。 这将从 twitter 和 blog 索引中复制文档:


POST _reindex
{
  "source": {
    "index": ["twitter", "blog"]
  },
  "dest": {
    "index": "all_together"
  }
}


也支持*号来匹配多个索引。


POST _reindex
{
  "source": {
    "index": "twitter*"
  },
  "dest": {
    "index": "all_together"
  }
}

7、限制处理的记录数

通过设置size大小来限制处理文档的数量。

POST _reindex
{
  "size": 10000,
  "source": {
    "index": "twitter",
    "sort": { "date": "desc" }
  },
  "dest": {
    "index": "new_twitter"
  }
}

8、从远程ES集群中重建索引

POST _reindex
{
  "source": {
    "remote": {
      "host": "http://otherhost:9200",
      "username": "user",
      "password": "pass",
      "socket_timeout": "1m",
      "connect_timeout": "10s"
    },
    "index": "source",
    "query": {
      "match": {
        "test": "data"
      }
    }
  },
  "dest": {
    "index": "dest"
  }
}

9、提取随机子集

说明:从源索引中随机取10条数据到新索引中。

POST _reindex
{
  "size": 10,
  "source": {
    "index": "twitter",
    "query": {
      "function_score" : {
        "query" : { "match_all": {} },
        "random_score" : {}
      }
    },
    "sort": "_score"    
  },
  "dest": {
    "index": "random_twitter"
  }
}

10、修改字段名称

原索引

POST test/_doc/1?refresh
{
  "text": "words words",
  "flag": "foo"
}


重建索引,将原索引中的flag字段重命名为tag字段。


POST _reindex
{
  "source": {
    "index": "test"
  },
  "dest": {
    "index": "test2"
  },
  "script": {
    "source": "ctx._source.tag = ctx._source.remove(\"flag\")"
  }
}


结果:


GET test2/_doc/1
{
  "found": true,
  "_id": "1",
  "_index": "test2",
  "_type": "_doc",
  "_version": 1,
  "_seq_no": 44,
  "_primary_term": 1,
  "_source": {
    "text": "words words",
    "tag": "foo"
  }
}


四、性能优化


常规的如果我们只是进行少量的数据迁移利用普通的reindex就可以很好的达到要求,但是当我们发现我们需要迁移的数据量过大时,我们会发现reindex的速度会变得很慢。

数据量几十个G的场景下,elasticsearch reindex速度太慢,从旧索引导数据到新索引,当前最佳方案是什么?

原因分析:

reindex的核心做跨索引、跨集群的数据迁移。

慢的原因及优化思路无非包括:

1)批量大小值可能太小。需要结合堆内存、线程池调整大小;

2)reindex的底层是scroll实现,借助scroll并行优化方式,提升效率;

3)跨索引、跨集群的核心是写入数据,考虑写入优化角度提升效率。

可行方案:

1)提升批量写入的大小值size

2)通过设置sliced提高写入的并行度


1、提升批量写入大小值

默认情况下 _reindex 使用 1000 的滚动批次。可以使用源元素source中的 size 字段更改批次大小:

POST _reindex
{
  "source": {
    "index": "source",
    "size": 5000
  },
  "dest": {
    "index": "dest"
  }
}


2、提高scroll的并行度

Reindex 支持 Sliced Scroll 来并行化重新索引过程。 这种并行化可以提高效率并提供一种将请求分解为更小的部分的便捷方式。

每个Scroll请求,可以分成多个Slice请求,可以理解为切片,各Slice独立并行,利用Scroll重建或者遍历要快很多倍。

slicing的设定分为两种方式:手动设置分片、自动设置分片。


自动设置分片如下:


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


slices大小设置注意事项:

1)slices大小的设置可以手动指定,或者设置slices设置为auto,auto的含义是:针对单索引,slices大小=分片数;针对多索引,slices=分片的最小值。

2)当slices的数量等于索引中的分片数量时,查询性能最高效。slices大小大于分片数,非但不会提升效率,反而会增加开销。

3)如果这个slices数字很大(例如500),建议选择一个较低的数字,因为过大的slices 会影响性能。

效果

实践证明,比默认设置reindex速度能提升10倍+。


五、超时问题


es中的请求超时时间默认是1分钟,当重建索引的数据量太大时,经常会出现超时。这种情况可以增大超时时间,也可以添加wait_for_completion=false参数将请求转为异步任务。

POST _reindex?slices=9&refresh&wait_for_completion=false
{
  "source": {
    "index": "twitter"
  },
  "dest": {
    "index": "new_twitter"
  }
}


1、获取reindex任务列表

GET _tasks?detailed=true&actions=*reindex


2、根据任务id查看任务

GET /_tasks/r1A2WoRbTwKZ516z6NEs5A:36619

3、取消任务

POST _tasks/r1A2WoRbTwKZ516z6NEs5A:36619/_cancel


总结


本文主要介绍了ES索引重建的常见使用场景以及典型的使用方法,并说明了相关性能优化的技巧和请求超时问题的处理方法。

目录
相关文章
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库——索引(2)-B+Tree、Hash结构,索引分类(聚集索引、二级索引)
MySQL数据库——索引(2)-B+Tree、Hash结构,索引分类(聚集索引、二级索引)
91 1
|
7月前
|
存储 NoSQL 分布式数据库
Hbase的三种索引_全局索引,覆盖索引,本地索引(七)
Hbase的三种索引_全局索引,覆盖索引,本地索引(七)
207 0
|
SQL 存储 缓存
索引合并,能不用就不要用吧!
索引合并,能不用就不要用吧!
|
存储 索引
ES索引切分
在生产项目中,由于ElasticSearch单个索引数据量大,索引中部分数据不常用,在搜索和写入文档时,效率较低。为了减小单个索引的数据量,提升搜索和文档写入效率,将大索引根据一定的规则拆分为小的索引。
290 0
ES索引切分
|
存储 分布式计算 安全
ES索引备份还原
es数据出于线上数据安全考虑,对于es已有的索引数据可以进行安全备份,通常可以将es备份到共享文件目录或者一些其它的数据存储的文件系统eg:HDFS、Amazon S3、Azure Cloud。备份会生成索引的快照存储到指定的仓库路径下,当需要进行数据还原的时候,就可以通过访问备份还原的接口快速实现数据还原。
251 0
ES索引备份还原
|
安全 大数据 API
ES如何查询索引的全量数据
ES如何查询索引的全量数据
2321 0
|
索引
索引分类、创建索引、删除索引
索引分类、创建索引、删除索引
140 0
索引分类、创建索引、删除索引
|
SQL OLTP 索引
【INDEX】重建索引的两条参考依据
如果是OLTP系统,存在正大量的删除和更新操作的系统中,日积月累,索引将会千疮百孔,使用索引用来检索数据的效率会急转直下。因此要求我们定期的对索引进行维护,我们可以使用DROP/CREATE方式或REBUILD方式完成索引的重建,恢复索引应该有的效率。 问题来了,什么时候需要重建?重建索引的依据是什么呢? 有两个依据可供参考。第一个是,查看索引的“高度”,如果索引树高超过了4我们就需要重点关注;另外一个参考依据是,索引条目被删除的数据占总索引条目的百分比如果超过了20%,一般在这种情况下就要考虑重建索引。 如果获得这两个参考依据?方法其实很简单,我们仅需对索引进行一下分析,然后通过IND
140 0