面试系列八 es写入数据的工做原理

(1)es写数据过程java

 

1)客户端选择一个node发送请求过去,这个node就是coordinating node(协调节点)node

2)coordinating node,对document进行路由,将请求转发给对应的node(有primary shard)面试

3)实际的node上的primary shard处理请求,而后将数据同步到replica node算法

4)coordinating node,若是发现primary node和全部replica node都搞定以后,就返回响应结果给客户端数据库

 

(2)es读数据过程api

 

查询,GET某一条数据,写入了某个document,这个document会自动给你分配一个全局惟一的id,doc id,同时也是根据doc id进行hash路由到对应的primary shard上面去。也能够手动指定doc id,好比用订单id,用户id。缓存

 

你能够经过doc id来查询,会根据doc id进行hash,判断出来当时把doc id分配到了哪一个shard上面去,从那个shard去查询restful

 

1)客户端发送请求到任意一个node,成为coordinate node负载均衡

2)coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其全部replica中随机选择一个,让读请求负载均衡性能

3)接收请求的node返回document给coordinate node

4)coordinate node返回document给客户端

 

(3)es搜索数据过程

 

es最强大的是作全文检索,就是好比你有三条数据

 

java真好玩儿啊

java好难学啊

j2ee特别牛

 

你根据java关键词来搜索,将包含java的document给搜索出来

 

es就会给你返回:java真好玩儿啊,java好难学啊

 

1)客户端发送请求到一个coordinate node

2)协调节点将搜索请求转发到全部的shard对应的primary shard或replica shard也能够

3)query phase:每一个shard将本身的搜索结果(其实就是一些doc id),返回给协调节点,由协调节点进行数据的合并、排序、分页等操做,产出最终结果

4)fetch phase:接着由协调节点,根据doc id去各个节点上拉取实际的document数据,最终返回给客户端

 

(4)搜索的底层原理,倒排索引,画图说明传统数据库和倒排索引的区别

 

(5)写数据底层原理

 

1)先写入buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件

 

2)若是buffer快满了,或者到必定时间,就会将buffer数据refresh到一个新的segment file中,可是此时数据不是直接进入segment file的磁盘文件的,而是先进入os cache的。这个过程就是refresh。

 

每隔1秒钟,es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件,segment file,这个segment file中就存储最近1秒内buffer中写入的数据

 

可是若是buffer里面此时没有数据,那固然不会执行refresh操做咯,每秒建立换一个空的segment file,若是buffer里面有数据,默认1秒钟执行一次refresh操做,刷入一个新的segment file中

 

操做系统里面,磁盘文件其实都有一个东西,叫作os cache,操做系统缓存,就是说数据写入磁盘文件以前,会先进入os cache,先进入操做系统级别的一个内存缓存中去

 

只要buffer中的数据被refresh操做,刷入os cache中,就表明这个数据就能够被搜索到了

 

为何叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,因此es是准实时的,由于写入的数据1秒以后才能被看到。

 

能够经过es的restful api或者java api,手动执行一次refresh操做,就是手动将buffer中的数据刷入os cache中,让数据立马就能够被搜索到。

 

只要数据被输入os cache中,buffer就会被清空了,由于不须要保留buffer了,数据在translog里面已经持久化到磁盘去一份了

 

3)只要数据进入os cache,此时就可让这个segment file的数据对外提供搜索了

 

4)重复1~3步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推动,translog会变得愈来愈大。当translog达到必定长度的时候,就会触发commit操做。

 

buffer中的数据,却是好,每隔1秒就被刷到os cache中去,而后这个buffer就被清空了。因此说这个buffer的数据始终是能够保持住不会填满es进程的内存的。

 

每次一条数据写入buffer,同时会写入一条日志到translog日志文件中去,因此这个translog日志文件是不断变大的,当translog日志文件大到必定程度的时候,就会执行commit操做。

 

5)commit操做发生第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer

 

6)将一个commit point写入磁盘文件,里面标识着这个commit point对应的全部segment file

 

7)强行将os cache中目前全部的数据都fsync到磁盘文件中去

 

translog日志文件的做用是什么?就是在你执行commit操做以前,数据要么是停留在buffer中,要么是停留在os cache中,不管是buffer仍是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。

 

因此须要将数据对应的操做写入一个专门的日志文件,translog日志文件中,一旦此时机器宕机,再次重启的时候,es会自动读取translog日志文件中的数据,恢复到内存buffer和os cache中去。

 

commit操做:一、写commit point;二、将os cache数据fsync强刷到磁盘上去;三、清空translog日志文件

 

8)将现有的translog清空,而后再次重启启用一个translog,此时commit操做完成。默认每隔30分钟会自动执行一次commit,可是若是translog过大,也会触发commit。整个commit的过程,叫作flush操做。咱们能够手动执行flush操做,就是将全部os cache数据刷到磁盘文件中去。

 

不叫作commit操做,flush操做。es中的flush操做,就对应着commit的全过程。咱们也能够经过es api,手动执行flush操做,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件。

 

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

 

实际上你在这里,若是面试官没有问你es丢数据的问题,你能够在这里给面试官炫一把,你说,其实es第一是准实时的,数据写入1秒后能够搜索到;可能会丢失数据的,你的数据有5秒的数据,停留在buffer、translog os cache、segment file os cache中,有5秒的数据不在磁盘上,此时若是宕机,会致使5秒的数据丢失。

 

若是你但愿必定不能丢失数据的话,你能够设置个参数,官方文档,百度一下。每次写入一条数据,都是写入buffer,同时写入磁盘上的translog,可是这会致使写性能、写入吞吐量会降低一个数量级。原本一秒钟能够写2000条,如今你一秒钟只能写200条,都有可能。

 

10)若是是删除操做,commit的时候会生成一个.del文件,里面将某个doc标识为deleted状态,那么搜索的时候根据.del文件就知道这个doc被删除了

 

11)若是是更新操做,就是将原来的doc标识为deleted状态,而后新写入一条数据

 

12)buffer每次refresh一次,就会产生一个segment file,因此默认状况下是1秒钟一个segment file,segment file会愈来愈多,此时会按期执行merge

 

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

 

es里的写流程,有4个底层的核心概念,refresh、flush、translog、merge

 

当segment file多到必定程度的时候,es就会自动触发merge操做,将多个segment file给merge成一个segment file。

相关文章
相关标签/搜索