写入数据过程
-
客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node (协调节点)。
-
coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)。
-
实际的 node 上的 primary shard 处理请求,然后将数据同步到 replica node 。
-
coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。
读取数据过程
可以通过 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 给客户端。
搜索数据过程
-
客户端发送请求到一个 coordinate node 。
-
协调节点将搜索请求转发到所有的 shard 对应的 primary shard 或 replica shard ,都可以。
-
query phase:每个 shard 将自己的搜索结果(其实就是一些 doc id )返回给协调节点,由协调节点进行数据的合并、排序、分页等操作,产出最终结果。
-
fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据,最终返回给客户端
写入数据原理
- 数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到 os cache,到了 os cache 数据就能被搜索到(所以我们才说 es 从写入到能被搜索到,中间有 1s 的延迟)。每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据丢失),translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 segment file 磁盘文件中。
数据写入 segment file 之后,同时就建立好了倒排索引。
删除/更新数据原理
- 如果是删除操作,commit 的时候会生成一个 .del 文件,里面将某个 doc 标识为 deleted 状态,那么搜索的时候根据 .del 文件就知道这个 doc 是否被删除了。
- 如果是更新操作,就是将原来的 doc 标识为 deleted 状态,然后新写入一条数据。
- buffer 每 refresh 一次,就会产生一个 segment file ,所以默认情况下是 1 秒钟一个 segment file,这样下来 segment file 会越来越多,此时会定期执行 merge。每次 merge 的时候,会将多个 segment file 合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉,然后将新的 segment file 写入磁盘,这里会写一个 commit point ,标识所有新的 segment file ,然后打开 segment file 供搜索使用,同时删除旧的 segment file 。
倒排索引特点
-
倒排索引中的所有词项对应一个或多个文档;
-
倒排索引中的词项根据字典顺序升序排列