Elasticsearch 8.X reindex 源码剖析及提速指南

news2025/1/23 13:11:45

1、reindex 源码在线地址

为方便大家验证,这里给出 reindex github 源码地址。

https://github.com/elastic/elasticsearch/blob/001fcfb931454d760dbccff9f4d1b8d113f8708c/server/src/main/java/org/elasticsearch/index/reindex/ReindexRequest.java

reindex 常见问题:

4ca676657dfeda7a5a1b805605762835.png

16a3965852bffa23bcfe4e5be3a570cc.png

2、reindex 源码本质

reindex 操作的本质是从一个或多个源索引中读取文档,并将这些文档索引到一个目标索引中,可能还涉及对文档的某些转换。

以下是从源码中得出的 reindex 操作的关键点:

2.1 源和目标

ReindexRequest 定义了源索引(从中读取文档)和目标索引(将文档索引到其中)。

2.2 查询和过滤

可以为源索引定义一个查询(使用 setSourceQuery 方法),以确定哪些文档应该被重新索引。

也就是可以迁移满足给定检索语句的数据。

2.3 文档转换

如果提供了一个脚本,它可以在文档从源索引移动到目标索引之前对文档进行修改或转换

2.4 批量处理

文档是批量从源索引读取并批量索引到目标索引的。

批处理的大小可以通过 setSourceBatchSize 方法进行调整。

这个值究竟可以多大,源码并没有明示。但是如下规则咱们得知道!

  • 设置一个非常大的滚动大小仍然可能会对集群造成压力,因为它会增加内存使用和集群节点之间的数据传输。

  • 因此,选择一个合适的滚动大小是很重要的,以确保在取得良好性能的同时,不会过度压迫集群。

2.5 远程源索引

0bf1afb2cd394530fe06d0f7693dbbf1.png

reindex 不仅可以在当前 Elasticsearch 集群中的索引之间移动文档(如图 1 所示),还可以从一个远程的 Elasticsearch 集群读取文档(如图 2 所示)。

60833f888d07396a58988488a539e460.png

这是通过 RemoteInfo 类实现的,它包含了远程集群的所有必要信息。

包含信息如下:

  • 远程集群的地址(可能是一个 URL 或 URI)

  • 认证信息(例如用户名和密码)

  • 请求头(为远程请求定制的特定头信息)

  • 连接超时和套接字超时

  • 其他与远程集群交互所需的配置信息

2.6 验证

在执行 reindex 操作之前,会进行一系列的验证检查(使用 validate 方法),以确保请求是合法的。

2.7 序列化/反序列化

ReindexRequest 类包含了将请求序列化到网络传输格式并从该格式反序列化的方法。

这允许 Elasticsearch 节点之间有效地通信并执行 reindex 请求。

2.8 输出

ReindexRequest 可以被转化为一个描述性的字符串(使用 toString 方法)或一个XContent格式(通常是JSON,使用 toXContent 方法),这对于日志记录和调试非常有用。

总结起来,reindex 操作的本质是从源索引读取文档、可能进行一些转换,然后将这些文档索引到目标索引。

此操作可以在当前集群的索引之间进行,也可以跨集群进行。这是一种强大的方式,可以用于数据迁移、索引重组、数据转换等任务。

3、reindex 加速

重新索引操作的速度受多个因素的影响, 如果希望加速 reindex 操作,以下是一些建议:

3.1 调整批次大小:

ReindexRequest 有一个 setSourceBatchSize 方法,允许我们设置每批处理的文档数量。

/**

     * Sets the scroll size for setting how many documents are to be processed in one batch during reindex

     */

    public ReindexRequest setSourceBatchSize(int size) {

        this.getSearchRequest().source().size(size);

        return this;

    }

增加批次大小可能会提高性能,但请注意,太大的批次可能会导致内存问题或请求超时。

3.2  slice 并行处理

slice 在 Elasticsearch 的重索引操作中确实可以帮助提速。slice 是一种将大型查询分解为多个较小部分并并行执行它们的方法,从而使整体操作更快。

在 ReindexRequest 类中,我们可以看到方法 forSlice(TaskId slicingTask, SearchRequest slice, int totalSlices),它允许我们为给定的滚动请求创建一个子切片。

如何实操?

关于设置切片数量: 当我们执行重索引操作时,可以设置 slices 参数来指定我们想要的切片数。

例如,如果我们选择 slices: 5,那么 Elasticsearch 将尝试将查询拆分成5个子查询,并尽可能均匀地分布文档。

并行执行提速

使用切片后,每个切片都可以在单独的线程或节点上并行执行。这样,如果我们有多个节点或足够的资源,切片可以显著提高重索引的速度。

实际命令:

在 Elasticsearch REST API 中,进行带切片的重索引操作的命令可能如下:

POST _reindex
{
  "source": {
    "index": "old_index",
    "size": 1000,
    "slice": {
      "id": 0,
      "max": 5
    }
  },
  "dest": {
    "index": "new_index"
  }
}

在上面的命令中,我们将原始索引分成了5个切片,并使用 id 参数来指定当前切片的编号。

要并行执行所有切片,需要为每个切片编号运行此命令(在此例中,从0到4)。

slice 注意事项

虽然切片可以加速操作,但它也会增加集群的负担,因为每个切片都会创建自己的滚动上下文。确保的 Elasticsearch 集群有足够的资源来处理我们选择的切片数量。

切片操作的最佳数量取决于数据、查询和集群配置。可能需要进行一些性能测验来找到最佳的切片数量。

总的来说,slice 可以显著提高重索引操作的速度(一会我们验证一把,用事实证明),但需要确保正确使用它,以便在提高速度的同时不过度负担集群。

3.3 优化查询

如果我们在 reindex 请求中使用了查询来筛选文档,确保该查询是优化的。避免使用复杂或低效的查询。比如:复杂嵌套查询、wildcard模糊查询等都尽量避免。

3.4 增加硬件资源

增加 Elasticsearch节点的 CPU、内存和I/O能力可以提高 reindex 的速度。

如果我们正在从远程集群进行重新索引,确保两个集群都有足够的资源。

这种针对数据量极大的情况。

3.5 优化索引设置:

在目标索引上临时禁用一些功能,如刷新和副本。完成 reindex 后,再启用它们:

设置 index.number_of_replicas 为 0 以禁用副本。

设置 index.refresh_interval 为 -1 以禁用刷新。

3.6 使用 Ingest Pipelines

如果我们正在在 reindex 操作中使用脚本对文档进行转换,考虑使用 Ingest Pipelines,这可能比脚本更高效。

3.7 网络优化

如果从远程集群重新索引,确保网络连接是高速、低延迟的。限制其他网络密集型操作的使用,以确保 reindex 请求可以充分利用带宽。

这属于边缘化建议,一般常识属于必知必会的。

3.8 限制其他操作

尝试在集群的非高峰时段执行 reindex 操作,并限制执行其他资源密集型操作,如大型搜索或其他索引操作(如段合并等)。

3.9 检查插件和外部脚本

确保没有任何插件或外部脚本影响 reindex 操作的性能。

3.10监控并调优

使用Elasticsearch的监控工具,如 Elastic Stack 的监控功能,来监控 reindex 操作的性能。这可以帮助我们识别瓶颈并进行相应的调优。

考虑到这些建议,最好在生产环境中进行测试,以找到最佳的设置和优化策略。

4、reindex 借助 slice 加速验证

4.1准备工作

  • 条件1——选择或创建一个足够大的数据。

需要一个大型索引,这样性能差异才会明显。小数据集可能不会显示出明显的差异。

  • 条件2——确保集群健康。

确保 Elasticsearch 集群在开始测试之前是健康的,所有节点都是在线的,没有挂起的任务。

  • 条件3——关闭其他大型操作。

确保集群上没有其他大型查询或索引操作在运行,以免影响性能测试结果。

4.2 不使用 slice 的重索引

  • 记录开始时间。

  • 使用 _reindex API 执行重索引操作,但不使用 slice。

  • 记录完成时间。

  • 计算持续时间。

## 第一种:直接迁移。

  "took": 4005,

POST _reindex
{
  "source": {
    "index": "image_index"
  },
  "dest": {
    "index": "image_index_direct"
  }
}

GET image_index_direct/_count

4.3 使用 slice 的重索引

  • 选择一个切片数量:例如,如果有5个数据节点,我们可能想尝试5个切片。

  • 记录开始时间。

  • 使用 _reindex API 执行重索引操作,为每个切片创建一个单独的请求。可以使用并发工具(如 parallel 命令或脚本)来并行运行所有的请求。

  • 记录所有切片完成的时间。

  • 计算总持续时间。

## 第二种,加了并行处理!
 
POST _reindex
{
  "source": {
    "index": "image_index",
    "slice": {
      "id": 0,
      "max": 5
    }
  },
  "dest": {
    "index": "image_index_slice"
  }
}

4.4 比较

比较两次重索引的总时间。理论上,使用 slice 的版本应该更快,尤其是在有多个节点和大量数据的集群中。

如下视频所示,我优先小范围做了验证。

数据量 16MB,上万条数据迁移结果对比:

迁移方式耗时
直接迁移4005ms
slice迁移1123ms

数据量 112MB,15万条长津湖影评数据迁移结果对比:

迁移方式耗时
直接迁移30000ms左右(事后视频回放看到的)
slice迁移10263ms

综上两种数量级不同数据的 reindex 结果可以看出,加了 slice 能提速 3-4倍

更多节点规模集群和大规模数据,期待大家留言反馈结果。

5、小结

有了方案,更多的付诸实践,拿出结果才更有谁服力!

a0c526dbb29298601cf17e4e670f8043.png

加油!

推荐阅读

  1. 全网首发!从 0 到 1 Elasticsearch 8.X 通关视频

  2. 重磅 | 死磕 Elasticsearch 8.X 方法论认知清单

  3. 如何系统的学习 Elasticsearch ?

  4. 2023,做点事

  5. 干货 | Elasticsearch Reindex性能提升10倍+实战

c370ec857a0fb7eddf814fc62b8b95f0.jpeg

更短时间更快习得更多干货!

和全球 近2000+ Elastic 爱好者一起精进!

66e844f9e4befc913c1b758b7e89710a.gif

大模型时代,抢先一步学习进阶干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/924680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

睿趣科技:抖音开网店要怎么找货源

在当今数字化的时代,电商平台的兴起为越来越多的人提供了开设网店的机会,而抖音作为一个充满活力的短视频平台,也为创业者提供了广阔的发展空间。然而,对于许多初次涉足电商领域的人来说,找到合适的货源却是一个重要的…

IIS之WEB服务器详解(下)

文章目录 前言一、如何在服务器发布自己的网站二、如何在同一服务器上发布多个网站 前言 上一篇博客我们已经在服务器上下载了 IIS-WEB 插件,里面有默认的网站,相当于做了一个简易的WEB网站。今天就来介绍如何配置自己的网站并发布,在WEB服务…

C# .aspx网页获取RFID读卡器HTTP协议提交的访问文件Request获得卡号、机号,Response回应驱动读卡器显示响声

本示例使用的设备:RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) 服务端代码: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.…

leetcode59. 螺旋矩阵 II(java)

螺旋矩阵 题目描述缩进法 上期经典 题目描述 难度 - 中等 原题链接 - 螺旋矩阵 示例1&#xff1a; 输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]] 示例 2&#xff1a; 输入&#xff1a;n 1 输出&#xff1a;[[1]] 提示&#xff1a; 1 < n < 20 缩进法…

Leetcode每日一题:1782. 统计点对的数目(2023.8.24 C++)

目录 1782. 统计点对的数目 题目描述&#xff1a; 实现代码与解析&#xff1a; hash 双指针 原理思路&#xff1a; 1782. 统计点对的数目 题目描述&#xff1a; 给你一个无向图&#xff0c;无向图由整数 n &#xff0c;表示图中节点的数目&#xff0c;和 edges 组成&am…

【C++初阶】list的常见使用操作

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前学习C和算法 ✈️专栏&#xff1a;C航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&#x1…

Opencascad(C++)-建模-创建有界直线段

文章目录 1、 前言2、用gp_Lin创建一条直线2.1 gp_Lin类成员函数2.2 创建一条直线2.3 运行结果 3、创建一条有界的直线段3.1 功能说明3.2 函数说明3.2 创建直线段的代码3.3 测试效果 1、 前言 在Opencascad开发时&#xff0c;经常会遇到创建直线的情况&#xff0c;采用gp_Line…

计算机终端核心安全配置规范

声明 本文是学习 政务计算机终端核心配置规范. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 范围 本标准提出了政务计算机终端核心配置的基本概念和要求&#xff0c;规定了核心配置的自动化实现方法&#xff0c;规范了核心配置实施流程。 本标准适…

设计模式(单例模式,工厂模式),线程池

目录 什么是设计模式? 单例模式 饿汉模式 懒汉模式 工厂模式 线程池 线程池种类 ThreadPoolExcutor的构造方法: 手动实现一个线程池 什么是设计模式? 计算机行业程序员水平层次不齐,为了让所有人都能够写出规范的代码,于是就有了设计模式,针对一些典型的场景,给出一…

嵌入式学习之linux

今天&#xff0c;主要对linux文件操作原理进行了学习&#xff0c;主要学习的内容就是对linux文件操作原理进行理解。写的代码如下&#xff1a;

[MyBatis系列④]核心配置文件

目录 1、简介 2、DTD 3、typeHandlers 3.1、默认类型处理器 3.2、自定义类型处理器 4、plugins ⭐MyBatis系列①&#xff1a;增删改查 ⭐MyBatis系列②&#xff1a;两种Dao开发方式 ⭐MyBatis系列③&#xff1a;动态SQL 1、简介 MyBatis的核心配置文件&#xff08;通常命…

【Spring Boot】数据库持久层框架MyBatis — MyBatis简介

MyBatis简介 本节首先会介绍什么是ORM、什么是MyBatis、MyBatis的特点以及核心概念&#xff0c;最后介绍MyBatis是如何启动、如何加载配置文件的&#xff1f; 1.什么是ORM ORM&#xff08;Object Relational Mapping&#xff0c;对象关系映射&#xff09;是为了解决面向对象…

抖音创作服务平台发布作品

最近分析了一下抖音创作服务平台发布作品的步骤 获取密钥等参数通过密钥等参数获取到上传视频需要的参数上传视频发布作品 需要的一些参数有a_bogus Signature crc32等 目前还没有校验a_bogus 只需要传入Cookie以及视频即可发布

C语言sscanf函数学习

sscanf()与scanf()相比&#xff0c;scanf()以键盘(stdin)为输入源&#xff0c;sscanf()以第一个参数的固定字符串为输入源&#xff1b; sscanf()的头文件是 #include <stdio.h>&#xff1b; 函数原型&#xff1a; int sscanf (char *str, char * format [, argument, ..…

纸贵科技连续三年蝉联IDC中国 FinTech 50榜单

近日&#xff0c;国际权威市场研究机构IDC公布了“2023 IDC中国FinTech 50榜单”。作为领先的区块链技术和解决方案服务商&#xff0c;纸贵科技凭借过硬的区块链技术和丰富的金融科技创新成果&#xff0c;连续第三年荣登IDC中国FinTech 50榜单。 IDC中国FinTech 50榜单是金融科…

广告电商模式

电商越来越渗透进我们的生活之中&#xff0c;网上医疗&#xff0c;网上订购电影票&#xff0c;车票等&#xff0c;未来绝不仅仅是网购这么简单&#xff0c;电商行业以后会与生活的方方面面更加精密结合在一起。因此&#xff0c;电商销售的发展是持续增长的&#xff0c;现在很多…

Oracle 查询(当天,月,年)的数据

Trunc 在oracle中&#xff0c;可利用 trunc函数 查询当天数据&#xff0c;该函数可用于截取时间或者数值&#xff0c;将该函数与 select 语句配合使用可查询时间段数据 查询当天数据 --sysdate是获取系统当前时间函数 --TRUNC函数用于截取时间或者数值&#xff0c;返回指定的…

[线程/C++(11)]线程池

文章目录 一、C实现线程池1. 头文件2. 测试部分 二、C11实现线程池1. 头文件2. 测试部分 一、C实现线程池 1. 头文件 #define _CRT_SECURE_NO_WARNINGS #pragma once #include<iostream> #include<string.h> #include<string> #include<pthread.h> #…

vue学习之热更新、单文件开发、插槽、作用域插槽

vue-cli 全局安装&#xff1a;-g&#xff0c;全局安装 vue-cli npm install -g vuecli 创建项目 vue create my-app 生成的文件结构&#xff1a; node-modules: 存放依赖src&#xff1a;源代码文件夹src- components&#xff1a;存放组件的位置 将上一篇中我们html的文件…

【SpringCloud技术专题】「Gateway网关系列」(1)微服务网关服务的Gateway组件的原理介绍分析

为什么要有服务网关? 我们都知道在微服务架构中&#xff0c;系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢&#xff1f;难道要一个个的去调用吗&#xff1f;很显然这是不太实际的&#xff0c;我们需要有一个统一的接口与这些微服务打交道&#xf…