ES底层数据存储原理

小丫2年前技术文章1703

1、ES底层数据存储原理架构图


image.png

Segment工作流程:

A、 新的文档在内存中组织

B、 每隔一段时间,buffer将会被提交:生成一个新的segment(一个额外的新的倒序索引)并被写到磁盘,同时一个新的提交点(commit point)被写入磁盘,包含新的segment的名称。磁盘fsync,所有在内核文件系统中的数据等待被写入到磁盘,来保障它们被物理写入。

C、 新的segment被打开,使它包含的文档可以被索引

D、内存中的buffer将被清理,准备接收新的文档。


2、索引存储的“不变性”原则(优点与限制)

       写到磁盘的倒排索引时不变的

        优点:

·        不需要添加锁。不存在写操作,因此不存在多线程更改数据。

·        提高读性能。一旦索引被内核的文件系统做了Cache,绝大多数的读操作会直接从内存而不需要经过磁盘。

·        提升其他缓存(例如fiter cache)的性能。其他的缓存在该索引的生命周期内保持有效,减少磁盘I/O和计算消耗。

限制:

·        修改字段类型,删除字段操作就需要重新构建整个索引

·        一个index可以容纳的数据量受限

·        一个索引可以更新的频率受限


3、细节原理分析

A、删除和更新

    segments是不变的,所以文档不能从旧的segments中删除,也不能在旧的segments中更新来映射一个新的文档版本。取之的是,每一个提交点都会包含一个.del文件,列举了哪一个segmen的哪一个文档已经被删除了。 当一个文档被删除了,它仅仅是在.del文件里被标记了一下。被删除的文档依旧可以被索引到,但是它将会在最终结果返回时被移除掉。

文档的更新同理:当文档更新时,旧版本的文档将会被标记为删除,新版本的文档在新的segment中建立索引。新旧版本的文档都会被检索到,但是旧版本的文档会在最终结果返回时被移除。

B、实时索引

       per-segment搜索的机制下,新的文档会在分钟级内被索引,但是还不够快。 瓶颈在磁盘。将新的segment提交到磁盘需要fsync来保障物理写入。但是fsync是很耗时的。它不能在每次文档更新时就被调用,否则性能会很低。 现在需要一种轻便的方式能使新的文档可以被索引,这就意味着不能使用fsync来保障。 ES和物理磁盘之间是内核的文件系统缓存。之前的描述中,在内存中索引的文档会被写入到一个新的segment。但是现在我们将segment首先写入到内核的文件系统缓存,这个过程很轻量,然后再flush到磁盘,这个过程很耗时。但是一旦一个segment文件在内核的缓存中,它可以被打开被读取。

 

C、更新持久化

      不使用fsync将数据flush到磁盘,我们不能保障在断电后或者进程死掉后数据不丢失。ES是可靠的,它可以保障数据被持久化到磁盘。一个完全的提交会将segments写入到磁盘,并且写一个提交点,列出所有已知的segments。当ES启动或者重新打开一个index时,它会利用这个提交点来决定哪些segments属于当前的shard 如果在提交点时,文档被修改会怎么样?

translog日志提供了一个所有还未被flush到磁盘的操作的持久化记录。当ES启动的时候,它会使用最新的commit point从磁盘恢复所有已有的segments,然后将重现所有在translog里面的操作来添加更新,这些更新发生在最新的一次commit的记录之后还未被fsync

translog日志也可以用来提供实时的CRUD。当你试图通过文档ID来读取、更新、删除一个文档时,它会首先检查translog日志看看有没有最新的更新,然后再从响应的segment中获得文档。这意味着它每次都会对最新版本的文档做操作,并且是实时的。

       D、Segment合并

    通过每隔一秒的自动刷新机制会创建一个新的segment,用不了多久就会有很多的segmentsegment会消耗系统的文件句柄,内存,CPU时钟。最重要的是,每一次请求都会依次检查所有的segmentsegment越多,检索就会越慢。

ES通过在后台merge这些segment的方式解决这个问题。小的segment merge到大的,大的merge到更大的。。。

这个过程也是那些被删除的文档真正被清除出文件系统的过程,因为被标记为删除的文档不会被拷贝到大的segment中。

4、索引读写

image.png

1.    索引过程:

1) 有一系列被索引文件

2) 被索引文件经过语法分析和语言处理形成一系列词(Term)

3) 经过索引创建形成词典和反向索引表。

4) 通过索引存储将索引写入硬盘。

2.    搜索过程:

a) 用户输入查询语句。

b) 对查询语句经过语法分析和语言分析得到一系列词(Term)

c) 通过语法分析得到一个查询树。

d) 通过索引存储将索引读入到内存。

e) 利用查询树搜索索引,从而得到每个词(Term) 的文档链表,对文档链表进行交,差,并得到结果文档。

f) 将搜索到的结果文档对查询的相关性进行排序。

g) 返回查询结果给用户。


相关文章

用了函数就无法使用索引?MySQL函数索引值得你拥有

MySQL中的索引,就像图书馆里的索引卡片,帮我们快速定位到想要的信息。但是,如果你对这些卡片动了点“手脚”,比如用个函数来“改造”一下索引字段,那么这些卡片可能就不再那么有效了,查找起来就得费劲多了...

minio存储桶命名规则

存储桶命名规则创建S3存储桶后,无法更改存储桶名称,因此请明智地选择名称。重要在2018年3月1日,我们更新了美国东部(弗吉尼亚北部)地区S3存储桶的命名约定,以匹配我们在所有其他全球AWS区域中使用...

开源大数据集群部署(十七)HADOOP集群配置(二)

开源大数据集群部署(十七)HADOOP集群配置(二)

1 HADOOP集群配置配置文件workers[root@hd1.dtstack.com software]# cd /opt/hadoop/etc/hadoop [root@hd1.dtstack...

DBMS_SESSION包跟踪10046

注意:DBMS_SESSION包:只能跟踪当前会话,不能指定会话DBMS_SESSION.SET_SQL_TRACE=ALTER SESSION SET SQL_TRACE; =ALTER SESSI...

MySQL 自增列使用上的一些 “坑”

MySQL 自增列使用上的一些 “坑”

前言MySQL 的规范中,一般都会建议表要有主键,常使用自增列作为主键字段,这和 MySQL 属于聚簇索引表有关,顺序增长的主键比较合适。最近有研发咨询,为什么有张表的自增主键变的非常大?而且偶尔还出...

开源大数据集群部署(十四)Ranger集成Hbase

开源大数据集群部署(十四)Ranger集成Hbase

在hd1.dtstack.com主机上执行在hmaster和back master上进行安装和执行Ø 解压ranger-2.3.0-hbase-plugin[root@hd1.dtstack.com ...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。