ElasticSearch 集群分片内部原理
时间:2022-07-26
本文章向大家介绍ElasticSearch 集群分片内部原理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
公众号:码农架构
分片内部原理
- 分片是如何工作的
- 为什么ES搜索是近实时性的
- 为什么CRUD 操作也是实时性
- ES 是怎么保证更新被持久化时断电也不丢失数据
- 为什么删除文档不会立即释放空间
- refresh, flush, 和 optimize API 作用
- 使文本可被搜索 倒排索引的结构 词项 文档列表 Term | Doc 1 | Doc 2 | Doc 3 | ... brown | X | | X | ... fox | X | X | X | ... quick | X | X | | ... the | X | | X | ...
- 倒排索引的不变性
- 不需要锁
- 可被内核的文件系统缓存,停留在内存中,大部分请求会直接请求到内存,不会落到磁盘上
- filter缓存,在索引的生命周期始终有效。不需要再每次数据改变时重建
- 写入单个较大的倒排索引使允许数据被压缩
- 如何在索引不变情况下 动态更新索引
- 使用更多的索引,来解决这个问题
- 通过增加新的补充索引来反映新近的修改,而不是直接重写整个倒排索引
- 一个 Lucene 索引包含一个提交点和三个段
- 逐段搜索的流程
- 新文档被收集到内存索引缓存
- 不时地, 缓存被 提交
- 一个新的段----一个追加的倒排索引--被写入磁盘
- 一个新的包含新段名字的 提交点 被写入磁盘
- 磁盘进行 同步 — 所有在文件系统缓存中等待的写入都刷新到磁盘
- 新的段被开启,让它包含的文档可见以被搜索
- 内存缓存被清空,等待接收新的文档
- 一个在内存缓存中包含新文档的 Lucene 索引
- 在一次提交后,一个新的段被添加到提交点而且缓存被清空
- 删除和更新文档
- 段是不可改变的,每个提交点都会有一个.del文件。在这个文件中能列出这些删除文档的短信息
- 当文档被删除时不是删除,只是在.del文件中被登记
- 文档的更新也是这样的,先将更新的文档标记为删除。然后文档的新版本被索引到一个新的段中
近实时搜索
- 提交(Commiting)一个新的段到磁盘需要一个 fsync 来确保段被物理性地写入磁盘,这样在断电的时候就不会丢失数据。但是每次提交的一个新的段都fsync 这样操作代价过大。可以使用下面这种更轻量的方式
- 在内存缓冲区中包含了新文档的 Lucene 索引
- Lucene 允许新段被写入和打开--使其包含的文档在未进行一次完整提交时便对搜索可见
- 缓冲区的内容已经被写入一个可被搜索的段中,但还没有进行提交
- 这里新段会被先写入到文件系统缓存--这一步代价会比较低,稍后再被刷新到磁盘--这一步代价比较高
- 默认情况下每个分片会每秒自动刷新一次
- 近 实时搜索: 文档的变化并不是立即对搜索可见,但会在一秒之内变为可见
- POST /_refresh // 刷新Refresh 所有的索引
- POST /blogs/_refresh // 只刷新Refresh blogs 索引 可以在settings 设置对定时刷新频率的大小
PUT /my_logs
{
"settings": {
"refresh_interval": "30s" //30秒刷新一次
"refresh_interval": "-1" //关闭自动刷新
"refresh_interval": "1s"//每秒自动刷新
}
}
持久化变更
在没有 fsync 把数据从内存刷新到硬盘中,我们不能保证数据在断电或程序退出时之后依然存在
- 即时每秒刷新,也不能实现近实时搜索。我们任然有另外的方法确保从失败中回复数据
- ES 增加一个translog,或者叫做事务日志。在每次操作是均进行日志记录
- 整个流程是如下的操作
- 一个文档被索引之后,就会被添加到内存缓冲区,并且 追加到了 translog -
- 刷新(refresh)使分片处于缓存被清空,但是事务日志不会的状态
- 内存缓冲区的文档被写入新的段中,但是没有进行fsync
- 段被打开,且可被搜索到
- 内存缓冲区被清空
- 进程继续进行,更多的文档被添加到内存缓冲区和追加的事务日志中
- 每隔一段时间,translog太大 或 索引被刷新。一个新的translog被创建,并且被全量提交 -
- translog 提供所有没有被刷新到磁盘操作的一个持久化记录。当ES启动时,会根据最后一个提交点去恢复已知的段
- translog 也可供用来提供实时的CRUD。但我们进行一些CRUD操作时,它会首先检查translog任何最近的变更。
-
flush API ** 执行一次提交,并截断translog**的操作
- 分片默认每30M自动flush一次。translog太大也会自动flush
- 可通过自己执行flush API操作 POST /blogs/_flush //刷新索引 POST /_flush?wait_for_ongoing //刷新索引并等待所有的刷新结果返回
段合并
- 段合并的时候会将那些旧的已删除的文档从文件系统中删除,被删除或者被更新的文档不会被复制到新的大段中
- 段合并的流程 -
- optimized API 的作用
- optimize API大可看做是 强制合并 API 。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Java学习笔记, 不断更新
- 这题真是送分——LeetCode题目12:整数转罗马数字
- 该了解一波了!零基础入门Nginx
- 轻松一刻——LeetCode题目13:罗马数字转整数
- 动动手——LeetCode题目14:最长公共前缀
- LeetCode题目15:三数之和
- 三数之和姊妹题——LeetCode题目16:最接近的三数之和
- 组合问题——LeetCode题目17:电话号码的字母组合
- Python读取PDF文档并翻译
- n数之和题目要类比——LeetCode题目18:四数之和
- SpringBoot使用MySQL访问数据
- MySQL数据库与JDBC编程
- 自动删除QQ空间指定好友的留言
- 在Ubuntu 18.04中安装VMware工具
- 微信小程序下拉刷新功能