elasticsearch内部原理自我总结

2024-08-27 16:18

本文主要是介绍elasticsearch内部原理自我总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

环境

elasticsearch:5.5

自我理解

对于elasticsearch我自己也是新手,只是想做点笔记,记录下自己的理解。

我一直想明白当一个文档被索引进elasticsearch时,其内部干什么了?
本人结合网上的教程,记录下

倒排索引

一个新文档要使其可见,需要使用倒排索引,其长相如下:

词项文档1文档2文档3
中国XX
小米XXX
华为XX
南昌XX

有了倒排索引之后,新进的文档就可以被搜索到了。

注意:倒排索引被写入磁盘后是 不可改变 的:它永远不会修改。 不变性有重要的价值

①不需要锁。如果你从来不更新索引,你就不需要担心多进程同时修改数据的问题。
② 一旦索引被读入内核的文件系统缓存,便会留在哪里,由于其不变性。只要文件系统缓存中还有足够的空间,那么大部分读请求会直接请求内存,而不会命中磁盘。这提供了很大的性能提升。
③其它缓存(像filter缓存),在索引的生命周期内始终有效。它们不需要在每次数据改变时被重建,因为数据不会变化。
④写入单个大的倒排索引允许数据被压缩,减少磁盘 I/O 和 需要被缓存到内存的索引的使用量。
当然,一个不变的索引也有不好的地方。主要事实是它是不可变的! 你不能修改它。如果你需要让一个新的文档 可被搜索,你需要重建整个索引。这要么对一个索引所能包含的数据量造成了很大的限制,要么对索引可被更新的频率造成了很大的限制。

动态更新(倒排)索引

由于倒排索引具有不变性(一旦被写入磁盘就不能再改变),那么我们如何来实现更新倒排索引呢?官方的做法就是用更多的倒排索引。通过增加新的倒排索引来反应新近的修改,而不是重写整个倒排索引,毕竟重写整个倒排索引,要消耗巨大资源;每一个倒排索引都会被轮流查询到–从最早的开始–查询完后再对结果进行合并。

如果一个新文档立马就写入磁盘也会影响性能,所以新的文档首先被添加到内存索引缓存中,然后写入基于磁盘的段中,接着包含这个新段的提交点也会被写入磁盘,接着磁盘同步,把文件系统缓存中的文档刷新到磁盘,接着新段被打开,使其可以被搜索到,接着内存索引缓存被清空,等待接受新的文档。

这里写图片描述

注意

段其实就是倒排索引,其不能被改变。当文档发生改变时,每个提交点会包含一个.del文件,文件中会列出这些被删除文档的段信息。所以文档被删除时,并不会立马被删除,只是被标记了,其依然可以被搜索到,只不过在结果集返回前就已经移除了。

这里有一个新的问题就是磁盘同步是一件很消耗资源的事情,如果每次插入一个文档都去执行的话,就会造成很大的性能问题。这意味着我们再插入新文档时,不能立马就进行同步。

我们要知道在Elasticsearch和磁盘之间是文件系统缓存。
新文档 写入 内存索引缓存中,接着会写入到新段上,重点来了,这个新段不会直接写入磁盘而是先写入到文件系统缓存中,稍后才会写入到磁盘。只要文件已经在缓存中,就可以像其他文件一样被打开和读取了。

这里写图片描述

refresh

elasticsearch中,写入和打开一个新段(倒排索引)的轻量的过程叫做refresh。也就是把内存索引缓存中的数据写到新段的一个过程。由于elasticsearch默认每个分片是每秒自动刷新一次。这就造成其索引是近实时搜索而不是实时搜索。最长需要等待1秒。

目前处于性能考虑,我们文档还放在文件系统缓存中,如果不进行同步到磁盘的话,假设断电了,数据就丢失了。而由于上面也说明,同步不是实时的,是每个一段时间同步一次,默认是30分钟一次。假设elasticsearch9点同步过了,下次需要在9点半同步,而此时刚好断电了,这时内存里的数据就全部丢失了。但是我们又不想丢失掉。所以elasticsearch引入了translog或者叫事务日志。

那么其最终的流程就变成了:

1、一个文档被索引(插入)后,就会被添加到内存缓存区,并且追加到translog
2、分片默认是每秒刷新一次;即把内存缓存区里的数据刷新写入到新段中(文件系统缓存中),此时没有进行fsync(磁盘同步)。
3、这个新段会被打开并且使其可被搜索。
4、内存缓存区被清空。
5、这个进程会继续工作,更多的文档被添加进内容缓存区和追加事务日志。
6、这也就意味着每隔一段时间translog会变得越来越大。这时(倒排)索引被flush;与此同时一个新translog会被创建,并且一个全量提价被执行:
①所有在内存缓存区的文档都被写入到新段。
②缓存区被清空
③一个提交点被写入硬盘
④文件系统缓存通过fsync被刷新(flush
⑤老的translog被删除

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

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

flush

translog进行截断并进行提交的行为在elasticsearch中称作flush。分片每30分钟被自动刷新(flush),或者在 translog 太大的时候也会刷新。请查看 translog 文档 来设置,它可以用来 控制这些阈值。


这时其实还有个小问题,要是translog在断电之前还没有写入磁盘,这时,数据照样还是会丢失。默认情况下translog是每5秒fsync到磁盘或者在每次写请求完成之后。对于这种情况,官方说明:但是对于一些大容量的偶尔丢失几秒数据问题也并不严重的集群,使用异步的 fsync 还是比较有益的。


由于自动刷新refresh每秒创建一个段,这样就会造成短时间内,段数量暴增。而段数目太多会带来较大的麻烦。 每一个段都会消耗文件句柄、内存和cpu运行周期。更重要的是,每个搜索请求都必须轮流检查每个段;所以段越多,搜索也就越慢。
Elasticsearch通过在后台进行段合并来解决这个问题。小的段被合并到大的段,然后这些大的段再被合并到更大的段。

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

启动段合并不需要你做任何事。进行索引和搜索时会自动进行。
1、 当索引的时候,刷新(refresh)操作会创建新的段并将段打开以供搜索使用。
2、 合并进程选择一小部分大小相似的段,并且在后台将它们合并到更大的段中。这并不会中断索引和搜索。

合并完成时的活动:

  • 新的段被刷新到了磁盘。
  • 写入一个提交点,该提交点包含新段且排除旧的和较小的段
  • 新的段被打开用来搜索
  • 老的段被删除

合并大的段需要消耗大量的I/O和CPU资源,如果任其发展会影响搜索性能。Elasticsearch在默认情况下会对合并流程进行资源限制,所以搜索仍然 有足够的资源很好地执行。

参考地址:
https://www.elastic.co/guide/cn/elasticsearch/guide/cn/merge-process.html
https://www.elastic.co/guide/en/elasticsearch/guide/current/making-text-searchable.html

这篇关于elasticsearch内部原理自我总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1112160

相关文章

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

MySQL中的表连接原理分析

《MySQL中的表连接原理分析》:本文主要介绍MySQL中的表连接原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、表连接原理【1】驱动表和被驱动表【2】内连接【3】外连接【4编程】嵌套循环连接【5】join buffer4、总结1、背景

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java Stream的distinct去重原理分析

《JavaStream的distinct去重原理分析》Javastream中的distinct方法用于去除流中的重复元素,它返回一个包含过滤后唯一元素的新流,该方法会根据元素的hashcode和eq... 目录一、distinct 的基础用法与核心特性二、distinct 的底层实现原理1. 顺序流中的去重

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

SQL中JOIN操作的条件使用总结与实践

《SQL中JOIN操作的条件使用总结与实践》在SQL查询中,JOIN操作是多表关联的核心工具,本文将从原理,场景和最佳实践三个方面总结JOIN条件的使用规则,希望可以帮助开发者精准控制查询逻辑... 目录一、ON与WHERE的本质区别二、场景化条件使用规则三、最佳实践建议1.优先使用ON条件2.WHERE用

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意