elasticsearch读写流程原理

                                  ES进阶学习之读写流程原理

今天小编来带大家学习一下es的读写工作流程及其原理

不多说,进入正题 

elasticsearch读写流程原理_第1张图片

 注:以下所有文字描述对照上图理解更加具体!!

es读工作流程

先说这个读的流程吧,是这样的,首先呢,在Es集群中,获取数据分为查询和搜索,查询:GET某一条数据,当你写入了某个document的时候,这个document会给你自动分配一个id doc id,当然这个docid我们也可以在写入doc的时候手动指定这个docid,然后查询的时候通过docid去进行查询, 也就是根据doc id进行hash路由到一个随机的shard节点上,这个时候它就作为协调节点,他会根据这个docid去查询到这个doc在哪个节点上,因为我们知道读的话,shard和replica都可以去读,这时候就采用随机轮询的算法,让客户端在shard和replica中随机进行读取,读取完后,接受请求的协调节点对数据进行返回

 

搜索:同样,客户端发送一个请求到一个协调节点上,因为不知道doc的id,不知道数据存在哪里,这个时候呢,就会将搜索的请求转发到所有的shard对应的primary shard或replica shard上,比如我有三个shard也就意味着我有三个replica,因为是读,所以,转发到三个节点上对应的shard或replica上就可以了,然后,每个shard将自己的搜索的结果其实就是通过内容查询出来和请求内容相关的doc id(通过倒排索引)返回给协调节点,比如说我现在搜索的是java,它就会进行对比,进行判断,把带有java的这些内容的docid返回给协调节点,这时候协调节点就会收到类似于“java真好”,“java真不好”的这些doc 的id,最后再由协调节点去拉去到此docid所对应的document的完整的数据拉取回来,然后进行数据的合并,排序,分页等操作,产出最终的结果,然后由协调节点返回给客户端

 

es的写流程

是这样的啊,其实是首先会对你要写的这条数进行hash,然后随机分发到一个节点,去执行写操作,然后呢,就是说,通过hash路由到这个节点之后,数据首先写到一个buffer中(缓冲区),这时候,是搜索不到数据的,只有等1秒后,数据会从buffer中refresh到一个新的segmentfile中并持久化到磁盘。

如果buffer快满的时候,也会将里面的数据存储到segmentfile中,清空buffer,其实并非将segmentfile持久化到磁盘需要一秒时间,而是首先会将segmentfile写入os cache中,注:os cache(操作系统的内存),然后再将segmentfile持久化到磁盘中,写入oscache的同时,建立倒排索引,这时就可以供客户端进行访问了,这就是为什么说es是准实时的了,默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到,当然我们可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。

还有一个概念,就是translog,每写入一条数据,就会写入一条translog到os cache中去,每个五秒就会持久化一条translog日志文件到磁盘中去,这是为了防止电脑突然卡住,或者突然宕机造成的数据丢失问题(内存中的数据还没来的及持久化,就宕机了),如果出现这种情况,这时候,重启机器,就会读取translog到buffer和oscache中进行数据的恢复了,但是每次一条数据写入buffer,同时会写入一条日志到translog日志文件中去,所以这个translog日志文件是不断变大的。

当translog日志文件大到一定程度的时候,就会执行commit操作(整个commit的过程叫做flush操作),commit操作发生第一步,就是将buffer中现有数据refresh到os cache中去,然后将commit point这个文件持久化到磁盘中,这个文件记录了,这个时间点之前,你刷到os cache的所有的segmentfile,清空buffer 然后强行将os cache中所有的数据全都一个一个的通过segmentfile的形式,持久到磁盘上去,然后把translog文件删掉清空,再开一个空的translog文件,而且translog是默认30分钟执行一次flush,一般我们不叫作commit操作,只是类似于一个提交的操作,我把它理解为commit,在es中的flush操作,就对应着commit的全过程。我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件

translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。也可以将translog设置成每次写操作必须是直接fsync到磁盘,但是性能会差很多

 

删除更新的原理

如果每一次删除,都需要从集群中找到存储那个数据的节点在进行删除,那么效率就太低了吧?

Es是这么操作的:如果是删除请求的话,提交的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了,客户端搜索的时候,发现数据在.del文件中标志为删除就不会搜索出来了,

如果是更新操作,就是将原来的doc标识为deleted状态,然后重新写入一条数据。

那么这并不是一个物理删除,那么物理删除实在什么时候呢?

其实啊,在es中还有一个概念就是mege(合并)

buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,此时会定期执行merge

每次merge的时候,会将多个segment file合并成一个,同时这里会将标识为deleted的doc给物理删除掉,然后将新的segment file写入磁盘,这里会写一个commit point,标识所有新的segment file,然后打开segment file供搜索使用,同时删除旧的segment file

 

说到这里es里的写流程,有4个底层的核心概念,refresh、flush、translog、merge综上所述,大家好好去理解!!

你可能感兴趣的:(elasticsearch读写流程原理)