ElasticSearch 面试 4 连炮,你顶得住么?
Java技术栈
www.javastack.cn
关注阅读更多优质文章
面试题
es 写入数据的工作原理是什么啊?
es 查询数据的工作原理是什么啊?
底层的 lucene 介绍一下呗?
倒排索引了解吗?
面试题剖析
es 写数据过程
客户端选择一个 node 发送请求过去,这个 node 就是
coordinating node
(协调节点)。coordinating node
对 document 进行路由,将请求转发给对应的 node(有 primary shard)。实际的 node 上的
primary shard
处理请求,然后将数据同步到replica node
。coordinating node
如果发现primary node
和所有replica node
都搞定之后,就返回响应结果给客户端。
es 读数据过程
doc id
来查询,会根据 doc id
进行 hash,判断出来当时把 doc id
分配到了哪个 shard 上面去,从那个 shard 去查询。客户端发送请求到任意一个 node,成为
coordinate node
。coordinate node
对doc id
进行哈希路由,将请求转发到对应的 node,此时会使用round-robin
随机轮询算法,在primary shard
以及其所有 replica 中随机选择一个,让读请求负载均衡。接收请求的 node 返回 document 给
coordinate node
。coordinate node
返回 document 给客户端。
es 搜索数据过程
java真好玩儿啊java好难学啊j2ee特别牛
java
关键词来搜索,将包含 java
的 document
给搜索出来。es 就会给你返回:java真好玩儿啊,java好难学啊。也不用怕,关注公众号Java技术栈回复java获取我写的精华Java系列教程。客户端发送请求到一个
coordinate node
。协调节点将搜索请求转发到所有的 shard 对应的
primary shard
或replica shard
,都可以。query phase:每个 shard 将自己的搜索结果(其实就是一些
doc id
)返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。fetch phase:接着由协调节点根据
doc id
去各个节点上拉取实际的document
数据,最终返回给客户端。
读请求可以从 primary shard 或 replica shard 读取,采用的是随机轮询算法。
写数据底层原理
refresh
到一个新的 segment file
中,但是此时数据不是直接进入 segment file
磁盘文件,而是先进入 os cache
。这个过程就是 refresh
。segment file
,每秒钟会产生一个新的磁盘文件 segment file,
这个 segment file
中就存储最近 1 秒内 buffer 中写入的数据。os cache
,即操作系统缓存,就是说数据写入磁盘文件之前,会先进入 os cache
,先进入操作系统级别的一个内存缓存中去。只要 buffer
中的数据被 refresh 操作刷入 os cache
中,这个数据就可以被搜索到了。
NRT
,全称 near real-time
。默认是每隔 1 秒 refresh 一次的,所以 es 是准实时的,因为写入的数据 1 秒之后才能被看到。可以通过 es 的 restful api
或者 java api
,手动执行一次 refresh 操作,就是手动将 buffer 中的数据刷入 os cache
中,让数据立马就可以被搜索到。os cache
中,buffer 就会被清空了,因为不需要保留 buffer 了,数据在 translog 里面已经持久化到磁盘去一份了。buffer
数据写入一个又一个新的 segment file
中去,每次 refresh
完 buffer 清空,translog 保留。commit
操作。refresh
到 os cache
中去,清空 buffer。commit point
写入磁盘文件,里面标识着这个 commit point
对应的所有 segment file
,同时强行将 os cache
中目前所有的数据都 fsync
到磁盘文件中去。flush
。默认 30 分钟自动执行一次 flush
,但如果 translog 过大,也会触发 flush
。flush 操作就对应着 commit 的全过程,我们可以通过 es api,手动执行 flush 操作,手动将 os cache 中的数据 fsync 强刷到磁盘上去。translog
中fsync
到磁盘,但是性能会差很多。关注公众号Java技术栈回复面试获取更多面试题。
删除/更新数据底层原理
.del
文件,里面将某个 doc 标识为 deleted
状态,那么搜索的时候根据 .del
文件就知道这个 doc 是否被删除了。deleted
状态,然后新写入一条数据。segment file
,所以默认情况下是 1 秒钟一个 segment file
,这样下来 segment file
会越来越多,此时会定期执行 merge。每次 merge 的时候,会将多个 segment file
合并成一个,同时这里会将标识为 deleted
的 doc 给物理删除掉,然后将新的 segment file
写入磁盘,这里会写一个 commit point
,标识所有新的 segment file
,然后打开 segment file
供搜索使用,同时删除旧的 segment file
。底层 lucene
倒排索引
有以下文档:
DocId | Doc |
---|---|
1 | 谷歌地图之父跳槽 Facebook |
2 | 谷歌地图之父加盟 Facebook |
3 | 谷歌地图创始人拉斯离开谷歌加盟 Facebook |
4 | 谷歌地图之父跳槽 Facebook 与 Wave 项目取消有关 |
5 | 谷歌地图之父拉斯加盟社交网站 Facebook |
对文档进行分词之后,得到以下倒排索引。
WordId | Word | DocIds |
---|---|---|
1 | 谷歌 | 1,2,3,4,5 |
2 | 地图 | 1,2,3,4,5 |
3 | 之父 | 1,2,4,5 |
4 | 跳槽 | 1,4 |
5 | 1,2,3,4,5 | |
6 | 加盟 | 2,3,5 |
7 | 创始人 | 3 |
8 | 拉斯 | 3,5 |
9 | 离开 | 3 |
10 | 与 | 4 |
.. | .. | .. |
Facebook
,搜索系统查找倒排索引,从中读出包含这个单词的文档,这些文档就是提供给用户的搜索结果。倒排索引中的所有词项对应一个或多个文档 倒排索引中的词项根据字典顺序升序排列
关注Java技术栈看更多干货