00:00
接下来给大家讲第七章的内容,第七章我们要讲的是as search的常见面试题。第一个为什么要使用as search,我们之前给大家讲过了,我们的数据库当中存储的数据如果采用索引的方式,其实查询是非常快的,但是系统中的数据啊,随着业务的发展,时间的推移,它会非常的多,可是在业务当中啊,我们往往需要对我们某些数据做模糊查询,而不是精确查询,在这种情况下,我们的模糊查询会导致查询引擎的什么放弃。它而模糊查询呢,会导致查询引擎放弃索引,那么这样的话它就是全表扫描,那么全表扫描的话,大家可以想象一下,查询效率是非常低的,而我们的ES呢,可以作为一个全文索引,将我们经常需要查询的字段放到我们的索引当中,这样的话快速定位,快速查找我小的数据,这不挺好吗?而且我们ES当中,它会有很多关键性的指标,还会有一些技术站来帮助我们去展示数据,这也是非常好的。接下来我们来看第二题,第二题呢是我们elastic search的matter选举流程。
01:11
那么所谓的选举流程呢?其实我们是靠一个叫做Jin discovery模块来负责的,它里面包含了两个部分,一个是PIN,一个是UN cast。那么然后呢,我们会对所有可以成为master节点的那个node呀进行我们的字典排序,那么哪些节点可以成为master呢?这里面有个配置叫no.master我们讲过给它设定为true,你当前节点就有资格成为master了,然后呢,我们每一次呢,把这个节点排完序以后,再选出它的第一个,它就可以当成master节点,然后呢,我们还要对某个节点的投票数量超过一半,超过半数以上,而且当前节点的选择他自己的话,这个节点就是我们的master,否则我们就需要重新执行上面的过程,就是这样啊。Master节点的职责呢,主要是包括集群节点和索引的管理,不包括文档数据级别的管理,文档数据级别呢,都是靠我们的data node,就是我们的数据节点来完成的。好吧,嗯,看第三题叫elastic search的集群脑裂问题,这个是什么意思呢?很简单,就是在集群当中啊,有多个master的。
02:19
那你有多个master的话,我们的master作用是管理集群呢,那么有两个master,那谁管理呢?哎,这样的话就脑部分裂了,对不对,我们就这个意思。那么好,他可能存的原因是什么?其实很简单,主要原因就是因为我们特殊的情况下,我们的数据节点访问不到master了,因访问不到master,它可能就会认为挂掉了,那么你挂掉以后要重新选举新的master,就会导致在整个集群里面出现了什么多个master情况。那你说老师为什么就访不到呢?哎,有几种情况,第一个网络问题,你网络延迟的话,那么我们的节点想访问master,那可能就是不行,对不对,超过了时间,那就会重新选举了,这第一个,第二个呢叫节点负载,咱们的master呢,它不仅仅什么呢,提供我们的管理,它如果是个数据节点的话,它还能够什么呢?进行数据访问,那么一旦它的数据量访问大了,就会导致它的数据操作延迟,那么这样的话,我们其他节点就可能会认为,诶它已经挂掉了,这也是有可能的。
03:20
还有一个就是我们GC垃圾回收,你垃圾回收的话,就会导致我们的什么响应延迟,那么你半天不响应,那么我们的数据节点可不就认为你挂掉了吗?这都有可能啊,那么脑裂问题该如何解决呢?首先第一个我们可以把那个我们的时间呢,给它稍微的调整一下,因为我们这边有个超时时间,一旦我们去判断我们的master已经什么呢?连接不上的时候,我们会有个时间,超过这个时间我们就会重新选举了,那如果你把这个时间变得长一些的话,那么我们可能在这个时间之内就可能啊matter恢复了,那不就行了吗?对不对,这是一种情况,还有呢,是我们的下面这个地方,就是选举触发这个呢,它表述的是我们用于控制选举行为发生的最小集群的节点数量,官方推荐呢,我们是什么呢?一半以上,哎,有这么一个配置啊,还有一个是角色分离,所谓的角色分离呢,就是说我们当前的主节点呢,它由于有数据访问会导致。
04:20
它的数据处理延迟就会导致我们的其他节点呢连接它会超时,所以在这种情况下,如果把我们的master和data呢相分离,你只做你的管理,不做数据的访问,那这样的话,它就应该不会受到我们数据访问的影响,哎,这也是一种方案,好吧,呃,接下来我们看第四题啊,Search索引文档的流程,那我们首先呢,我们来看我们之前画过的一张图,这张图形当中大家可以看到客户端向我们的集群呢发出索引文档的请求,它会选择任何一个节点,这个节点当接收到请求之后,它会根据我们的路由算法找到我们的应该放的那个组分片的位置。
05:00
找到这个主分片的位置以后呢,它会往里面去索引数据,那么索引数据了之后呢,它会保证我们数据的完整性,它会将它的副本数据给它进行同步,同步完成以后呢,我们的用户,我们的客户端就可以进行访问了,哎,这就是一个最基本的索引的访问流程,但是细节上有所变化,比方说当我们的用户呢,发出请求以后,他的索引请求呢,会在我们内存当中会创建一个index,就是我们的索引。然后呢,它会把这个索引呢,再在内存当中形成一个分段对象,就是这样,可是这样它为了防止我们的数据出现问题,它会同时在索引数据之后呢,会写入到一个日志当中,我们叫translog,那么在这个过程当中啊,每个一秒中,它会将我们内存当中的这个segment的数据刷写到,或者说我们要刷新到我们OS cash,就是我们的文件系统的缓存放到这边,为什么要放到我们这个sig当中呢?它的它的主要目的呢,是为了能够让我们在这个位置接收用户的查询。
06:00
以前我们的查询都是等待落盘之后才查的,现在我们如果数据一旦到了OSK当中,就可以进行查询了,然后呢,我们这个里面的数据啊,它一旦到达某个时间,比方说诶,我们的30分钟,或者呢,我们的translog大于了512兆的话,它会将OS当中的数据刷写到磁盘当中,那么这样的话,我们的磁盘文件会不断的刷写,一旦刷写之后比较多了,那么性能会比较差,所以我们这个刷写的数据还可以进行合并,哎,就是这样的,这就是我们的一个完整的索引文档的流程。那接下来我们看第五题s search更新和删除文档的流程,那么其实啊,删除和更新的也是写的操作,对吧?但是呢,我们ES中的文档是不可变的,所以我们是不能够被删除或者改动以展示其变更的,你做不到啊,那么磁盘照每个段都有一个相应的点delete文件,那么当删除请求发送以后啊,文档并没有真的被删除,是逻辑上被删掉了。
07:00
所以呢,在我们这个文件当中啊,它会被标记为删除,也就意味着这个文档依然是能够匹配查询的,但是它会在结果当中被过滤掉,你就看不见了,所以呢,当我们段合并时,我就要想办法把这个文件中的数据呢给它清除掉,那这样的话就会好很多。然后呢,在新的文档被创建时,我们ES会被该文档指定一个版本号,当执行更新时,旧版本的文档在我们删除文件中会被标记为删除,新版本的文档会被索引到一个新的段,那么旧版本的数据依然是能够被查询,但是它会被结果过滤。所以啊,也就意味着我们除了这一点操作以外,我们的更新呢,删除啊,包括我们之前的索引数据啊,其实都是一样的啊,那接下来呢,我们来看我们的第六题啊,来search的搜索的流程,那么这个流程呢,我们在下面呢,用文字的方式给大家列出来啊,咱们首先看一看,嗯,搜索被执行成一个两阶段的过程,他们称之为query than fact。
08:01
那么首先在初始查询阶段,查询会广播到索引中,每一个分片的拷贝,你查询嘛,那么你去分解一下,将我们的数据放到不同的分片当中去查,这样的话性能会更快一些,对不对?而且呢,它查询的时候会构建我们的什么查询队列,那么然后在搜索的时候呢,会查询我们的文件系统缓存,也就意味着它不是查文件,它是查那个文件系统缓存,所以在这种情况下,其实性能还是不错的啊。然后呢,每个分片呢,返回自己的优先队列中所有文档的ID和排序值给协调节点,它合并这些值到自己的优先队列,来产生一个全局排序后的结果列表。这样的话,我们的查询就算是结束了,接下来呢,我们查询之后就是取回数据了,我们的协调节点呢,它会辨别出哪些文档需要被取回,并把它相关的分片提交多个盖盖的请求,就意味着我们去找真正的那个请求数据,那么每个分片加载并丰富文档,把我们的数据给他拿到,然后拿到以后将我们的最终结果呢反馈给我们的客户端就可以了,所以啊,他会有一个查找匹配的过程,然后再去找到那些核心和具体的对象和数据。
09:14
我们接下来来看第七题as search在部署时对我们Linux的设置有哪些优化的方法?首先第一个,如果你的机器的内存更大是非常理想的,比方说64个G对不对,为什么呀?之前我们讲过ES在做读写的时候呢,它会利用上我们的buffer以及我们的cash,就是我们的内存和我们的缓存,但这样的话,你的内存越多,你的执行效果,你的查询效率不就越快嘛,对不对?但是老师我没弄。但是老师我们没有那么多内存行不行也可以啊,那么我们32G16G也是可以的,但是你少于8G就会适得其反了啊。还有一个如果要在更快的单核CPU和更多的核心中选择的话,那么其实我们选择更多的核心会好很多。因为你单核的CPU,你再快,你只能多线程,什么并发执行,或者说串行执行,你达不到真正的并行执行,你的效率就变低了,如果你的核数多,那么你并行计算是非常强大的,能不能明白同学们,嗯,然后接下来他说了,如果你负担得起我们的固态硬盘的话,那么要比我们机械硬盘要好太多,这个咱们前面提到过,对不对啊,因为我们的,嗯,磁盘操作呢,也是影响整个ES效率的一个非常重要的一个什么参数,一个选项,嗯,即使数据中心它近在咫尺,也要避免集群跨越多个数据中心。
10:35
说的简单点,让他们更近一点,对吧,减少网络传输的这种性能损耗啊,好,请确保运行你应用程序的加入虚拟机和我们服务器的加入虚拟的版本是完全一样的,那么在这种情况下,我们依然是很多地方的一些操作就不会有冲突啊,还有呢,它这边呢,会调整一些参数呢,改变它的一些配置,让我们在集群的时候可以什么呢?嗯,避免过多的分片交换,这样的话也可以提高我们的效率啊。
11:03
呃,还有呢,就是不要随意修改垃圾回收器和各个线程池的大小,这个他们默认就可以了,你要给他随意改动的话,如果你不确定就会导致一些性能上的一些损耗啊,还有一个把你的内存呢,一半给我们的Lucy,说白了这个就是指的是什么,我们的那个内存和文件系统缓存就是这样的,但是不要超过32G,这个咱们提到过,对吧?嗯。然后呢,内存交换到磁盘时,对服务器性能是致命的,就意味着落盘的这个操作其实是非常慢的啊,这个呢,我们要考虑考虑如何能减少磁盘的落盘对吧?嗯,我们在之前给大家演示Linux下面去启动我们ES的时候,你会发现它改动了很多的系统配置,其实主要原因就是因为我们的Lucy要使用大量的文件,所以我们要把一些文件的描述符啊,包括一些我们的什么套接字这种东西要给它进行什么更改,改变一些它的参数啊,那么接下来呢,是我们索引阶段性能提升的方法,第一个调整批量处理的大小,这个得慢慢调啊,慢慢调,还有一个使用我们的固态什么硬盘,对吧?然后呢,下面呢是我们的断和合并啊,就意味着我们在做批量数据的操作的时候,我们需要去做一些我们的操作,让我们的数据呢,进行一些什么合并操作,但是你合并的太频繁是有问题的,对不对?哎,这个咱们知道啊,如果你的搜索结果呢,不需要进实时的准确。
12:30
绝度可以考虑把每一个索引的刷新时间改为30秒啊。还有一个,如果你在做大批量的数据导入时,需要考虑将我们副本的变为零,因为如果你把副本不变为零的话,它的这个时间会非常的长。延迟会非常的大,是这样的啊呃,接下来我们看第八题啊,GC方面在使用ES时需要注意什么,这个呢,我们就简单的把几项咱们列出来,咱们过一下就可以了。第一个倒排词典的所引呢,需要常驻内存,它无法GC,需要GC需要监控我们data notde上的一个什么段的一个内存的增长趋势。
13:09
还有呢,它会有存在各类的缓存,那么这些缓存呢,我们需要合理的设置它的大小,并且要根据什么最坏的情况来看堆是否够用,也就是说各类缓存全部占稳的时候,这个堆空间是否还可以分配给其他任务来,就是这样,这些东西我们需要看一看啊。还有避免返回大量结果集的搜索与聚合,确实需要大量拉取数据的场景,可以采用特殊的操作来实现。还有呢,我们集群的状态呢,驻留内存并无法扩水平扩展,超大规模集群可以考虑拆成多个集群,通过我们tree boot能连接,然后呢,想知道我们的内存够不够呢?其实我们需要根据我们的实际应用场景,对集群的堆的使用情况做持续的监控,来看一看我们到底我们的内存是怎么样一个情况,说第九题啊,我们第九题是ES对于大数据量的聚合是如何实现的。
14:02
因为数据越来越多呀,我们肯定是要对数据呢进行聚合统计嘛,而这个聚合统计啊,其实我们的ES底层呢,是有一些算法的,而且它通过一些特定的算法呢,来得到一些我们的什么比特位数据,然后呢做概率估算,从而得到一些数据的基数,然后通过这些基数呢,来得到我们的一些什么匹配的精度啊,是这样的,那么这种东西呢,对于大家来讲呢,可能就比较陌生了啊,这个都偏向于我们底层的这种什么运算规则了,这个呢,我们就不过多的做介绍了,好不好?同学们,接下来我们来看我们的第十个题啊,第十个题说在并发情况下,我们ES是如何保证读写一致性的。什么意思啊?什么叫读写一致性啊?就是说我们在并发强调的就是多线程同时访问,你也访问,我也访问,那么一般情况下我们是通过版本号的乐观锁来进行控制的,以确保新版本不会被旧版本覆盖,那么由应用层来处理具体的冲突,这个咱们再给大家讲,那个乐观所说我们演示过,就是说它会有一个什么序列号啊,一些东西,通过那个来判断我们当前的数据状态是不是最新的。
15:12
所以啊,如果不是最新的话,那你肯定不能改嘛,你得重新再取最新的才能改,对不对?哎,就这个意思,还有呢,对于我们的写操作来讲,我们的一致性还体现在什么呢?就是我们副本和主分片当中的数据同步问题,如果我们这里取个one,就意味着只要我们的master啊,只要我们的主分片他的数据保存成功了,我们的副本是暂时先不用考虑的,对吧,那这样的话,客户端就可以做下一次操作。那如果是二的话,它的一次性级别最高,它的所有的副本和分片的数据要全部成功了才能往下走,而我们的这个什么cor肉,它表示的含什么含义呢?就是说只要我们有什么一半以上的数据,我们的一半以上的这个分区啊副本他们成功了就都可以,好吧,嗯,对于我们读的操作来讲,同样我们可以设定专门的参数,在我们组分片和副本分片都查询完以后才会返回,当然了,我们也可以设定我们的什么异步操作,我们可以根据我们的请求参数来查询我们的主分片信息,不用考虑别的对不对,哎,是这样的啊,这是我们的结果一致性的一种什么我们的考虑。那接下来我们看第11题啊,如何监控elastic search的集群状态,我们今天给大家演示过,我们有一个叫elastic search的hide一个插件,这个插件呢,在咱们谷歌浏览器当中呢,可以直接来使用,当我们连接上集群之后,集群的很多数据指标呢,我们都能够看得到。包括我们当。
16:40
前的一些节点信息,分片信息,以及我们集群的健康信息,他都能够看得到,对不对,但是其实我们还有一个官方的一个key banner,这个key班ner呢,其实也可以更好的来监控我们的ES,它可以实时查看我们当前的集群的健康状态,以及它的性能啊,各方面的一些指标还是非常丰富的啊,看一下第12题啊,第12题说是否了解质典数,那首先呢,我们要考虑一个字典数据的结构是什么样子,大家看。
17:09
我们的质典结构呢,分很多种啊,比方说我们的排序列表,数组啊,集合呀,哈希map呀,Map呀,包括我们的什么list呀,这些东西,还包括数形结构啊,其实都可以存储我们的什么字典数据,那然后呢,我们所谓的质典数呢,又称之为叫单词查找数,我们的退数已是一种树形结构,它是一种哈希树的变种,它典型应用在我们统计排序和保存大量的字符串,但是里面不仅仅是这个局限于字符串啊,所以呢,经常被搜索引擎系统用于文本持频的统计。它的优点是利用字符串的公共前缀来减少查询时间,最大限度的减少无谓的字符串比较,查询效率比哈希数高啊。那么它的核心思想呢,其实就是空间换时间啊,就是这样的,我们空间更多一些,但是我们的时间更快一些,对不对啊,就是这样。
18:00
所以利用字符串的公共前缀来降低查询时间的开销,以达到提高效率的目的。它有三个基本特性,那第一个根节点不包含任何的字符,我们的根节点就有数形结构了嘛,对不对?除根节点外,每个节点都只包含一个字符,除根节点到某一个节点的路径上经过的字符连接起来为该节点对应的字符串。每个节点的所有子节点包文的字符都不相同,对于中文的字点数来讲,每个节点的子节点用一个哈希表来存储,这样的话就不用浪费太大的空间,而且查询速度上可以保留哈希的复杂度大OE哎,这个就是我们所谓的字典数的一些简单的思路啊,这就是我们这点数字当中的一些简单的概念,这个大家了解一下吧,好吧,嗯,第13题ES中集群节点索引文档类型是什么?其实啊,他就在问你一些基础的概念啊,因为核心的底层啊,他其实我们一般不怎么考虑,那么的一些基础概念,你能不能搞清楚也是非常重要的啊。那首先我们。
19:00
这第一个集群,集群是一个或多个节点的一个集合。啊,他们共同保存着我们的整个数据,并提供跨所有节点的联合索引和搜索功能。集群是由唯一名称标识,默认情况下它的名称是as search,名称很重要,如果节点设置为名称加入集群的话,那么该节点只能是集群的一部分。说的简单点就是所有的节点的集群名称应该是相同的,对不对?然后呢,我们所谓的节点呢,就属于集群的一部分,它是一个单个的服务器,它存储数据,并参与集中索引和搜索的功能。还有,所以呢,就像关型数据库中的什么数据库一样,它有一个定义,多种类型的映射索引,是逻辑名称空间映射到一个或多个主分片,并且可以有零个或多个副本分片。所以啊,你把那个我们的索引当成一个数据库,这么来理解其实是可以的。
20:04
还有我们下面我们的文档其实就类似于我们数据库当中的一行数据啊,你可以把它理解为就是数据,所以呢,我们的数据里面包含了不同的结构和字段啊,这个咱们要理解,但是呢,有一个问题什么呢?你不能够把我们那个type当成我们的表。就这个类型,这个类型啊,你不要把它理解为我们的表,因为我们在我们当前的版本当中已经不再推荐使用那个类型的概念了,所以我们这里先不要去考虑说啊老师,我们的那个数据库索引呢,他们是对应的,我们的那个表和type是对应的,我们那个document和我们的那个行是对应的,这个以前这么设计理解是没问题的,现在咱们可不要这么理解了,好不好?同学们,接下来我们来说一下第14题啊,ES当中的倒排索引是什么?这个在咱们前面的讲解当中啊,咱们已经讲了很多次了,所以我们这里呢,就简单的过一下就可以了啊嗯,倒排索引呢是搜索引擎的核心,搜索引擎的主要目标是在查找发生搜索条件的文档时提供快速搜索。而ES当中的倒排索引呢?其实就是它底层的loion的倒排索引。
21:12
它区别于传统的正向索引呢,倒排索引会在存储数据时,将我们的关键词和我们数据进行关联,保存到我们的倒排表当中去,然后再查询的时候,将查询的内容呢进行分词之后,再从倒排表中去进行匹配,匹配之后呢再去查找我们的数据,是这样的一个基本的过程啊,那么我们概念来讲就有一个正牌索引和正向索引的概念,那么我们反过来将我们的那个关键词和数据做关联,那这个其实就叫倒排索引。
我来说两句