ElasticSearch基本原理!
ElasticSearch基本原理!
月伴飞鱼文档写入流程
客户端发送任何一个请求到任意一个节点,这个节点就成为协调节点 (coordinate node)。
协调节点对新增document(可以手动设置
doc id
,也可以由系统分配)的id号进行哈希取值。再根据分片的数量进行取模,得到的数量就是具体的节点,然后将请求转发给对应node。
node上的primary shard处理请求,然后将数据同步到replica node。
协调节点如果发现primary shard所在的node和所有的replica shard所对应的 node 都搞定之后,就会将请求返回给客户端。
文档提取流程
客户端发送任何一个请求到任意一个node,这个节点就成为协调节点。
协调节点对文档id进行哈希路由,此时会使用round-robin随机轮询算法。
- 在主分片以及所有的副本分片中随机选择一个,让读请求负载均衡。
数据提取完毕,返回document给协调节点。
协调节点再将数据返回给客户端。
文档搜索过程
文档搜索和提取的区别:
文档提取:一次性获取一个文档。
文档搜索:一次性获取多个文档。
客户端发送一个请求给协调节点(coordinate node)。
协调节点将搜索的请求转发给所有shard对应的primary shard或replica shard。
query phase:
- 每一个shard将自己搜索的结果(其实也就是一些唯一标识),返回给协调节点。
- 由协调节点进行数据的合并、排序、分页等操作,产出最后的结果。
fetch phase :
- 接着由协调节点,根据唯一标识去各个节点进行拉取数据,最后汇总返回给客户端。
文档写入的底层原理
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,会影响查询性能。
删除和更新过程
删除和更新都是写操作,但是由于 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更。
- 所以 ES 利用 .del 文件 标记文档是否被删除,磁盘上的每个段都有一个相应的
.del
文件。如果是删除操作,文档其实并没有真的被删除,而是在
.del
文件中被标记为 deleted 状态。
- 该文档依然能匹配查询,但是会在结果中被过滤掉。
如果是更新操作,就是将旧的 doc 标识为 deleted 状态,然后创建一个新的 doc。
每次segment merge 的时候,会将多个 segment 文件合并成一个,同时这里会将标识为 deleted 的 doc 给物理删除掉。
不写入到新的 segment 中,然后将新的 segment 文件写入磁盘,这里会写一个 commit point ,标识所有新的 segment 文件。
然后打开 segment 文件供搜索使用,同时删除旧的 segment 文件。
性能优化
数据预热
对于那些比较热的,经常会有人访问的数据,做一个专门的缓存预热子系统,对热数据每隔一段时间,就提前访问一下。
让数据进入 ES内存 里面去,这样下次别人访问的时候,一定性能会好一些。
冷热分离
将冷数据写入一个索引中,然后热数据写入另外一个索引中。
这样可以确保热数据在被预热之后,尽量都让他们留在 ES内存 里,别让冷数据给冲掉。