面试题
ES写入数据的工作原理是什么?ES查询数据的工作原理是什么?底层的Lucene介绍一下?倒排索引了解吗?
面试官心理分析
问这个,其实面试官就是要看看你了解不了解es的一些基本原理,因为用es无非就是写入数据,搜索数据。你要是不明白你发起一个写入和搜索请求的时候,es在干什么,那你真的是……
对es基本就是个黑盒,你还能干啥?你唯一能干的就是用es的api读写数据了。要是出点什么问题,你啥都不知道,那还能指望你什么呢?
从Lucene到Elasticsearch:全文检索实战京东月销量91¥63.2购买面试题剖析
es写数据过程
客户端选择一个node发送请求过去,这个node就是coordinatingnode(协调节点)。
coordinatingnode对document进行路由,将请求转发给对应的node(有primaryshard)。
实际的node上的primaryshard处理请求,然后将数据同步到replicanode。
coordinatingnode如果发现primarynode和所有replicanode都搞定之后,就返回响应结果给客户端。
es-writees读数据过程
可以通过docid来查询,会根据docid进行hash,判断出来当时把docid分配到了哪个shard上面去,从那个shard去查询。
客户端发送请求到任意一个node,成为coordinatenode。
coordinatenode对docid进行哈希路由,将请求转发到对应的node,此时会使用round-robin随机轮询算法,在primaryshard以及其所有replica中随机选择一个,让读请求负载均衡。
接收请求的node返回document给coordinatenode。
coordinatenode返回document给客户端。
es搜索数据过程
es最强大的是做全文检索,就是比如你有三条数据:
java真好玩儿啊
java好难学啊
j2ee特别牛
你根据java关键词来搜索,将包含java的document给搜索出来。es就会给你返回:java真好玩儿啊,java好难学啊。
客户端发送请求到一个coordinatenode。
协调节点将搜索请求转发到所有的shard对应的primaryshard或replicashard,都可以。
queryphase:每个shard将自己的搜索结果(其实就是一些docid)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
fetchphase:接着由协调节点根据docid去各个节点上拉取实际的document数据,最终返回给客户端。
写请求是写入primaryshard,然后同步给所有的replicashard;读请求可以从primaryshard或replicashard读取,采用的是随机轮询算法。
写数据底层原理
es-write-detail先写入内存buffer,在buffer里的时候数据是搜索不到的;同时将数据写入translog日志文件。
如果buffer快满了,或者到一定时间,就会将内存buffer数据refresh到一个新的segmentfile中,但是此时数据不是直接进入segmentfile磁盘文件,而是先进入oscache。这个过程就是refresh。
每隔1秒钟,es将buffer中的数据写入一个新的segmentfile,每秒钟会产生一个新的磁盘文件segmentfile,这个segmentfile中就存储最近1秒内buffer中写入的数据。
但是如果buffer里面此时没有数据,那当然不会执行refresh操作,如果buffer里面有数据,默认1秒钟执行一次refresh操作,刷入一个新的segmentfile中。
操作系统里面,磁盘文件其实都有一个东西,叫做oscache,即操作系统缓存,就是说数据写入磁盘文件之前,会先进入oscache,先进入操作系统级别的一个内存缓存中去。只要buffer中的数据被refresh操作刷入oscache中,这个数据就可以被搜索到了。
为什么叫es是准实时的?NRT,全称nearreal-time。默认是每隔1秒refresh一次的,所以es是准实时的,因为写入的数据1秒之后才能被看到。可以通过es的restfulapi或者javaapi,手动执行一次refresh操作,就是手动将buffer中的数据刷入oscache中,让数据立马就可以被搜索到。只要数据被输入oscache中,buffer就会被清空了,因为不需要保留buffer了,数据在translog里面已经持久化到磁盘去一份了。
重复上面的步骤,新的数据不断进入buffer和translog,不断将buffer数据写入一个又一个新的segmentfile中去,每次refresh完buffer清空,translog保留。随着这个过程推进,translog会变得越来越大。当translog达到一定长度的时候,就会触发