为了账号安全,请及时绑定邮箱和手机立即绑定
首页 手记 【金秋打卡】第18天...

【金秋打卡】第18天 详细描述ES写入,更新,删除和查询的具体过程

2022.11.11 01:13 37浏览

课程名称海量数据高并发场景,构建Go+ES8企业级搜索微服务

课程章节:11-4

课程讲师少林码僧

课程内容

 https://img3.sycdn.imooc.com/636c7df20001190812351010.jpg

  • Query-Fetch两个阶段.

    • 第一阶段)客户端发出请求到ES节点。收到请求节点的节点 会以 Coordinating (协调)节点的身份,在全部主副分片中随机选择一个,发送查询请求

    • 第一阶段被选中的分片执行查询排序。然后每个分⽚都会返回 排序后的⽂档 Id 和排序值给 Coordinating 节点

    • 第二阶段协调者 节点会将 Query 阶段获取的⽂档 Id 列表,重新进行排序。选取 From 到 From + Size 个文档的 Id

    • 阶段再次发出请求到相应的分⽚获取详细的文档数据

  • 读数据过程

    • 可以通过 doc id 来查询,根据路由算法,默认会根据 doc id 进行 hash,判断出来当时把 doc id 分配到了对应的 shard 上面去,然后去那个 shard 去查询。

    • 客户端发送请求到任意一个 节点,成为 协调者 。

    •  协调者 对 doc id 进行哈希路由,将请求转发到对应的 node,此时会使用 round-robin 随机轮询算法,在 primary shard 以及其所有 replica 中随机选择一个,让读请求负载均衡。

    • 接收请求的 node 返回 document 给 协调者 

    •  协调者  返回 document 给客户端

  • 写数据的过程

    • 客户端选择一个 node 发送请求过去,这个 node 就是 coordinating node (协调节点)。

    • coordinating node 对 document 进行路由,将请求转发给对应的 node(有 primary shard)。

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

    • coordinating node 如果发现 primary node 和所有 replica node 都搞定之后,就返回响应结果给客户端。

    

            ※ 写数据的时候,先写内存buffer,同时记录log,将数据写入translog文件。在buffer里面的时候,你去查询数据,数据是查不到的,这就是为何不建议把ES当业务存储的原因。实时性很差,除非每次写入后都刷一次,把buffer里面的数据刷盘。

             ※ buffer如果快慢了,就会refrash到segment file 中(存在os cache),数据会先进入 os cache,(生成的segment file 存在os cache)(此时构建倒排索引)

            ※每隔 1 秒钟,es 将 buffer 中的数据写入一个新的 segment file ,每秒钟会产生一个新的磁盘文件 segment file ,这个 segment file 中就存储最近 1 秒内 buffer 中写入的数据。(生成的segment file 存在os cache)

            ※ 如果buffer里面没数据就不refreash了,如果有,但是没有满,每过一秒,就刷一次,刷入到新的segment file里面

            ※ 所谓  os cache,就是系统维护的一个缓存,通常是对存储器使用的,进入存储器比如硬盘的数据,会先被系统放入  os cache,再统一刷入磁盘,毕竟一次性读写要比多次读写效率高,进入到os cache,基本是在系统层面来说就是已经入盘了,读取磁盘数据和读取os cache数据对用户来说是无感知的。

            ※ es是准实时的,NRT near real-time,因为es 在写数据的时候,默认刷盘是1秒一次,所以在一切时候,你写入的数据需要1秒钟后才能查到,如果遇到系统繁忙,缓存占满等一系列问题,可能还要更久。当然,也可以通过es的 restful api 来手动执行一次 refresh 操作,buffer就被清空,数据记录到 translog。

            ※ 如果不听的refresh,记入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 中去。

其实 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 磁盘文件中。

https://img2.sycdn.imooc.com/636d31050001778b08310998.jpg


  • 数据更新过程

    • 所谓更新就是将需要更新的doc标识为删除,把更新后的数据当做新的数据写进去一条新的

  • 删除

    • 删除就是commit的时候会生成一个.del 文件,里面将某个记录设置为删除状态,搜索的时候就知道谁被删除了,和mysql的innodb行记录里面专门记录null值的做法差不多

https://img2.sycdn.imooc.com/636d3110000119f414981079.jpg





点击查看更多内容
0人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
PHP开发工程师
手记
粉丝
0
获赞与收藏
2

关注TA,一起探索更多经验知识

同主题相似文章浏览排行榜

风间影月说签约讲师

51篇手记,涉及Java、MySQL、Redis、Spring等方向

进入讨论

Tony Bai 说签约讲师

151篇手记,涉及Go、C、Java、Python等方向

进入讨论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消