轻松了解面试官心理!ElasticSearch写入数据的工作原理是什么? | 技术头条

戳蓝字“CSDN云计算”关注我们哦!


640?wx_fmt=jpeg


作者:手留余香

转自: Java架构沉思录

面试题

es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗?

面试官心理分析

问这个,其实面试官就是要看看你了解不了解 es 的一些基本原理,因为用 es 无非就是写入数据,搜索数据。你要是不明白你发起一个写入和搜索请求的时候,es 在干什么,那你真的是......


对 es 基本就是个黑盒,你还能干啥?你唯一能干的就是用 es 的 api 读写数据了。要是出点什么问题,你啥都不知道,那还能指望你什么呢?

面试题剖析

es 写数据过程

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

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

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

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

 

640?wx_fmt=jpeg

es 读数据过程

可以通过 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 给客户端。


es 搜索数据过程


es 最强大的是做全文检索,就是比如你有三条数据:

java真好玩儿啊java好难学啊j2ee特别牛


你根据 java 关键词来搜索,将包含 java的 document 给搜索出来。es 就会给你返回:java真好玩儿啊,java好难学啊。


  • 客户端发送请求到一个 coordinate node

  • 协调节点将搜索请求转发到所有的 shard 对应的 primary shard 或 replica shard,都可以。

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

  • fetch phase:接着由协调节点根据 doc id 去各个节点上拉取实际的 document 数据,最终返回给客户端。

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

写数据底层原理

640?wx_fmt=jpeg

 

先写入内存 buffer,在 buffer 里的时候数据是搜索不到的;同时将数据写入 translog 日志文件。


如果 buffer 快满了,或者到一定时间,就会将内存 buffer 数据 refresh 到一个新的 segment file 中,但是此时数据不是直接进入 segment file 磁盘文件,而是先进入 os cache 。这个过程就是 refresh


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


但是如果 buffer 里面此时没有数据,那当然不会执行 refresh 操作,如果 buffer 里面有数据,默认 1 秒钟执行一次 refresh 操作,刷入一个新的 segment file 中。


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


为什么叫 es 是准实时的? NRT,全称 near real-time。默认是每隔 1 秒 refresh 一次的,所以 es 是准实时的,因为写入的数据 1 秒之后才能被看到。可以通过 es 的 restful api 或者 java api,手动执行一次 refresh 操作,就是手动将 buffer 中的数据刷入 os cache中,让数据立马就可以被搜索到。只要数据被输入 os cache 中,buffer 就会被清空了,因为不需要保留 buffer 了,数据在 translog 里面已经持久化到磁盘去一份了。


重复上面的步骤,新的数据不断进入 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 磁盘文件中。


数据写入 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


底层 lucene


简单来说,lucene 就是一个 jar 包,里面包含了封装好的各种建立倒排索引的算法代码。我们用 Java 开发的时候,引入 lucene jar,然后基于 lucene 的 api 去开发就可以了。


通过 lucene,我们可以将已有的数据建立索引,lucene 会在本地磁盘上面,给我们组织索引的数据结构。


倒排索引


在搜索引擎中,每个文档都有一个对应的文档 ID,文档内容被表示为一系列关键词的集合。例如,文档 1 经过分词,提取了 20 个关键词,每个关键词都会记录它在文档中出现的次数和出现位置。


那么,倒排索引就是关键词到文档 ID 的映射,每个关键词都对应着一系列的文件,这些文件中都出现了关键词。


举个栗子。


有以下文档:

640?wx_fmt=jpeg

对文档进行分词之后,得到以下倒排索引。

640?wx_fmt=jpeg


另外,实用的倒排索引还可以记录更多的信息,比如文档频率信息,表示在文档集合中有多少个文档包含某个单词。


那么,有了倒排索引,搜索引擎可以很方便地响应用户的查询。比如用户输入查询 Facebook,搜索系统查找倒排索引,从中读出包含这个单词的文档,这些文档就是提供给用户的搜索结果。


要注意倒排索引的两个重要细节:


  • 倒排索引中的所有词项对应一个或多个文档

  • 倒排索引中的词项根据字典顺序升序排列

上面只是一个简单的栗子,并没有严格按照字典顺序升序排列。



640?wx_fmt=png


福利

扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


640?wx_fmt=jpeg


推荐阅读:

  • 2019年技术盘点微服务篇(一) | 程序员硬核评测

  • 为什么说要注销 QQ 的,都是君子呢?

  • 程序员怒了!你敢削减专利奖金,我敢拒绝提交代码!

  • 如何教小朋友编写第一个程序?

  • 研究人员:Intel 的 VISA 漏洞可访问计算机中所有数据

  • 大数据杀熟时代, 隐私被扒光的你毫无自由可言, 而隐私币就是你的那根救命稻草!

  • 如何将TensorFlow Serving的性能提高超过70%?

  • 做了四年以太坊核心开发者, 以太坊升级了, 我也该离开了……


640?wx_fmt=png喜欢就点击“在看”吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/524280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenGL 伽马线

目录 一.OpenGL 伽马线 1.IOS Object-C 版本2.Windows OpenGL ES 版本3.Windows OpenGL 版本 二.OpenGL 伽马线 GLSL Shader三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 &…

GitHub 创建项目

需求:在github上创建一个新的远程仓库:

Qt界面设计器中的界面预览与程序运行时界面不一样

用QtCreate创建的界面应用程序,在ui文件中拖入所需的控件,并进行布局,布局完成后在ui文件的工具->form Editor->预览可查看当前界面。问题便是:通过预览查看界面布局没有问题,但运行程序时界面与预览的界面存在偏差。 我做…

找了前锤子CTO钱晨加入SLG ,百度终于认了……新的一年第4批CDN牌照公布;亚马逊开设云计算技术培训工作 | 极客头条...

关注并标星星CSDN云计算极客头条:速递、最新、绝对有料。这里有企业新动、这里有业界要闻,打起十二分精神,紧跟fashion你可以的!每周三次,打卡即read更快、更全了解泛云圈精彩newsgo go go 百度宣布正式进军社交领域并…

Windows OpenGL ES 图像伽马线

目录 一.OpenGL ES 图像伽马线 1.原始图片2.效果演示 二.OpenGL ES 图像伽马线源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 Open…

idea将本地项目推送至远程仓库(图形化版本01)

需求:演示把项目推送到github远程仓库: 需求思路分析:1.拉取或更新(Update Project)项目2.将本地项目添加至暂存区3.将暂存区的项目提交到本地仓库4.将本地仓库中的代码推送至(Push)远程GitHub仓库5.登录查看&#xff…

5G精华问答:5G的速度到底有多快?| 技术头条

近几年5G大火,尤其是2019年更是达到了高潮,关于5G的各种问题也随之而来,它究竟有多快,会不会取代WiFi和4G,今天就为大家来解答各种关于5G的问题吧。1Q:5G会取代Wi-Fi么?A:5G是第五代…

第一篇:Spring Boot 快速入门篇

小技巧: Spring Boot 集成周边技术3部曲 1.pom文件引入maven依赖 2.配置文件中配置相关信息 3.启动类上加注解 一、Spring Boot 构建项目有2种方式: Maven 构建项目 1、访问 http://start.spring.io/2、选择构建工具 Maven Project、Java、Spring Boot…

Windows OpenGL 图像伽马线

目录 一.OpenGL 图像伽马线 1.原始图片2.效果演示 二.OpenGL 图像伽马线源码下载三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效 零基础 OpenGL ES …

OpenStack已死?恐怕你想多了 | 技术头条

戳蓝字“CSDN云计算”关注我们哦!技术头条:干货、简洁、多维全面。更多云计算精华知识尽在眼前,get要点、solve难题,统统不在话下!译者:Lorraine Lo在接受不同采访时我经常会被问到这么一个问题&#xff1a…

Windows 环境 Jenkins集成构建SonarQube

关于Windows搭建SonarQube_Mysql的相关操作先点击下面的链接,进行跳转。 操作手册: Windows搭建SonarQube_Mysql 启动Jenkins有2种方式: 第1种:java -jar jenkins.war :原理是用自身的netty启动第2种:把jenkins.war…

tcp的简单使用实例一

话不多说,直接上自己写的一个tcp小程序,分为客户端和服务端两个程序,实现了单一方向的数据传输。下面来看具体的代码: 先看客户端的程序。创建基于Qt Widgets Application 的应用程序,选择基类QDialog,修改类名为myCli…

英特尔强势上新一大波数据产品,小伙伴们“奔走相告”…… | 极客头条

戳蓝字“CSDN云计算”关注我们哦!技术头条:干货、简洁、多维全面。更多云计算精华知识尽在眼前,get要点、solve难题,统统不在话下!作者:刘晶晶近日,英特尔推出了一款创新产品组合,点…

Qt中Tcp通信的简单使用二

tcp编程中写的一个简单的单项传输数据的小例子&#xff0c;和上一节一样&#xff0c;分为客户端和服务端程序&#xff0c;下面看一下界面的效果。 创建的方法和之前一样&#xff0c;上面上代码&#xff1a; 客户端 Client.h #ifndef CLIENT_H #define CLIENT_H#include <…

atom插件安装方法

Search Atom packages 安装插件前提&#xff1a; 1、安装git 和node.js2、node官网&#xff1a;https://nodejs.org/en/3、下载稳定版 4、安装node.js 详细安装步骤&#xff1a; http://www.runoob.com/nodejs/nodejs-install-setup.html 5、插件搜索官网&#xff1a; https…

Docker精华问答:Docker与虚拟机的区别?| 技术头条

Docker 是个划时代的开源项目&#xff0c;它彻底释放了计算虚拟化的威力&#xff0c;极大提高了应用的维护效率&#xff0c;降低了云计算应用开发的成本&#xff01;使用 Docker&#xff0c;可以让应用的部署、测试和分发都变得前所未有的高效和轻松&#xff01;1Q&#xff1a;…

Qt下Tcp通信的简单使用三

和之前两个例子一样&#xff0c;程序比较简单&#xff0c;刚入门的可以看看&#xff0c;先上效果图。 下面是客户端&#xff1a; myClient.h #ifndef CLIENT_H #define CLIENT_H#include <QDialog>QT_BEGIN_NAMESPACE namespace Ui { class Client; } QT_END_NAMESPAC…

44年前的今天,改变世界的TA诞生了! | 极客头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;1975年4月4日&#xff0c;是历史上普通的一天。这一天&#xff0c;有两个人成立…

第二篇:Spring Boot 热部署

文章目录1. 依赖2. 开启实时自动编译3. 开启运行自动编译开关1. 依赖 <!-- 热部署DevTools --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId></dependency>2. 开启实时自…

Spring Boot 企业实战_前夕

Spring Boot 专栏设置意在实战微服务&#xff0c;依赖统一由父工程进行依赖控制&#xff0c;其他子项目均依赖此工程。 小技巧&#xff1a; Spring Boot 集成周边技术3部曲 1.pom文件引入maven依赖 2.配置文件中配置相关信息 3.启动类上加注解 创建Spring Boot 父工程&#xff…