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索引重建的常见使用场景以及典型的使用方法,并说明了相关性能优化的技巧和请求超时问题的处理方法。

目录
相关文章
|
存储 缓存 算法
ES写入过程和写入原理调优及如何保证数据的写一致性(上)
ES写入过程和写入原理调优及如何保证数据的写一致性
ES写入过程和写入原理调优及如何保证数据的写一致性(上)
ElasticSearch Task命令说明
ElasticSearch task相关命令,以及返回信息解读。
6237 0
ElasticSearch Task命令说明
|
5月前
|
算法 搜索推荐 Serverless
为什么 ES 的搜索结果只到 10,000?强制“数清楚”的代价有多大
Elasticsearch 7.x后默认返回10,000总数,实为Block-Max WAND算法的性能优化——跳过低分文档块以提升查询速度。强行开启`track_total_hits:true`将禁用该优化,导致CPU飙升、延迟激增。本文深入Lucene底层,解析其原理、陷阱与治理方案。
683 1
正则表达式 命名捕获组
命名捕获组
6494 147
|
缓存 Java 索引
Elasticsearch的TermsQuery慢查询分析和优化
前言 本篇文章主要记录业务上的一个TermsQuery优化和分析的过程和一些思考。 在使用ES的时候,经常会遇到慢查询,这时候可以利用profile进行分析,当利用profile也查看不出什么端倪时候,可以尝试通过阅读代码查看查询为什么这么慢。如下是一个我们内部业务的一个慢查询,经常出现4s左右的延时,一模一样的查询,但是延时不一样,且很难复现。 { "from": 0,
4049 0
Elasticsearch的TermsQuery慢查询分析和优化
|
NoSQL Redis 监控
redis-shake数据同步&迁移&备份导入导出工具使用介绍
redis-shake是阿里云Redis&MongoDB团队开源的用于redis数据同步的工具。
74025 4
redis-shake数据同步&迁移&备份导入导出工具使用介绍
|
人工智能 安全 机器人
AppFlow:将Kimi大模型加入钉钉群聊
使用AppFlow将Kimi大模型(基于Moonshot)集成到钉钉的步骤概览: 1. 在AppFlow控制台创建连接流,选择钉钉机器人,触发事件为收到文本消息。 2. 添加智谱AI的“使用prompt对话大模型”动作,配置API KEY。 3. 配置模型推理后消息的发送回钉钉的动作,插入变量表示模型结果。 4. 配置Webhook地址和加签(或IP白名单),在钉钉群聊中添加机器人,启用Outgoing机制,填写AppFlow的Webhook地址。 5. 通过@机器人在群聊中与Kimi模型进行交互。 这个教程展示了如何通过AppFlow将AI模型无缝接入钉钉,提升办公效率。
1106 5
|
存储 搜索推荐 数据可视化
【Elasticsearch】Elasticsearch索引创建与管理详解
【Elasticsearch】Elasticsearch索引创建与管理详解
1769 10
|
NoSQL Redis
Redis——单机迁移cluster集群如何快速迁移
Redis——单机迁移cluster集群如何快速迁移
635 0
|
存储 JSON NoSQL
【redis数据同步】redis-shake数据同步全量+增量
【redis数据同步】redis-shake数据同步全量+增量