ES读写数据过程及原理
倒排索引
首先来了解一下什么是
倒排索引,就是建立词语与文档的对应关系(词语在什么文档出现,出现了多少次,在什么位置出现)
搜索的时候,根据搜索关键词,直接在索引中找到对应关系,搜索速度快。
doc:表示哪个文档,
frep:表示出现的频率
pos:表示出现的位置
1、写数据过程
-
客户端通过hash选择一个node发送请求,这个node被称做coordinating node(协调节点),
-
协调节点对docmount进行路由,将请求转发给到对应的primary shard
-
primary shard 处理请求,将数据同步到所有的replica shard
-
此时协调节点,发现primary shard 和所有的replica shard都处理完之后,就反馈给客户端。
2、写数据的底层原理
-
在到达primary shard的时候 ,数据先写入内存buffer , 此时,在buffer里的数据是不会被搜索到的同时生成一个translog日志文件 , 将数据写入translog里
-
如果内存buffer空间快man满了,就会将数据refresh到一个新的segment file文件中,而且es里每隔1s就会将buffer里的数据写入到一个新的segment file中,这个segment file就存储最最近1s中buffer写入的数据,如果buffer里面没有数据,就不会执行refresh操作,当建立segment file文件的时候,就同时建立好了倒排索引库。
-
在buffer refresh到segment之前 ,会先进入到一个叫os cache中,只要被执行了refresh操作,就代表这个数据可以被搜索到了。数据被输入os cache中,buffer就会被清空了,所以为什么叫es是准实时的?NRT,near real-time,准实时。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。还可以通过es的restful api或者java api,手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到。
-
就这样新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去,每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发commit操作。translog也是先进入os cache中,然后每隔5s持久化到translog到磁盘中,
-
commit操作,第一步,就是将buffer中现有数据refresh到os cache中去,清空buffer 每隔30分钟flush
-
es也有可能会数据丢失 ,有5s的数据停留在buffer、translog os cache, segment file os cache中,有5s的数据不在磁盘上,如果此时宕机,这5s的数据就会丢失,如果项目要求比较高,不能丢失数据,就可以设置参数,每次写入一条数据写入buffer,同时写入translog磁盘文件中,但这样做会使es的性能降低。
-
如果是删除操作,commit操作的时候就会生成一个.del文件,将这个document标识为deleted状态,在搜索的搜索的时候就不会被搜索到了。
-
如果是更新操作,就是将原来的document标识为deleted状态,然后新写入一条数据
-
buffer每次refresh一次,就会产生一个segment file,所以默认情况下是1秒钟一个segment file,segment file会越来越多,当躲到一定程度的时候,es就会自动触发merge(合并)造作,将所有segment file文件 merge成一个segment file,并同时物理删除掉标识为deleted的doc,
3、es读取过程
-
客户端发送get请求到任意一个node节点,然后这个节点就称为协调节点,
-
协调节点对document进行路由,将请求转发到对应的node,此时会使用随机轮询算法,在primary shard 和replica shard中随机选择一个,让读取请求负载均衡,
-
接收请求的node返回document给协调节点,
-
协调节点,返回document给到客户端
4、 搜索过程
-
客户端发送请求到协调节点,
-
协调节点将请求大宋到所有的shard对应的primary shard或replica shard ;
-
每个shard将自己搜索到的结果返回给协调节点,返回的结果是dou.id或者自己自定义id,然后协调节点对数据进行合并排序操作,最终得到结果。
-