ElasticSearch面试相关

一.es写数据过程

1.客户端选择一个node节点发送请求,这个node就是协调节点

2.协调节点对文档进行路由,将请求转发给对应的node上(有主分片的)

3.实际的node上的主分片处理请求,然后把数据同步到副本分片上

4.协调节点发现主分片和副本分片都搞定之后,将响应结果返回给客户端

二.读数据过程

1.通过文档id查询,根据文档id进行hash 判断当时把文档id存到了哪个分片上去了,从那个分片进行查询

客户端发送请求到任意一个 node,成为 coordinate node

协调节点对文档id进行hash路由,将请求抓发到对应的node上,此时会使用round-robin随机轮询算法在主分片以及其所有replica中随机算则一个,让读请求负载均衡

接受请求的node返回文档给协调节点

协调节点返回文档给客户端

es搜索数据过程

客户端发送请求到一个协调节点

协调节点将搜索请求转发到所有的分片对应的主分片上或者副本分片上都可以

查询阶段:每个分片将自己的搜索结果其实就是一些文档id返回给协调节点,由协调节点进行数据的合并,排序,分页等操作,产出最终结果

刷新阶段,接着由协调节点根据文档id去各个节点拉取实际的文档数据,最终返回给客户端

写请求是写入 primary shard,然后同步给所有的 replica shard;读请求可以从 primary shard 或 replica shard 读取,采用的是随机轮询算法

写数据的底层原理

 1.先写入内存,在内存中的时候数据是搜索不到的,同时将数据写入到日志文件中

如果buffer快满了,或者到了一定的时间(默认为1s)就会将内存buffer数据refresh到一个新的segment file中,但是此时数据不是直接进入segment file磁盘文件,而是先进入系统缓存中,这个过程就是refresh

每隔1s中es将buffer中的数据写入一个新的segment file,每秒钟会产生一个新的磁盘文件segment file 这个segment file中就存储最近1s内buffer中写入的数据

但是如果buffer里面没有数据,当然不会执行refresh操作,如果buffer里面由数据,默认1秒钟执行一次

操作系统里面,磁盘文件气都有一个东西叫操作系统缓存,就是说数据写入磁盘文件之前,会先进入os cache,先进入操作系统级别的一个内存缓存中去,只要buffer中干的数据被refresh操作刷入os cache中,这个数据就可以被搜索到了,

为什么叫es是准实时的? 因为写入的数据1秒之后次啊会被看到,可以通过es的restful api 或者java api 手动执行一次refresh操作,就是手动将buffer中的数据刷入os cache中,让数据立马就可以被搜索到,只要数据被输入操作系统缓存中,buffer就会被清空,不需要保留buffer了,数据在日志里面已经持久化到磁盘去了

重复上面的步骤,新的数据不断进入 buffer 和 translog,不断将 buffer 数据写入一个又一个新的 segment file 中去,每次 refresh 完 buffer 清空,translog 保留。随着这个过程推进,translog 会变得越来越大。当 translog 达到一定长度的时候,就会触发 commit 操作。

commit 操作发生第一步,就是将 buffer 中现有数据 refresh 到 os cache 中去,清空 buffer。然后,将一个 commit point写入磁盘文件,里面标识着这个 commit point 对应的所有 segment file,同时强行将 os cache 中目前所有的数据都 fsync 到磁盘文件中去。最后清空 现有 translog 日志文件,重启一个 translog,此时 commit 操作完成。

这个 commit 操作叫做 flush。默认 30 分钟自动执行一次 flush,但如果 translog 过大,也会触发 flush。flush 操作就对应着 commit 的全过程,我们可以通过 es api,手动执行 flush 操作,手动将 os cache 中的数据 fsync 强刷到磁盘上去。

translog 日志文件的作用是什么?你执行 commit 操作之前,数据要么是停留在 buffer 中,要么是停留在 os cache 中,无论是 buffer 还是 os cache 都是内存,一旦这台机器死了,内存中的数据就全丢了。所以需要将数据对应的操作写入一个专门的日志文件 translog 中,一旦此时机器宕机,再次重启的时候,es 会自动读取 translog 日志文件中的数据,恢复到内存 buffer 和 os cache 中去。

translog 其实也是先写入 os cache 的,默认每隔 5 秒刷一次到磁盘中去,所以默认情况下,可能有 5 秒的数据会仅仅停留在 buffer 或者 translog 文件的 os cache 中,如果此时机器挂了,会丢失 5 秒钟的数据。但是这样性能比较好,最多丢 5 秒的数据。也可以将 translog 设置成每次写操作必须是直接 fsync 到磁盘,但是性能会差很多。

实际上你在这里,如果面试官没有问你 es 丢数据的问题,你可以在这里给面试官炫一把,你说,其实 es 第一是准实时的,数据写入 1 秒后可以搜索到;可能会丢失数据的。有 5 秒的数据,停留在 buffer、translog os cache、segment file os cache 中,而不在磁盘上,此时如果宕机,会导致 5 秒的数据丢失。

总结一下,数据先写入内存 buffer,然后每隔 1s,将数据 refresh 到 os cache,到了 os cache 数据就能被搜索到(所以我们才说 es 从写入到能被搜索到,中间有 1s 的延迟)。每隔 5s,将数据写入 translog 文件(这样如果机器宕机,内存数据全没,最多会有 5s 的数据丢失),translog 大到一定程度,或者默认每隔 30mins,会触发 commit 操作,将缓冲区的数据都 flush 到 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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值