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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu