ElasticSearch基本原理!

文档写入流程

客户端发送任何一个请求到任意一个节点,这个节点就成为协调节点 (coordinate node)。

协调节点对新增document(可以手动设置doc id,也可以由系统分配)的id号进行哈希取值。

再根据分片的数量进行取模,得到的数量就是具体的节点,然后将请求转发给对应node。

node上的primary shard处理请求,然后将数据同步到replica node。

协调节点如果发现primary shard所在的node和所有的replica shard所对应的 node 都搞定之后,就会将请求返回给客户端。

image-20221019211600114

文档提取流程

客户端发送任何一个请求到任意一个node,这个节点就成为协调节点。

协调节点对文档id进行哈希路由,此时会使用round-robin随机轮询算法。

  • 在主分片以及所有的副本分片中随机选择一个,让读请求负载均衡。

数据提取完毕,返回document给协调节点。

协调节点再将数据返回给客户端。

image-20221019211816105

文档搜索过程

文档搜索和提取的区别:

  • 文档提取:一次性获取一个文档。

  • 文档搜索:一次性获取多个文档。

客户端发送一个请求给协调节点(coordinate node)。

协调节点将搜索的请求转发给所有shard对应的primary shard或replica shard。

query phase:

  • 每一个shard将自己搜索的结果(其实也就是一些唯一标识),返回给协调节点。
  • 由协调节点进行数据的合并、排序、分页等操作,产出最后的结果。

fetch phase :

  • 接着由协调节点,根据唯一标识去各个节点进行拉取数据,最后汇总返回给客户端。

image-20221019211933274

文档写入的底层原理

refresh

  • ES 接收数据请求时先存入 ES 的内存中,默认每隔一秒会从内存 buffer 中将数据写入操作系统缓存 os cache。

  • 到了 os cache 数据就能被搜索到(所以ES 是近实时的,因为1s 的延迟后执行 refresh 便可让数据被搜索到)。

fsync

  • translog 会每隔5秒或者在一个变更请求完成之后执行一次 fsync 操作,将 translog 从缓存刷入磁盘,这个操作比较耗时。
  • 如果对数据一致性要求不是跟高时建议将索引改为异步,如果节点宕机时会有5秒数据丢失。

flush

  • ES 默认每隔30分钟会将 os cache 中的数据刷入磁盘,同时清空 translog 日志文件。

merge

  • ES 的一个 index 由多个 shard 组成,而一个 shard 其实就是一个 Lucene 的 index。
  • 它又由多个 segment 组成,且 Lucene 会不断地把一些小的 segment 合并成一个大的 segment。
  • 执行索引操作时,ES会先生成小的segment,ES 有离线的逻辑对小的 segment 进行合并,优化查询性能。
  • 但是合并过程中会消耗较多磁盘 IO,会影响查询性能。

image-20231111232733271

删除和更新过程

删除和更新都是写操作,但是由于 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更。

  • 所以 ES 利用 .del 文件 标记文档是否被删除,磁盘上的每个段都有一个相应的.del 文件。

如果是删除操作,文档其实并没有真的被删除,而是在 .del 文件中被标记为 deleted 状态。

  • 该文档依然能匹配查询,但是会在结果中被过滤掉。

如果是更新操作,就是将旧的 doc 标识为 deleted 状态,然后创建一个新的 doc。

每次segment merge 的时候,会将多个 segment 文件合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉

不写入到新的 segment 中,然后将新的 segment 文件写入磁盘,这里会写一个 commit point ,标识所有新的 segment 文件。

然后打开 segment 文件供搜索使用,同时删除旧的 segment 文件。

性能优化

数据预热

对于那些比较热的,经常会有人访问的数据,做一个专门的缓存预热子系统,对热数据每隔一段时间,就提前访问一下。

让数据进入 ES内存 里面去,这样下次别人访问的时候,一定性能会好一些。

冷热分离

将冷数据写入一个索引中,然后热数据写入另外一个索引中。

这样可以确保热数据在被预热之后,尽量都让他们留在 ES内存 里,别让冷数据给冲掉。