es写入和查询的工作原理

es写数据过程

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

2)coordinating node,对document进行路由(document会自动给你分配一个全局唯一的doc id,根据doc id进行hash路由到对应的primary shard上面去。也可以手动指定doc id,比如用订单id,用户id),将请求转发给对应的node(有primary shard)

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

4)coordinating node,如果发现primary node和所有replica node都搞定之后,就返回响应结果给客户端

写数据底层原理

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

2)如果buffer快满了,或者到一定时间(默认1秒),就会将buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入磁盘,而是先进入os cache(操作系统级别的一个内存缓存)。refresh之后写入的数据即可被搜索到,这个也就叫做准实时--NRT(refresh对应solr的soft commit)数据被refresh到os cache中,buffer就被清空了

3)重复以上步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segment file中去。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发commit操作。(对应solr的hard commit)

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

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

6)强行将os cache中目前所有的数据都fsync到磁盘文件中去

translog日志文件的作用是什么?

在执行commit操作之前,数据要么是在buffer中,要么是在os cache中,无论是buffer还是os cache都是内存,一旦这台机器死了,内存中的数据就全丢了。所以需要将数据对应的操作写入translog日志文件中,一旦此时机器宕机,再次重启的时候,es会自动读取translog日志文件中的数据,恢复到内存buffer和os cache中去。

7)然后将现有的translog清空,再次创建一个新的translog,此时commit操作完成。默认每隔30分钟执行一次commit,但是如果translog过大,也会触发commit。整个commit的过程,叫做flush操作。我们可以手动执行flush操作,就是将所有os cache数据刷到磁盘文件中去。我们也可以通过es api,手动执行flush操作,手动将os cache中的数据fsync强刷到磁盘上去,记录一个commit point,清空translog日志文件。

8)translog其实也是先写入os cache的,默认每隔5秒刷一次到磁盘中去,所以默认情况下,可能有5秒的数据会仅仅停留在buffer或者translog文件的os cache中,如果此时机器挂了,会丢失5秒钟的数据。但是这样性能比较好,最多丢5秒的数据。如果要求不能丢失数据的话,可以将translog设置成每次写操作必须是直接fsync到磁盘,但是这会导致写性能、写入吞吐量会下降一个数量级。本来一秒钟可以写2000条,现在你一秒钟只能写200条,都有可能。

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

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

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

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


 es读数据过程

查询,GET某一条数据,你可以通过doc id来查询,会根据doc id进行hash,判断出来当时把doc id分配到了哪个shard上面去,从那个shard去查询

1)客户端发送请求到任意一个node,成为coordinate node
2)coordinate node对document进行路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primary shard以及其所有replica中随机选择一个,让读请求负载均衡
3)接收请求的node返回document给coordinate node
4)coordinate node返回document给客户端

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数据,最终返回给客户端

原文地址:https://www.cnblogs.com/zz-ksw/p/12434753.html