Elasticsearch进阶篇(一):Elasticsearch写入原理深入详解

Elasticsearch写入原理深入详解

1. ES相关问题

引用官方文档地址:分片内部原理 | Elasticsearch: 权威指南 | Elastic

为什么Elasticsarch是近实时,而不是准实时?
为什么文档的CRUD (创建-读取-更新-删除) 操作是实时的?
Elasticsearch 是怎样保证更新被持久化在断电时也不丢失数据?
Refresh、flush的作用是什么? 什么时候使用?
Elasticsearch存储怎么让数据保存在磁盘上,而不是在内存上?
为什么删除文档不会立刻释放空间?

2. ES索引、分片、分段的概念

2.1 索引 index

索引是 Elasticsearch 存储、组织和搜索数据的逻辑容器。它类似于 MySQL 中的数据表,一个 Elasticsearch 集群可以包含多个索引。从 Elasticsearch 7.x 开始,Elasticsearch 不再支持多个 type且默认为_doc,并在之后的版本中完全移除,因此索引可以认为是一个数据表而非数据库

2.2 分片 shard

在Elasticsearch中,分片是对索引数据的水平划分和分布。索引被分成多个分片,每个分片可以在集群的不同节点上存储。这种分片的设计提供了一种水平扩展的能力,允许将大量数据分布到多个节点上,从而提高性能和可伸缩性。每个分片就是一个Lucene的实例,具有完整的功能。

ES使用数据**分片(shard)**来提高服务的可用性,将数据分散保存在不同的节点上以降低当单个节点发生故障时对数据完整性的影响,同时使用副本(repiica)来保证数据的完整性。关于分片的默认分配策略,在7.x之前,默认5个primary shard,每个primary shard默认分配一个replica,即5主1副,而7.x之后,默认1主1副

2.3 分段 segment

一个段(segment)是有完整功能的倒排索引Lucene中的索引指的是段的集合和提交点(commit point,即记录所有分段的文件)。当在这个commit point上进行搜索,就是在这个提交点下面的所有的segment文件中搜索,每个segment返回结果,然后汇总返回给用户。

每当创建新文档时,它们就会被写入新的 Segment 中。 每当创建新文档时,它们都属于一个新的 Segment,并且无需修改前一个 Segment。 如果必须删除文档,则在其原始 Segment 中将其标记为已删除。 这意味着它永远不会从 Segement 中物理删除

与更新相同:文档的先前版本在上一个 Segment 中被标记为已删除,更新后的版本保留在当前 Segment 中的同一文档 ID下

  • 分段内的doc数量上限是2的31次方

  • 默认每秒都会生成一个segment文件

  • 在分片中搜索将依次搜索每个片段,然后将其结果合并到该分片的最终结果中

    查看索引中分段信息的方法:

GET /nlc_works/_segments 

es写入流程

shards: 包含了关于索引各个分片的详细信息。

  • 0, 1, 2: 这些是分片的编号,表示各个分片的信息。
    • routing: 分片的路由信息,表示该分片所在的节点、状态等。
    • num_committed_segments: 分片中已提交的段(segments)数量。
    • num_search_segments: 分片中用于搜索的段数量。
    • segments: 分片中的段信息。
      • _2, _3, _a, _b, _c, _3, _4: 这些是段的标识,表示各个段的信息。
        • generation: 段的代数,表示段的生成次数。
        • num_docs: 段中文档的数量。
        • deleted_docs: 已删除的文档数量。
        • size_in_bytes: 段的大小(以字节为单位)。
        • memory_in_bytes: 段占用的内存大小。
        • committed: 表示该段是否已提交。
        • search: 表示该段是否用于搜索。
        • version: Lucene 版本。
        • compound: 表示该段是否是复合段。
        • attributes: 段的属性信息。

2.4 索引、分片、分段的关系图示

Lucene 索引就是我们所说的Elasticsearch分片 ,而 Elasticsearch 中的索引是分片的集合。

es写入流程

3. es写入操作

3.1 refresh操作

refresh 操作是指手动或自动刷新索引从in-memory buffer(内存缓冲区)到 filesystem cache(文件系统缓存) 的过程。在 ES中写入的文档首先被索引到内存中的缓冲区(in-memory buffer)创建一个新的segment,执行refresh 操作会使该segment写入filesystem cache(文件系统缓存),同时可以立即被搜索到。

es写入流程

可以通过两种方式触发 refresh 操作:

  1. 显式刷新(Explicit Refresh):通过发送 refresh 请求到 Elasticsearch API 来手动执行刷新操作。这样可以确保在需要时立即刷新数据,但过于频繁的手动刷新可能会影响性能

    POST /{index}/_refresh
    
  2. 自动刷新(Automatic Refresh):Elasticsearch 也支持自动刷新机制。可以配置索引的刷新间隔(refresh interval),使得索引在一定时间内自动刷新。这样可以减少手动操作的需求,但需要权衡刷新频率与性能之间的关系。

    PUT /my_index/_settings
    {"index.refresh_interval": "1s"
    }
    

    关闭自动刷新

    PUT /my_index/_settings
    { "refresh_interval": -1 
    }
    

3.2 flush操作

Elasticsearch 中的 flush 操作是指将 filesystem cache(文件系统缓存) 中的数据写入到磁盘,并清空事务日志(transaction log)文件的过程。这个过程确保了在节点重启或者故障发生时,已经提交但尚未持久化到磁盘上的数据不会丢失。

具体来说,flush 操作包含以下步骤:

  1. 写入磁盘(Write to Disk):将filesystem cache(文件系统缓存)的 segment 数据刷入磁盘,确保数据持久化。

  2. 清空事务日志(Clear Transaction Log):清空事务日志文件,以删除已经被持久化的数据。事务日志是用来记录索引操作的,包括写入、更新和删除操作。一旦数据被成功写入到磁盘,相关的事务日志就会被清空,以释放磁盘空间并减少对日志文件的依赖。

    es写入流程

flush 操作默认情况下不会经常执行,而是由 Elasticsearch 自动管理。通常,Elasticsearch 会根据一定的条件来触发 flush 操作,例如:

  • translog大小达到阈值
  • 默认配置下固定时间间隔
  • 手动触发 flush

在默认配置下,Elasticsearch 会每隔一段时间(默认是 30 分钟)执行一次 flush 操作。这个时间间隔可以通过配置文件进行调整以满足特定需求。flush 操作的执行频率和时机会受到硬件性能、索引写入频率等因素的影响。

手动触发 flush 操作 API:

POST /{index}/_flush

3.3 commit 提交

commit point 是指在内存中的数据被成功写入到磁盘上并持久化的时间点。当 Elasticsearch 成功将数据写入到磁盘上后,会生成一个新的 commit point,这个点标志着数据的持久化已经完成,之后的操作可以基于这个新的 commit point。

commit 操作流程

  • 写入新的分段(segment):首先,Elasticsearch 将内存中的新文档数据写入到磁盘上,形成一个新的分段。这个新的分段包含了最近添加的文档数据。

  • 更新提交点(commit point):随后,Elasticsearch 更新分片的提交点,记录新创建的分段以及相关的元数据信息。。

  • 同步磁盘(fsync):为了确保数据的持久化,Elasticsearch 执行磁盘同步操作,将所有在文件系统缓存中等待的写入操作刷新到磁盘上。

  • 打开新分段:完成同步后,新创建的分段被打开,使得其中包含的文档数据可以被搜索。新添加的文档就可以立即被查询到。

  • 清空内存缓冲区:最后内存中的索引缓冲区被清空,准备接受新的文档数据。下一次的提交操作就可以将新的文档写入到一个新的分段中

commit point 的生成通常发生在以下情况下:

  1. 显式提交(Explicit Commit):通过 API 或命令向 Elasticsearch 发送显式提交请求,要求将内存中的数据刷新到磁盘上。这种情况下,commit point 会被立即生成。

  2. 自动提交(Automatic Commit):Elasticsearch 会定期检查内存中的缓冲区,并在达到一定条件时自动触发数据的刷新。这些条件可能包括缓冲区已满、一定的时间间隔已过等。

    es写入流程

每个 commit point 记录了当前 Elasticsearch 中所有可用的段(segments)。对于每个 commit point,都会有一个与之对应的 .del 文件,用于记录删除操作。在 Elasticsearch 中,删除操作并不会直接从磁盘上物理移除文档,而是将其标记为已删除状态。这些删除操作会被准确地记录在 .del 文件中,包括了在某个段内哪些文档已被删除。当进行查询操作时,尽管在段中已经标记为删除的文档可以被查询到,但在返回结果时,Elasticsearch 会根据对应 commit point 维护的 .del 文件,将已被删除的文档过滤掉,确保返回的结果是准确的。这一机制保证了即使执行了删除操作,查询结果也会反映出文档的最新状态。

4. Elasticsearch写入步骤拆解

在Elasticsearch中,当数据被写入到一个节点的主分片之后,副本分片会被复制到其他节点。这个过程是由Elasticsearch内部的分片复制机制完成的,通常在写入数据到主分片之后,Elasticsearch会异步地将主分片的数据复制到其他节点上的相应副本分片

当前有三个节点,并且每个索引有一个主分片和一个副本分片,那么数据写入的过程如下:

  1. 客户端发送写入请求到Nginx负载均衡器

  2. Nginx负载均衡器根据负载均衡算法选择一个节点作为协调节点

  3. 协调节点通过哈希取模算法确定数据要写入的目标节点,并将写入请求转发到目标节点

  4. 目标节点接收到写入请求后,将数据写入到对应的主分片

  5. 目标节点开始将主分片的数据异步复制到其他节点上的副本分片

  6. 其他节点接收到复制请求后,开始接收并存储副本分片的数据

  7. primary和replica节点数据写入完成后,协调节点返回结果响应,nginx转发响应结果

    ​ Elasticsearch写入步骤图示

es写入拆解

5. 相关参考

官网参考:分片内部原理 | Elasticsearch: 权威指南 | Elastic

官网参考:[Inside a Shard | Elasticsearch: The Definitive Guide master] | Elastic

参考链接: Elasticsearch写入原理深入详解-阿里云开发者社区 (aliyun.com)

参考:Elasticsearch:Elasticsearch 中的 refresh 和 flush 操作指南_elasticsearch flush-CSDN博客

本文依照官网和其他资料整理完成,如果有错误之处烦请指出

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

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

相关文章

FineReport报表如何在单元格中显示本地图片(图片地址已存储到MySQL数据库中)

帆软帮助文档对应查看链接:https://help.fanruan.com/finereport/doc-view-854.html?source4#需求:在设计FineReport报表时,想在单元格中显示图书信息对应的图片,图片路径已存储到MySQL数据库中 一、查询数据库 查询MySQL中图书…

为什么defineProps宏函数不需要从vue中import导入?

前言 我们每天写vue代码时都在用defineProps,但是你有没有思考过下面这些问题。为什么defineProps不需要import导入?为什么不能在非setup顶层使用defineProps?defineProps是如何将声明的 props 自动暴露给模板? 举几个例子 我们…

【算法面试题】-06

智能成绩表 题目描述 小明来到学校当老师&#xff0c;需要将学生按考试总分或单科分数进行排名&#xff0c;你能帮帮他吗&#xff1f; 输入描述 第 1 行输入两个整数&#xff0c;学生人数 n 和科目数量 m。 0 < n < 100 0 < m < 10 第 2 行输入 m 个科目名称&…

探索性数据分析EDA的数据可视化

大家好&#xff0c;数据可视化是探索性数据分析的重要组成部分&#xff0c;因为它有助于分析和可视化数据&#xff0c;以获得对数据分布、变量之间的关系和潜在异常值的启示性见解。Python具有丰富的库&#xff0c;可以快速高效地创建可视化。 在Python中&#xff0c;通常使用…

MIT 6.S081---Lab: locks

Memory allocator (moderate) 修改kernel/kalloc.c&#xff0c;修改kmem声明并定义结构体数组&#xff1a; 修改kernel/kalloc.c中的kinit函数&#xff0c;对kmemList进行初始化&#xff1a; 修改kernel/kalloc.c中的kfree函数&#xff0c;获取当前的cpuid并将释放的内存添加到…

C语言知识点总结00-C语言知识点目录

专栏主页&#xff1a; 数据结构算法程序设计基础C语言知识点总结https://blog.csdn.net/seeker1994/category_12585732.html 最优算法100例00-最优算法100例目录 数据结构知识点总结00-知识点目录 ...... C语言知识点目录 程序设计基础C语言知识点总结 1 概述 2 数…

CSS 【详解】响应式布局(明天内容)

响应式布局&#xff1a; 同一页面在不同的屏幕上有不同的布局&#xff0c;即一套代码自适应不同的屏幕。 常用 单位&#xff1a; 像素&#xff08;px&#xff09;&#xff1a;像素是最常用的长度单位&#xff0c;它表示屏幕上的一个物理像素点。例如&#xff0c;width: 200px; …

Java学习笔记------常用API(二)

Object 无有参构造 public Object() 空参构造 成员方法&#xff1a; public String toString() 返回对象的字符串表示 public boolean equals(object obj) 比较两个对象是否相等 Object默认用号比较地址值&#xff0c;需要重写才能比较属性值 protected O…

使用Anaconda创建Python指定版本的虚拟环境

由于工作的需要和学习的需要&#xff0c;需要创建不同Python版本的虚拟环境。 比如zdppy的框架&#xff0c;主要支持的是Python3.8的版本&#xff0c;但是工作中FastAPI主要使用的是3.11的版本&#xff0c;所以本地需要两套Python环境。 决定使用Anaconda虚拟环境管理的能力&…

【小白学机器学习8】统计里的自由度DF=degree of freedom, 以及关于df=n-k, df=n-k-1, df=n-1 等自由度公式

目录 1 自由度 /degree of freedom / df 1.1 物理学的自由度 1.2 数学里的自由度 1.2.1 数学里的自由度 1.2.2 用线性代数来理解自由度&#xff08;需要补充&#xff09; 1.2.3 统计里的自由度 1.3 统计学里自由度的定义 2 不同对象的自由度 2.1 纯公式的自由度&#…

xss.haozi.me靶场“0x0B-0x12”通关教程

君衍. 一、0x0B 实体编码绕过二、0x0C script绕过三、0x0D 注释绕过四、0X0E ſ符号绕过五、0x0F 编码解码六、0x10 直接执行七、0x11 闭合绕过八、0x12 闭合绕过 一、0x0B 实体编码绕过 我们首先构造payload进行测试&#xff1a; 这里我们可以看到全部转为了大写&#xff0c…

2024年3月份实时获取地图边界数据方法,省市区县街道多级联动【附实时geoJson数据下载】

首先&#xff0c;来看下效果图 在线体验地址&#xff1a;https://geojson.hxkj.vip&#xff0c;并提供实时geoJson数据文件下载 可下载的数据包含省级geojson行政边界数据、市级geojson行政边界数据、区/县级geojson行政边界数据、省市区县街道行政编码四级联动数据&#xff0…

一台GTX1080显卡的怪兽,我可不能错过这个机会!

标题&#xff1a;我花了30块钱买了一台电脑主机。 这个配置能赚钱吗&#xff1f; 1. 收购惊喜 那是一个阳光明媚的下午&#xff0c;我在水管修理店里闲逛。 突然&#xff0c;一位老顾客手里拿着一台旧电脑主机匆匆走了进来。 他说&#xff1a;“小王&#xff0c;你能帮我看看…

【算法训练营】周测3

清华大学驭风计划课程链接 学堂在线 - 精品在线课程学习平台 (xuetangx.com) 如果需要答案代码可以私聊博主 有任何疑问或者问题&#xff0c;也欢迎私信博主&#xff0c;大家可以相互讨论交流哟~~ 考题11-3 题目描述 输入格式 输出格式 输出到标准输出。 若可以通关&…

STM32的GPIO初始化配置-学习笔记

简介&#xff1a; 由于刚开始没有学懂GPIO的配置原理&#xff0c;导致后面学习其它外设的时候总是产生阻碍&#xff0c;因为其它外设要使用前&#xff0c;大部分都要配置GPIO的初始化&#xff0c;因此这几天重新学习了一遍GPIO的配置&#xff0c;记录如下。 首先我们要知道芯片…

力扣701. 二叉搜索树中的插入操作

思路&#xff1a;往二叉搜索树中插入一个值&#xff0c;树的结构有多种符合的情况&#xff0c;那我们可以选一种最容易的插入方式&#xff0c;反正只需要插入一个值而已&#xff0c;我们不难发现&#xff0c;不管插入什么值&#xff0c;都可以安排插入到叶子节点上。 再利用二叉…

传统SessionID,Cookie方式与SringSecurity+JWT验证方式

在Spring Boot框架中&#xff0c;可以使用Spring Session来处理会话管理。Spring Session允许开发者在不同的存储后端&#xff08;如Redis、数据库等&#xff09;之间共享和管理会话状态。通过Spring Session&#xff0c;开发者可以轻松地实现会话管理、会话失效以及跨多个节点…

Redux Toolkit

本文作者为 360 奇舞团前端开发工程师 阅读本文章前&#xff0c;需要先了解下 redux 的基本概念与用法&#xff0c;Redux Toolkit 是建立在 Redux 基础之上的工具包&#xff0c;因此需要对 Redux 的基本概念有一定的了解&#xff0c;包括 Action、Reducer、Store、Middleware 等…

【C语言】如何规避野指针

✨✨ 欢迎大家来到莉莉的博文✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 目录 一、概念&#xff1a; 二、野指针成因&#xff1a; 2.1. 指针未初始化 2.2 指针越界访问 3. 指针指向的空间释放 三、如何规避野指针 3.…

专题二 - 滑动窗口 - leetcode 904. 水果成篮 | 中等难度

leetcode 904. 水果成篮 leetcode 904. 水果成篮 | 中等难度1. 题目详情1. 原题链接2. 基础框架 2. 解题思路1. 题目分析2. 算法原理3. 时间复杂度 3. 代码实现4. 知识与收获 leetcode 904. 水果成篮 | 中等难度 1. 题目详情 你正在探访一家农场&#xff0c;农场从左到右种植…