ElasticSearch数据实时性原理分析与持久化

news2024/9/17 7:41:51

问题复现

现在有这么一种业务场景,需要将海量的数据通过Hive进行数据清洗并统计,最后落库到ES中,因为需要支持大数据量的分词,模糊搜索,所以考虑用ES而不直接放到Mysql中,前端需要直接对数据进行交互,当通过后端请求向ES中新增一条数据时,页面数据刷新不会立即查询出新增的数据,即ES中的数据会存在延迟刷新

原因分析

这里先讲下ES中的一些基础概念,Shard(片)、Segment(段)、 In-memory buffer(内存索引缓存区)。

ES中的文档,是被组织在一个个片中的,一个索引可以分成多个分片,这个分片的数量在创建索引时,就要确定好。而每个片,是由多个Segment组成的,也就是说,ES存储数据的基本物理单元是Segment。

新增或修改一个文档的操作是这样的:

客户端对文档的修改,会放到内存索引缓存区中,在内存索引缓存区中会将这些修改组织成一个Segment,然后将这个Segment持久化到磁盘中。一旦Segment持久化成功,该文档的修改对客户端才可见。


如图:In-memory buffer就是内存索引缓存区,这里的内容将会组织成一个个Segment,此时它还不可搜索。

矛盾来了,Segment持久化就要写磁盘,而写磁盘是非常耗性能的

因此,ES引入一个FileSystem Cache(文件系统缓存)的概念。

In-memory buffer 中的内容,先不持久化到磁盘,而是先写入FileSystem Cache,一旦写入FileSystem Cache ,则这些内容也可以索引到了。当FileSystem Cache 达到一定数量级,或者达到某个时间点,它会调用写磁盘的操作,把它的内容写入磁盘(这一点在下文持久化中详细说明)。这样,就不会频繁写入磁盘了。

写入FileSystem Cache 是一个比较轻量级的操作,In-memory buffer 写入FileSystem Cache 的频率可以控制,默认是1s写入一次。

这也解释了开头说的ES近实时性。即对文档的修改,默认最多等 1s,就可以索引到了。

In-memory buffer 写入FileSystem Cache 的动作,称为Refresh。

Refresh的频率可以调整,对于迁移旧索引文件的操作,则可以把Refresh频率设置更长时间,比如30s,因为你对实时性要求并不高。

如果你实时性要求很高,也可以手工调用Refresh进行数据的刷新。

这里,官网有这么一段话:

尽管刷新是比提交轻量很多的操作,它还是会有性能开销。当写测试的时候, 手动刷新很有用,但是不要在生产环境下每次索引一个文档都去手动刷新。 相反,你的应用需要意识到 Elasticsearch 的近实时的性质,并接受它的不足。

解决思路

问题是elasticsearch中更新数据后有延迟

① 解决方案1 :

在新增一条文档数据,返回响应数据之前,让线程睡眠1秒钟,然后再返回响应数据,发现页面在新增文档跳转到文档列表页面后可以看到新增的文档数据了,但是休眠1S也可能会出现无法正常响应的结果;

② 解决方法2:indexRequest.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);

Elasticsearch 刚索引的文档并不是立即对搜索可见,它们会先在内存buffer中,待buffer 数据满后或主动刷新操作才会写入到文件缓存区中,便可以搜索。通过设置参数手动让内存buffer中的数据立即Refresh到FileSystem Cache中,便可实时操作文档数据,但是从前面的分析可见,会影响性能;

持久化

上面仔细看的同学,可能会注意到,FileSystem Cache之所以快,是因为他是内存的写入,没有及时提交到磁盘。如果FileSystem Cache在提交前,ES崩了,那数据不是丢失了吗?

因此,ES又引入一个概念:translog(事务日志)

每一次对 Elasticsearch 进行操作时均会进行translog的记录。所以,引入translog后的写数据过程,是这样的:

  1. 一个文档被索引之后,就会被添加到内存缓冲区(In-memory buffer),并且 追加到了translog 。

如下图所示:

  1. 每秒钟通过refresh,会将In-memory buffer 中的数据写入FileSystem Cache,并清空In-memory
    buffer,注意,此时并不会清空translog,如下图所示:

  1. 这个进程不断工作,Translog大小不断增加;此时,ES会执行一个Flush操作,该操作可以将Translog截断,清空原来的Translog区,并且,此时FileSystem Cache 中的内容也会持久化到磁盘。

Flush操作的频率可以设置 ,默认是每30分钟一次,或者是当Translog大小达到一定阈值,也会触发Flush操作,这些都可以设置 。

注意,这里的Flush操作并没有涉及到translog的提交。那translog是什么时候提交的呢?我们通过translog来保证持久化,那它本身是否是安全的呢?

这里引用官网的一段话:

translog 的目的是保证操作不会丢失。这引出了这个问题: Translog 有多安全?

在文件被 fsync 到磁盘前,被写入的文件在重启之后就会丢失。默认 translog 是每 5 秒被 fsync 刷新到硬盘, 或者在每次写请求完成之后执行(e.g. index, delete, update, bulk)。这个过程在主分片和复制分片都会发生。最终,基本上,这意味着在整个请求被 fsync 到主分片和复制分片的translog之前,你的客户端不会得到一个 200 OK 响应。

在每次请求后都执行一个 fsync 会带来一些性能损失,尽管实践表明这种损失相对较小(特别是bulk导入,它在一次请求中平摊了大量文档的开销)。

但是对于一些大容量的偶尔丢失几秒数据问题也并不严重的集群,使用异步的 fsync 还是比较有益的。比如,写入的数据被缓存到内存中,再每5秒执行一次 fsync 。

这个行为可以通过设置 durability 参数为 async 来启用:

PUT /my_index/_settings
{
“index.translog.durability”: “async”,
“index.translog.sync_interval”: “5s”
}
这个选项可以针对索引单独设置,并且可以动态进行修改。如果你决定使用异步 translog 的话,你需要 保证 在发生crash时,丢失掉 sync_interval 时间段的数据也无所谓。请在决定前知晓这个特性。

如果你不确定这个行为的后果,最好是使用默认的参数( “index.translog.durability”: “request” )来避免数据丢失。

可以看到translog默认是每次写入数据并返回客户端前,会写入成功translog。只有写入translog成功了,才会跟客户端说写入成功。

这跟mysql的redo日志有点相似 。所以说,translog是安全的。

Segment

上面我们提到,ES对索引的修改会在In-memory buffer中,每隔一秒形成一个段提交到FileSystem Cache中,这样不久,segment 的数量会很多。而段数目太多会带来较大的麻烦。 每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢。

Elasticsearch通过在后台进行段合并来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段。

段合并的时候会将那些旧的已删除文档从文件系统中清除。被删除的文档(或被更新文档的旧版本)不会被拷贝到新的大段中。

注意:ES对于文档的删除,是将此文档打上一个.del的标,在段合并时,才会真正将此段删除。

段合并的过程,是ES自动完成的,我们无须进行干预。

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

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

相关文章

Redis的自增也能实现滑动窗口限流?

文章目录限流核心原理以及代码基于Spring切面实现的注解版本限流是大家开发之路上一定会遇到的需求。比如:限制一定时间内,接口请求请求频率;一定时间内用户发言、评论次数等等,类似于滑动窗口算法。这里分享一份拿来即用的代码&a…

buildroot构建hisi平台根文件系统和工具链

buildroot构建hisi平台根文件系统和工具链 前面使用了arm-hisiv300-linux 工具链来作为Buildroot的外部工具链进行编译,然后遇到了很多编译问题。 https://blog.csdn.net/duapple/article/details/128516133?spm1001.2014.3001.5501 这里不使用hisi的工具链&…

Seata简介

小结: nacos 【name server】:注册中心,解决服务的注册与发现 nacos【config】:配置中心,微服务配置文件的中心化管理,同时配置信息的动态刷新 Ribbon:客户端负载均衡器,解决微服务集…

C++之引用类型,深浅拷贝构造

引用类型:给内存段取别名。 int m 10; //引用,给内存段取别名,所以需要给他一段内存段,而不只是声明。 int& n m;//不是赋值的意思,是别名的意思 想要在被调函数中修改主调函数中定义的变量的值时,…

小程序用户头像昵称获取规则调整与之对应调式策略、新API接口的bug

目录 调整时间 调整背景 调整说明 开发者与之对应的debug策略 1.button里面包含一个image,这种包含关系 2.然后我们可以看到官方给出的是用button组件中的open-type属性并且给到了一个chooseAvatar值! 3.我们会发现光放给我们了一个“配置好的”命…

CSAPP Cache Lab

CSAPP Cache Lab 本实验将帮助您了解缓存存储器对 C 语言性能的影响程式。实验室由两部分组成。 在第一部分中,您将编写一个小的 C 程序(大约 200-300 行)模拟高速缓存的行为。 在第二部分中,您将优化一个小型矩阵转置函数&#…

NoMachine出现 The session negotiation failed的解决方案及踩坑总结

问题情况:我A电脑输入用户名和密码可以远程B电脑,B电脑输入用户名密码就是登录不上A电脑。 B电脑上密码是用的账户密码(就是图标是一把钥匙的那个)。 A电脑上的密码是用的PIN密码(Win11系统推荐的那个)。 通…

ArcGIS基础实验操作100例--实验37线要素生成规则或随机采样点

本实验专栏参考自汤国安教授《地理信息系统基础实验操作100例》一书 实验平台:ArcGIS 10.6 实验数据:请访问实验1(传送门) 高级编辑篇--实验37 线要素生成规则或随机采样点 目录 一、实验背景 二、实验数据 三、实验步骤 &…

小程序安全设置的经验分享

一、小程序框架概述 在第一部分小程序框架概述中,将介绍小程序抽象框架、小程序调用框架和小程序初始化流程。下面让大白来逐一介绍。 1、小程序抽象框架 1.1视图层 包含WXML、WXSS和页面视图组件。 WXML是一种类似XML格式的语言,支持数据绑定、条件渲染、列表渲染、自定…

零入门容器云网络-10:基于golang编程netlink包方式操作tun设备

已发表的技术专栏(订阅即可观看所有专栏) 0  grpc-go、protobuf、multus-cni 技术专栏 总入口 1  grpc-go 源码剖析与实战  文章目录 2  Protobuf介绍与实战 图文专栏  文章目录 3  multus-cni   文章目录(k8s多网络实现方案) 4  gr…

【Linux】静态库和共享库

目录 库是什么 静态库和共享库 库的链接 优缺点 查看使用的库 制作库 制作静态库 静态库的使用 制作共享库 共享库的使用 静态库和共享库的区别 库是什么 库就是预先编译好的方法的集合 .h中是库函数的声明,库函数的实现在库中,如&#xff…

ChatGPT上线了!我在2023年1月2日这一天用上了它!百问百答!我只能说(真NB)算法工程师可以不用百度/Google了!

目录:问答结果1、你有什么nlp算法?2、平台终端3、如何训练深度学习模型?4、如何压缩nlp模型?5、bert模型有哪些用途?6、你知道汽车座舱吗?7、知识图谱有什么用途?8、能给一个构建知识图谱的案例吗&#xff…

S32K144—基于MBD的BLDC六步换相算法

可以简单分为六个功能区域: 1、全局变量 全局变量的定义是建模过程中遇到的第一个难点,因为它涉及到我们软件开发中最基础的东西——数据类型定义(Data Types Definition)。 在 Simulink 中可以通过 Bus Editor 构建自定义数据类…

【 shell 编程 】第5篇 文本编辑三剑客

文本编辑三剑客 文章目录文本编辑三剑客一、正则表达式1.基本正则表达式元字符2.拓展正则表达式元字符二、grep1.grep2.egrep3.fgrep三、sed四、awk一、正则表达式 1、简介:正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的…

点云算法-提取kitti路面点云

目录 一、ransac原理 二、ransac 地面分割原理 三、ransac常见应用 四、代码 五、截图 六、总结 一、ransac原理 RANSAC是“random sample consensus(随机抽样一致)”的缩写。它可以从一组包含“局外点”的观测数据集中,通过迭代方式估…

【408篇】C语言笔记-第二十一章(汇编语言)

文章目录第一节:汇编指令格式讲解1. 汇编指令格式2. 生成汇编方法第二节:汇编常用指令讲解1. 相关寄存器2. 常用指令3. 条件码第三节:各种变量赋值汇编实战1. 各种变量赋值汇编实战解析第四节:选择循环汇编实战1. 选择循环汇编实战…

基于ssm+mysql+jsp实现歇后语管理系统

基于ssmmysqljsp实现歇后语管理系统一、系统介绍二、系统展示1.歇后语大全2.歇后语排行榜3.歇后语管理4.用户管理三、其它系统四、获取源码一、系统介绍 本系统实现了 普通用户:歇后语大全、歇后语排行榜、歇后语管理 管理员用户:歇后语大全、歇后语排行…

一键替换Markdown文件的字体样式

功能说明 一键替换MD文件的字体样式:加粗字体—>橙色不加粗 也可以针对其它样式做切换,源码就一个demo类,修改正则匹配相关变量即可; 环境要求: windows jdk1.8 工具下载 百度网盘:提取码: ae16 …

week9

T1【深基18.例3】查找文献 题目描述 小K 喜欢翻看洛谷博客获取知识。每篇文章可能会有若干个(也有可能没有)参考文献的链接指向别的博客文章。小K 求知欲旺盛,如果他看了某篇文章,那么他一定会去看这篇文章的参考文献&#xff0…

7.1 定义抽象数据类型

文章目录定义改进的Sales_data 类定义成员函数引入this指针引入const成员函数类作用域和成员函数在类的外部定义成员函数定义返回this的函数类的静态成员定义类相关的非成员函数构造函数合成的默认构造函数某些类不能依赖合成的默认构造函数定义构造函数拷贝 赋值和析构某些类不…