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

相关文章

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Spring 依赖注入与循环依赖总结

《Spring依赖注入与循环依赖总结》这篇文章给大家介绍Spring依赖注入与循环依赖总结篇,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Spring 三级缓存解决循环依赖1. 创建UserService原始对象2. 将原始对象包装成工

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

MySQL中查询和展示LONGBLOB类型数据的技巧总结

《MySQL中查询和展示LONGBLOB类型数据的技巧总结》在MySQL中LONGBLOB是一种二进制大对象(BLOB)数据类型,用于存储大量的二进制数据,:本文主要介绍MySQL中查询和展示LO... 目录前言1. 查询 LONGBLOB 数据的大小2. 查询并展示 LONGBLOB 数据2.1 转换为十

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字