Elasticsearch 分片内部原理—近实时搜索、持久化变更

目录

一、近实时搜索

refresh API

二、持久化变更

flush API


一、近实时搜索

随着按段(per-segment)搜索的发展,一个新的文档从索引到可被搜索的延迟显著降低了。新文档在几分钟之内即可被检索,但这样还是不够快。

磁盘在这里成为了瓶颈。提交(Commiting)一个新的段到磁盘需要一个 fsync 来确保段被物理性地写入磁盘,这样在断电的时候就不会丢失数据。 但是 fsync 操作代价很大; 如果每次索引一个文档都去执行一次的话会造成很大的性能问题。

我们需要的是一个更轻量的方式来使一个文档可被搜索,这意味着 fsync 要从整个过程中被移除。

在Elasticsearch和磁盘之间是文件系统缓存。 像之前描述的一样, 在内存索引缓冲区( Figure 19, “在内存缓冲区中包含了新文档的 Lucene 索引” )中的文档会被写入到一个新的段中( Figure 20, “缓冲区的内容已经被写入一个可被搜索的段中,但还没有进行提交” )。 但是这里新段会被先写入到文件系统缓存—​这一步代价会比较低,稍后再被刷新到磁盘—​这一步代价比较高。不过只要文件已经在缓存中, 就可以像其它文件一样被打开和读取了。

Figure 19. 在内存缓冲区中包含了新文档的 Lucene 索引

Lucene 允许新段被写入和打开—​使其包含的文档在未进行一次完整提交时便对搜索可见。 这种方式比进行一次提交代价要小得多,并且在不影响性能的前提下可以被频繁地执行。

Figure 20. 缓冲区的内容已经被写入一个可被搜索的段中,但还没有进行提交

refresh API

在 Elasticsearch 中,写入和打开一个新段的轻量的过程叫做 refresh 。 默认情况下每个分片会每秒自动刷新一次。这就是为什么我们说 Elasticsearch 是 实时搜索: 文档的变化并不是立即对搜索可见,但会在一秒之内变为可见。

这些行为可能会对新用户造成困惑: 他们索引了一个文档然后尝试搜索它,但却没有搜到。这个问题的解决办法是用 refresh API 执行一次手动刷新:

POST /_refresh 
POST /blogs/_refresh 

刷新(Refresh)所有的索引。

只刷新(Refresh) blogs 索引。

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

并不是所有的情况都需要每秒刷新。可能你正在使用 Elasticsearch 索引大量的日志文件, 你可能想优化索引速度而不是近实时搜索, 可以通过设置 refresh_interval , 降低每个索引的刷新频率:

PUT /my_logs
{"settings": {"refresh_interval": "30s" }
}

每30秒刷新 my_logs 索引。

refresh_interval 可以在既存索引上进行动态更新。 在生产环境中,当你正在建立一个大的新索引时,可以先关闭自动刷新,待开始使用该索引时,再把它们调回来:

PUT /my_logs/_settings
{ "refresh_interval": -1 } PUT /my_logs/_settings
{ "refresh_interval": "1s" } 

关闭自动刷新。

每秒自动刷新。

二、持久化变更

如果没有用 fsync 把数据从文件系统缓存刷(flush)到硬盘,我们不能保证数据在断电甚至是程序正常退出之后依然存在。为了保证 Elasticsearch 的可靠性,需要确保数据变化被持久化到磁盘。

​ 在动态更新索引,我们说一次完整的提交会将段刷到磁盘,并写入一个包含所有段列表的提交点。Elasticsearch 在启动或重新打开一个索引的过程中使用这个提交点来判断哪些段隶属于当前分片。

即使通过每秒刷新(refresh)实现了近实时搜索,我们仍然需要经常进行完整提交来确保能从失败中恢复。但在两次提交之间发生变化的文档怎么办?我们也不希望丢失掉这些数据。

Elasticsearch 增加了一个 translog ,或者叫事务日志,在每一次对 Elasticsearch 进行操作时均进行了日志记录。通过 translog ,整个流程看起来是下面这样:

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

    New documents are added to the in-memory buffer and appended to the transaction log

    Figure 21. 新的文档被添加到内存缓冲区并且被追加到了事务日志

  2. 刷新(refresh)使分片处于 Figure 22, “刷新(refresh)完成后, 缓存被清空但是事务日志不会”描述的状态,分片每秒被刷新(refresh)一次:

    • 这些在内存缓冲区的文档被写入到一个新的段中,且没有进行 fsync 操作。
    • 这个段被打开,使其可被搜索。
    • 内存缓冲区被清空。

    After a refresh, the buffer is cleared but the transaction log is not

    Figure 22. 刷新(refresh)完成后, 缓存被清空但是事务日志不会

  3. 这个进程继续工作,更多的文档被添加到内存缓冲区和追加到事务日志。

    The transaction log keeps accumulating documents

    Figure 23. 事务日志不断积累文档

  4. 每隔一段时间—​例如 translog 变得越来越大—​索引被刷新(flush);一个新的 translog 被创建,并且一个全量提交被执行:

    • 所有在内存缓冲区的文档都被写入一个新的段。
    • 缓冲区被清空。
    • 一个提交点被写入硬盘。
    • 文件系统缓存通过 fsync 被刷新(flush)。
    • 老的 translog 被删除。

translog 提供所有还没有被刷到磁盘的操作的一个持久化纪录。当 Elasticsearch 启动的时候, 它会从磁盘中使用最后一个提交点去恢复已知的段,并且会重放 translog 中所有在最后一次提交后发生的变更操作。

translog 也被用来提供实时 CRUD 。当你试着通过ID查询、更新、删除一个文档,它会在尝试从相应的段中检索之前, 首先检查 translog 任何最近的变更。这意味着它总是能够实时地获取到文档的最新版本。

After a flush, the segments are fully commited and the transaction log is cleared

Figure 24. 在刷新(flush)之后,段被全量提交,并且事务日志被清空

flush API

这个执行一个提交并且截断 translog 的行为在 Elasticsearch 被称作一次 flush 。 分片每30分钟被自动刷新(flush),或者在 translog 太大的时候也会刷新。它可以用来 控制这些阈值:


 flush API可以被用来执行一个手工的刷新(flush):

POST /blogs/_flush POST /_flush?wait_for_ongoing 

刷新(flush) blogs 索引。

刷新(flush)所有的索引并且并且等待所有刷新在返回前完成。

你很少需要自己手动执行 flush 操作;通常情况下,自动刷新就足够了。

这就是说,在重启节点或关闭索引之前执行 flush 有益于你的索引。当 Elasticsearch 尝试恢复或重新打开一个索引, 它需要重放 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" )来避免数据丢失。

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

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

相关文章

在Openresty中使用lua语言向请求浏览器返回请求头User-Agent里边的值

可以参考《Linux学习之Ubuntu 20.04在https://openresty.org下载源码安装Openresty 1.19.3.1,使用systemd管理OpenResty服务》安装Openresty。 然后把下边的内容写入到openresty配置文件/usr/local/openresty/nginx/conf/nginx.conf(根据实际情况进行选…

麻省理工学院与Meta AI共同开发StreamingLLM框架,实现语言模型无限处理长度

🦉 AI新闻 🚀 麻省理工学院与Meta AI共同开发StreamingLLM框架,实现语言模型无限处理长度 摘要:麻省理工学院与Meta AI的研究人员联合研发了一款名为StreamingLLM的框架,解决了大语言模型在RAM与泛化问题上的挑战&am…

Linux文件目录总结

众所周知,Linux系统文件目录是树状结构,如下图所示: 英文缩写的目录下到底存放的是什么文件,善于做归纳总结的逍遥哥哥来解释一下: /bin:bin是Binary的缩写,这个目录存放着最经常使用的命令。 …

设计模式02———建造者模式 c#

首先我们打开一个项目 在这个初始界面我们需要做一些准备工作 建基础通用包 创建一个Plane 重置后 缩放100倍 加一个颜色 更换天空盒(个人喜好) 任务:使用【UI】点击生成6种车零件组装不同类型车 【建造者模式】 首先资源商店下载车模型 将C…

用3-8译码器实现全减器

描述 请使用3-8译码器和必要的逻辑门实现全减器,全减器接口图如下,A是被减数,B是减数,Ci是来自低位的借位,D是差,Co是向高位的借位。 3-8译码器代码如下,可将参考代码添加并例化到本题答案中。 …

B端产品需求分析的思路和方法 4大方面

需求分析对产品成功和客户满意度至关重要,它帮助团队深入了解用户需求,优化用户体验,减少开发中的需求变更,降低开发风险。如果缺乏产品分析,容易造成产品定位不准确,用户体验不佳,不能满足用户…

纯干货,怎样用手机提取歌曲伴奏?

提取歌曲伴奏这个需求还是很大的,要想去掉原声只留伴奏,只要使用音分轨人声分离软件中的【音频提取伴奏】功能就能解决这个问题了,下面就给大家具体演示一下操作步骤! 第一步:打开【音分轨】APP,进入首页点…

微信小程序之本地生活(九宫格)

文章目录 一.创建项目二.配置修改json三.编写WXML四.编写WXSS五.最终效果 一.创建项目 创建新的项目&#xff0c;名称为&#xff1a;本地生活 二.配置修改json 在app.json中删除其他页面 将index改为grid 自动生成新的文件 添加自己的轮播图片 源代码&#xff1a; <!--…

【node】nodemailer配置163、qq等邮件服务指南

上一章 【node】发送邮件及附件简要使用说明 邮箱配置 参数配置参考如下&#xff1a; let transporter nodemailer.createTransport({host: smtp.qq.com,port: 465,secure: true,auth: {user: **********,pass: your-password} });邮箱服务提供商的要求&#xff0c;配置SM…

3.3 数据定义

思维导图&#xff1a; 前言&#xff1a; **核心概念**&#xff1a; - 关系数据库支持**三级模式结构**&#xff1a;模式、外模式、内模式。 - 这些模式中包括了如&#xff1a;模式、表、视图和索引等基本对象。 - SQL的数据定义功能主要包括了模式定义、表定义、视图和索引的定…

【Python】WebUI自动化—Selenium的下载和安装、基本用法、项目实战(16)

文章目录 一.介绍二.下载安装selenium三.安装浏览器驱动四.QuickStart—自动访问百度五.Selenium基本用法1.定位节点1.1.单个元素定位1.2.多个元素定位 2.控制浏览器2.1.设置浏览器窗口大小、位置2.2.浏览器前进、刷新、后退、关闭3.3.等待3.4.Frame3.5.多窗口3.6.元素定位不到…

【opencv】windows10下opencv4.8.0-cuda C++版本源码编译教程

【opencv】windows10下opencv4.8.0-cuda C版本源码编译教程 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 文章目录 【opencv】windows10下opencv4.8.0-cuda C版本源码编译教程前言准备工具cuda/cudnncmakeopencv4.8.0opencv_contrib CMake编译VS2019编…