ES底层数据存储原理

小丫2年前技术文章1468

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) 返回查询结果给用户。


相关文章

Impala 操作命令

Impala 操作命令

Impala的外部shell选项描述-h, --help显示帮助信息-v or --version显示版本信息-i hostname, --impalad=hostname 指定连接运行 impala...

HDP部署Tez UI

首先部署tomcat在官网下载apache-tomcat-9.0.22.tar.gz[root@hdp02 opt]# wget https://archive.apache.org/dist/tom...

EMR-flinksql运行失败问题

EMR-flinksql运行失败问题

运行flinksqlsql-client.sh报错:[root@emr1 bin]# ./sql-client.shSLF4J: Class path contains multiple SLF4J...

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

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

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

手动模拟 CNI 网络中 host-gw 模式互通

手动模拟 CNI 网络中 host-gw 模式互通

在Kubernetes中,CNI的作用就是让两台Node节点之间的Pod能够互相通信,其中有封包的方式,也有路由转发的方式,host-gw就是路由转发的方式。host-gw 模式介绍host-gw模式...

Kubernetes源码解读(六)-- Informer源码分析

Kubernetes源码解读(六)-- Informer源码分析

Informer 这个词的出镜率很高,我们在很多文章里都可以看到 Informer 的身影,但是我们在源码里真的去找一个叫做 Informer 的对象,却又发现找不到一个单纯的 Informer,但是...

发表评论    

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