IILeeのBlog

IILeeのBlog

ES 数据库重建索引 Reindex 【数据迁移】

122
2022-04-20
ES 数据库重建索引 Reindex 【数据迁移】

应用背景:

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

2、当数据的 mapping 需要修改,但是大量的数据已经导入到索引中了,重新导入数据到新的索引太耗时;但是在 ES 中,一个字段的 mapping 在定义并且导入数据之后是不能再修改的,

所以这种情况下也可以考虑尝试使用 Reindex。

Reindex:

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

数据迁移步骤:

1、创建新的索引 (可以通过 java 程序也可以直接在 head 插件上创建)

注意:在创建索引的时候要把表结构也要创建好 (也就是 mapping)

2、复制数据

最简单、基本的方式:

1)代码请求:

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

2)利用命令:

curl _XPOST 'ES 数据库请求地址: 9200/_reindex' -d{"source":{"index":"old_index"},"dest":{"index":"new_index"}}

但如果新的 index 中有数据,并且可能发生冲突,那么可以设置 version_type"version_type": "internal"或者不设置,则 Elasticsearch 强制性的将文档转储到目标中,覆盖具有相同类型和
ID 的任何内容:

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

数据迁移效率

问题发现:

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

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

原因分析:

reindex 的核心做跨索引、跨集群的数据迁移。
慢的原因及优化思路无非包括:
1)批量大小值可能太小。需要结合堆内存、线程池调整大小;
2)reindex 的底层是 scroll 实现,借助 scroll 并行优化方式,提升效率;
3)跨索引、跨集群的核心是写入数据,考虑写入优化角度提升效率。

可行方案:

1)提升批量写入大小值

默认情况下,_reindex 使用 1000 进行批量操作,您可以在 source 中调整 batch_size。

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

批量大小设置的依据:

1、使用批量索引请求以获得最佳性能。

批量大小取决于数据、分析和集群配置,但一个好的起点是每批处理 5-15 MB。

注意,这是物理大小。文档数量不是度量批量大小的好指标。例如,如果每批索引 1000 个文档:

1)每个 1kb 的 1000 个文档是 1mb。

2)每个 100kb 的 1000 个文档是 100 MB。

这些是完全不同的体积大小。

2、逐步递增文档容量大小的方式调优。

1)从大约 5-15 MB 的大容量开始,慢慢增加,直到你看不到性能的提升。然后开始增加批量写入的并发性 (多线程等等)。

2)使用 kibana、cerebro 或 iostat、top 和 ps 等工具监视节点,以查看资源何时开始出现瓶颈。如果您开始接收 EsRejectedExecutionException,您的集群就不能再跟上了:
至少有一个资源达到了容量。

要么减少并发性,或者提供更多有限的资源 (例如从机械硬盘切换到 ssd 固态硬盘),要么添加更多节点。

2)借助 scroll 的 sliced 提升写入效率

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

sliced 原理(from medcl)

1)用过 Scroll 接口吧,很慢?如果你数据量很大,用 Scroll 遍历数据那确实是接受不了,现在 Scroll 接口可以并发来进行数据遍历了。
2)每个 Scroll 请求,可以分成多个 Slice 请求,可以理解为切片,各 Slice 独立并行,利用 Scroll 重建或者遍历要快很多倍。

slicing 使用举例

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 倍 +。

后记

原文地址 : www.cnblogs.com