分布式全文检索引擎ElasticSearch-数据的写入存储底层原理

news2025/2/26 23:13:32

一、数据写入的核心流程

当向 ES 索引写入数据时,整体流程如下:

1、客户端发送写入请求

客户端向 ES 集群的任意节点(称为协调节点,Coordinating Node)发送一个写入请求,比如 index(插入或更新)或 delete(删除)请求。

2、协调节点处理请求

  • 协调节点接收到请求后,确定数据应该存储在哪个索引和分片上。
  • 通过路由计算确定目标分片,默认的路由规则是通过文档的 _id 取哈希值,再对分片数取模来定位分片。
shard = hash(_id) % number_of_primary_shards

3、请求转发给主分片

协调节点将请求转发给对应的 主分片(Primary Shard)所在的节点,主分片负责执行写入操作。

4、主分片写入阶段

主分片接收到写入请求后,执行以下操作:

  • 写入内存缓冲区(Buffer):首先将数据写入到内存中的写入缓冲区,这是一块内存区域,用于快速接收新数据。
  • 写入事务日志(Translog):同时,将数据写入事务日志(Translog)。Translog 是一个顺序写入的日志文件,用于在节点宕机时进行数据恢复,确保数据不会丢失。

5、数据刷新到段(Segment)

  • 定期刷新(Flush):每隔一定时间(默认是 1 秒)或当缓冲区达到一定大小时,ES 会将内存缓冲区中的数据刷新到段(Segment)中。段是倒排索引的基本存储单元。
  • 生成新的段文件:数据被写入段后,段文件会被写入磁盘,段文件一旦生成便是不可更改的(只读的)。
  • 清空缓冲区:刷新后,内存缓冲区被清空,但 Translog 依然保留,直到执行 flush 操作。

6、同步到副本分片

  • 主分片写入成功后,将请求转发给对应的 副本分片(Replica Shard) 所在的节点。
  • 副本分片执行与主分片相同的写入操作,确保主副本数据一致。
  • 当所有副本分片写入成功后,主分片向协调节点返回写入成功的确认。

7、返回写入结果给客户端

协调节点收到主分片和副本分片的成功确认后,向客户端返回写入成功的响应。

二、核心组件介绍

1、内存缓冲区(Buffer)

  • 作用:用于临时存储写入的数据,提高写入性能。
  • 刷新机制:每隔一段时间(默认 1 秒)或当缓冲区满时,数据会被刷新到段(Segment)。

2、事务日志(Translog)

  • 作用:用于记录所有未持久化到段的数据,防止数据丢失。
  • 持久化:写入操作在返回成功之前,必须确保数据被写入 Translog。
  • Flush 操作:定期将数据从缓冲区刷新到段,并清空 Translog,生成新的空的 Translog。

3、段(Segment)

下一节将详细讲

4、主分片与副本分片

  • 主分片(Primary Shard):负责处理写入和查询请求。
  • 副本分片(Replica Shard):主分片的冗余副本,用于提高数据可用性和查询性能。
  • 一致性:写入时,主分片和副本分片保持数据一致,确保容错能力。

三、段的深度剖析

什么是段

段(Segment) 是倒排索引的基本存储单元。每当数据被写入或更新时,ES 并不会立即将其合并到现有的数据结构中,而是将数据写入新的段。段存储在磁盘上,并以不可变的形式存在。这种设计有助于提升写入和查询的性能,同时简化了数据管理。

段 是一种包含索引数据的小型文件集合,每个段都包含:

  • 倒排索引(Inverted Index):用于快速搜索文档的内容。
  • 文档元数据(如 _id、分数等)。
  • 存储字段(Stored Fields):用于存储完整的文档内容或字段值。
  • 删除标记(Deletion Markers):标记哪些文档被逻辑删除。

什么时候生成段?

当 ES 将数据从内存缓冲区刷新(Refresh)到磁盘时,就会创建新的段。这些段会持续累积,直到 ES 触发合并(Merge)操作,将多个小段合并成更大的段。

为什么使用段

  • 高效写入

    • ES 将数据先写入内存缓冲区,然后批量刷新到新的段,而不是直接修改现有的段。
    • 这种批量写入减少了频繁的磁盘操作,提高了写入性能。
  • 并发查询与写入

    • 由于段是只读的,多个查询可以并发访问这些段,而不会影响写入操作。
    • 新数据写入时,不会影响正在查询的旧段,保证了数据的可用性。
  • 快速删除与更新

    • ES 的删除和更新操作不直接修改段内的数据,而是通过逻辑标记(标记文档为删除)来实现。
    • 这种方式避免了频繁的磁盘重写操作,提高了性能。
  • 增量合并

    • ES 通过定期将多个小段合并成大段,减少段的数量,优化查询性能。
    • 合并过程是在后台异步进行的,不影响前台查询和写入。

为什么段是不可变的

  • 简化并发控制

    • 因为段是不可变的,多个查询可以安全地并发读取相同的段,而无需担心数据被修改或锁定。
    • 不需要复杂的并发控制机制,简化了系统设计。
  • 提高查询性能

    • 由于段不变,ES 可以预先构建和优化倒排索引,确保查询时能够快速检索数据。
    • 不可变的段使得查询操作可以直接访问磁盘数据,无需等待写入操作完成。
  • 高效的删除和更新

    • 删除和更新不会直接修改段内的数据,而是通过生成新的段和标记旧段来完成。
    • 这种方式避免了频繁的随机写入,提高了磁盘写入性能。
  • 崩溃恢复与数据安全

    • 不可变的段一旦写入磁盘,就不会被更改。这意味着即使 ES 崩溃,已写入的段不会丢失或损坏。
    • 恢复时,只需要重新应用事务日志(Translog)中尚未刷新的数据。

四、为什么说ES的检索是近实时的

如果ES像MySQL一样,等到数据真正落盘完毕,才返回写入成功,这叫直接写入方式,这能达到实时搜索。但是这会有什么样的问题呢?

直接写入存在的问题

提交一个新的段到磁盘需要 fsync操作,确保段被物理地写入磁盘,即时电源失效也不会丢失数据。

但是 fsync 是昂贵的,严重影响性能,当写数据量大的时候会造成ES 停顿卡死,查询也无法做到快速响应新文档在几分钟之内即可被检索,并且这样还是不够快,磁盘在这里成为了瓶颈。

延时写策略

所以 fsync不能在每个文档被索引的时就触发,需要一种更轻量级的方式使新的文档可以被搜索,所以为了提升写的性能,ES没有每新增一条数据就增加一个段到磁盘上而是采用延时写的策略。

具体做法如下:

每当有新增的数据时,就将其先写入到内存中

在内存和磁盘之间是文件系统缓存,当达到默认的时间(1秒钟)或者内存的数据达到一定量时,会触发一次刷新(Refresh),将内存中的数据生成到一个新的段上并缓存到文件缓存系统上,稍后再被刷新到磁盘中并生成提交点。

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

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

相关文章

TensorRT C++ API模型加速 —— TensorRT配置、模型转换、CUDA C++加速、TensorRT C++ 加速

文章目录 前言:TensorRT简介0.1、TensorRT算法流程0.2、TensorRT主要优化技术 一、TensorRT配置1.1、TensorRT环境配置1.1.1、CUDA安装1.1.2、TensorRT下载1.1.3、TensorRT CUDA配置1.1.4、TensorRT配置1.1.4.1、TensorRT python配置1.1.4.2、TensorRT C配置&#x…

RPC 服务与 gRPC 的入门案例

RPC 协议 RPC(Remote Procedure Call Protocol)即远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务的协议,允许一个计算机程序可以像调用本地服务一样调用远程服务 。 RPC的主要作用是不同的服务间方法调用就像本地…

基于Spring Boot的体育商品推荐系统

一、系统背景与目的 随着电子商务的快速发展和人们健康意识的提高,体育商品市场呈现出蓬勃发展的态势。然而,传统的体育商品销售方式存在商品种类繁多、用户选择困难、个性化需求无法满足等问题。为了解决这些问题,基于Spring Boot的体育商品…

在 DDD 中优雅的发送 Kafka 消息

前言 1:host 映射 下载 SwitchHost 配置一个映射地址。点击 添加一个本地环境,之后配置你的 IP kafka 这样就能找这个地址了。IP 为你本地的IP,如果是云服务器就是公网IP地址 使用docker-compose.yml进行一键部署安装 version: 3.0 # docker-compose …

数字电视标准与分类

数字电视相关内容是一个极其成熟且久远的领域,并不像其它的技术方面那么前沿。但是学习技术的另外一个方面也不就是可以维持咱们的好奇心以及认识生活中多个事务后面的技术本质。 近年来,电视领域发生了一系列的变化,电视数字化的进程明显加快…

AI视频配音技术创新应用与商业机遇

随着人工智能技术的飞速发展,AI视频配音技术已经成为内容创作者和营销人员的新宠。这项技术不仅能够提升视频内容的吸引力,还能为特定行业带来创新的解决方案。本文将探讨AI视频配音技术的应用场景,并讨论如何合法合规地利用这一技术。 AI视频…

Airbus结构数字样机理念及实践(转)

关注作者 1、数字样机的背景 早期的设计文档通过二维工程图来描述,对工程师来说,绘制工程图足够表达设计思想,工程图成为了标准的“工程师语言”。但是外围的用户通常通过透视图来表达设计意图,不得不产生了大量针对不同教育背景…

UNIAPP框架uView初步集成与开发设计

uView UI,是uni-app生态最优秀的UI框架,全面的组件和便捷的工具会让您信手拈来,如鱼得水。本文章分享UNIAPP集成使用uView页面动态开发设计。 一、使用HBuilder X 直接导入插件,下载后重启 uView - DCloud 插件市场 二、配置样…

【图像处理lec7】图像恢复、去噪

目录 一、图像退化与恢复概述 二、图像退化中的噪声模型 1、使用 imnoise 函数添加噪声 (1)imnoise 函数的概述 (2)函数语法 (3)支持的噪声类型与具体语法 (4)噪声类型的详细…

dpdk中udp包的接受与发送

预备知识 dpdk中一些关键宏定义与结构体定义 以太网帧相关 宏RTE_ETHER_ADDR_LEN mac地址长度,6字节48位 宏RTE_ETHER_TYPE_IPV4 代表ipv4 struct rte_ether_hdr 以太网帧头结构体,包含了三个成员变量,目的地址,源地址&#…

C语言进阶(2) ---- 指针的进阶

前言:指针的主题,我们在初阶的《指针》章节已经接触过了,我们知道了指针的概念: 1.指针就是个变量,用来存放地址,地址唯一标识一块内存空间。 2.指针的大小是固定的4/8个字节(32位平台/64位平台)。 3.指针是…

项目整体结构优化

文章目录 1.依赖配置方式1.作为专门管理依赖的模块2.作为父模块3.作为子模块4.注意事项1.关于relativePath的配置2.关于打包的配置3.遇到maven报错的解决方案1.首先刷新maven2.从子模块开始clean-install3.最终:在最顶级的模块clean-package 2.概览3.新建一个子模块sun-depende…

计算机视觉-边缘检测

图片分类 一张图片中可能有多个需要识别的物体,会用方框标注他们的位置和类别 例: 给出一张照片,计算机需要从中识别出这是一只猫 一张图片的计算量是较大的,这张图片的尺寸虽然是6464,因为每张图片有3个颜色通道&am…

多模块应用、发布使用第三方库(持续更新中)

目录: 1、多模块概述(HAP、HSP、HAR) HAR与HSP两种共享包的主要区别体现在: 2、三类模块: 3、创建项目:项目名:meituan (1)创建Ability类型的Module,编译后为HAP文件…

安卓 文件管理相关功能记录

文件管理细分为图片、视频、音乐、文件四类 目录 权限 静态声明权限 动态检查和声明权限方法 如何开始上述动态申请的流程 提示 图片 获取图片文件的对象列表 展示 删除 视频 获取视频文件的对象列表 获取视频file列表 按日期装载视频文件列表 展示 播放 删除…

CHIMA网络安全攻防大赛经验分享

比赛模式 第一轮:20分钟基础知识赛(50道题) 安全运维,法律法规,linux操作系统等 第二轮:50分钟CTF夺旗(5道题) 题目涵盖 密码学 运用多种工具,如ASCII对照&#xff0c…

QT 国际化(翻译)

QT国际化(Internationalization,简称I18N)是指将一个软件应用程序的界面、文本、日期、数字等元素转化为不同的语言和文化习惯的过程。这使得软件能够在不同的国家和地区使用,并且可以根据用户的语言和地区提供本地化的使用体验。…

[Java] 使用 VSCode 来开发 Java

目录 前言Java 环境怎么看自己是否已经配置完成?安装 JDK安装 Maven 环境修改 Maven 依赖源 完善 VS Code配置插件配置 Maven配置 Maven Settings配置 Maven 可执行文件地址 前言 由于使用 VSCode 编码已经成为习惯,并且它确实相对其他的 IDE 较为轻量化…

如何高效获取Twitter数据:Apify平台上的推特数据采集解决方案

引言 在数据分析和市场研究领域,Twitter(现在的X)数据一直是重要的信息来源。但是,自从Twitter更改API定价策略后,获取数据的成本大幅提升。本文将介绍一个经济实惠的替代方案。 为什么需要Twitter数据? …

vue3+ant design vue实现日期选择器不展示清除按钮

1、代码&#xff1a;只需设置:allowClear"false"即可 <a-date-pickerv-model:value"value1":disabledDate"disabledDate"change"queryRate":allowClear"false" />const disabledDate (current: Dayjs) > {// 获取…