00:00
讲一下进实时搜索ES search的主要应用场景呢,就是实时数据全文检索,但是ES软件本身并非是实时的,而是进实时或叫准实时的,主要原因就在于ES的数据搜索是基于分段搜索,这里的分段我们前面讲过了,ES中的每一段其实就是一个倒排索引,最新的数据更新会体现在最新的段中,而最新的段落盘之后,ES软件才能进行数据搜索,那么这样的话,磁盘的IO性能就极大的影响了ES软件的查询效率。但是反过来想想呢,全文搜索引擎设计的目的不就是能快速的、准确的获取我们想要的数据吗?所以啊,降低数据查询处理的延迟就显得尤为重要。那么在优化查询效率上,ES都做了哪些尝试呢?我们这里一起来看一看。那么首先ES软件的索引呢?它采用了多分片的存储方式。整体架构上采用了一组多副,这个咱们前面讲过一个主分片多个副本的概念,对不对?通过配置路由规则,将数据分成多个数据子集,每个数据子集提供独立的索引和搜索功能,当写入文档的时候,根据路由规则将文档发送给特定的分片来建立索引。
01:15
这个咱们之前提到过,咱们现在来看一看,那么我们接下来呢,给大家画图呢,然后大家体会一下这个过程,好吧,来首先我先写一个集群,来,我给个蓝色。接下来我们加一些文字,我们叫做集群cluster好了,改完之后把颜色呢,我们稍微的变一变,变成白色醒目一些,然后呢,变变得稍微大一些啊,这个呢,就是我们的一个集群啊,就是它了,那接下来我们在这里面就应该有不同的数据节点,对吗?比方说我们的data node,咱们叫数据节点,那这里呢,我们拿过来放到这边啊,我们来写上咱们叫数据节点,把这个呢给它放过来啊好。放在稍微大一些啊,放到这边,然后呢,这个数据节点呢,它会有个master什么什么概念,这个咱们暂时先不考虑了,好吧,那我这里给他一个绿色的啊,给个绿色的,那么我们这里呢,拷贝拷贝以后呢,三个我们的数据节点放过来,那我觉得这个地方可以用文字方式给他描述一下吧,好不好来。
02:10
我这里呢,放过来放这边我们写上叫data node啊,咱们叫数据节点,然后呢,颜色给它变成白色,嗯。好了,那这个时候呢,我们复制一下我们三个数据节点,好三个数据节点的话,我现在准备干嘛呢?客户端呢,我们发送请求,发送请求呢会找到集群的某个节点,记住这个节点可以是任何一个节点,那么找到这个节点以后,那然后怎么办呢?记住这个时候我们要写入数据的话,我们需要先考虑我们往组分片中去写入,那么主分片在哪啊,咱们来。我们的主分片呢,可能啊,就是在我们的第二台机器上,大家看一下来这个呢,是我们的一个分片,但是呢,我给它写上一个来我们这里呢,叫做什么呢?叫二零,那咱们叫做二零,然后呢,我们再来,我们写上一个叫做二一,这是我们的二一,好,中间的这个呀,我们称之为叫做来拷贝,我们写上叫做土酚片,我们写上叫P0,哎,咱们叫P0,好了,同学们,这个呢,我们换个颜色吧,好不好,那个我们的紫色,嗯,行了。
03:15
那么当我们写入数据的时候,它首先会找到第一个我们的节点,第一个节点呢,它来计算你当前的我们主分配的位置,这边会有个路由计算的规则。这个咱们之前给大家提过,有个叫路由计算的规则,它会用哈希,然后呢,传递一个我们的什么,我们的路由的一个参数,我们比方说是那个ID呢,在模拟我们那个分片的数量,在模拟我们的分片的数量,咱们写上啊,咱们叫做分片的数量啊,比方说大家可以看到我现在就三个分片嘛,那么它计算完毕以后,不是零就是一,就是二,这样的话可以找到我们的任何一台我们的节点,然后计算出它的主分片的位置,对不对,哎,就这个意思,所以在这种情况下,我们的请求啊,就会发生变化,我们的箭头诶,就指向了咱们的这个主分片放过来。
04:05
你放过来以后记住了,这个时候我们当前的第一个节点,我们就称之为叫协调节点,它来协调调度嘛,然后呢,它会找到我们当前的这个主分片的节点,然后呢,往里面写入对不对,可是你光写入主分片是不够的,为了保证我们的数据安全,我们需要将它同步到我们的副本当中,对不对,所以这个时候呢,同学们,看来我们的箭头呢,要指向它了,哎,要指向它了,好,指向它了以后我们放过来,我们写上啊,这是第一步。咱们的第一步好,然后呢,这个呢,是我们的第二步啊,它是我们的第二步。然后呢,接下来这是我们的第三步,但第三步啊,它的这个副本有两个,就意味着第三步其实是并行的,并不是说谁先做谁后做,所以呢,我们的箭头呢,从这个地方咱们再来指向这个位置啊讲它这个呢,也是我们的第三步,好吧,同学们来。在这种操作模式下,我们ES文档写入呢,主要是写主分片和副本分片,那么写入操作的延时啊,就等同于主分片的写入时间,以及并行计算中最长的副本的什么延迟时间,这个大家能明白吗?所以我们再给大家把这个说说清楚啊来放过来。
05:20
搬过来以后这边呢,我们写上24啊,然后把它去掉,我们写上就是我们的操作啊,咱们写上叫延时。它的这个岩石是什么呢?是我们的主分片啊,主分片的岩石。加上我们的什么并行计算,并行写入我们的副本啊,副本最大延迟啊,最大延迟为什么呢?因为我们也不知道我们写入哪个副本什么时间更长,所以在这种情况下,你把那个最大的那个副本延时呢给它加上,这样的话就是总共写入的延迟了啊,就这意思,所以大家会发现副本分片的个数就直接决定了写入的性能,如果副本多,那某一个比较时间长的话,那么写入的效率就会比较低。
06:06
但是啊,这样的好处也是非常明显的,它避免写入后单击或磁盘故障导致数据丢失,数据会更加安全。可是呢,在数据和性能方面呢,我们一般都会选择我们的数据的安全,那么除非一些允许丢失数据的特殊场景,我们才会把效率呢做到极致,对不对?所以数据不丢这个是我们的前提条件,但是一味追求的数据安全而忽略数据查询的效率,也会丢失很多的用户,所以合理的配置副本数量,在性能和安全之间取得平衡也是非常重要的。刚才呢,我们把这个写的流程呢简单的过了一下,那接下来我们看一看索引具体的写操作是怎么去做的。首先客户端将请求发送到我们的主分片所在的节点ES,为了减少磁盘IO,保证读写性能,会在内存中建立索引,创建对象,那我现在呢,就画一个内存。
07:02
然后呢,这个内存呢,我们来写上啊,咱们这边写上咱们叫memory。好了,那我接下来呢,我们来把我们的客户端给它画出来。客户端,然后呢,他发送请求,他会走到我们的内存,在内存中把索引创建出来,诶就是这样,那好了,那我这里呢,就给他准备一个索引就可以了啊来索引数据,咱们这里简单点啊,咱们简单点就写上一个我们叫index,我觉得就可以了啊,一个索引数据,好,那么这个索引数据啊,它首先放在我们的内存当中,那么这个时候它会把这个,所以呢,给它封装好之后,形成一个分段的什么数据对象,所以呢,我这里光有个它还是不够的,我们还得再加一个拷贝,那拷贝。OB过来以后呢,放到这边我们写上,咱们叫做segment。这是那个分段的数据对象啊,来好了,那你这么写完了以后,可是你最终是要把我们这个分段数据是要落盘的呀,对不对,所以我们的箭头呢,要指向我们真正的磁盘,所以啊,你现在都是内存操作,我们再来咱们拷贝,拷贝以后把这个呢放到我们这边啊,给它放过去。
08:14
然后把它拿过来,这个能我们拷贝,拷贝之后呢,我写上咱们这个叫做Dis,诶咱们的磁盘,那么这个磁盘当中啊,就应该也有一个S,但是记住这是内存中的对象,这是磁盘中的文件,所以啊磁盘中的文件,那么我们这个颜色给它稍微的标识一下,好吧,同学们,这个呢,就是我们最基本的一个什么写入的操作,而且当你写入完成之后,我们的客户端还可以进行查询。什么意思,你得真正落盘了,表示的是这个索引呢,已经保存下来了,那么我们的用户才能够发送请求去进行我们的查询操作来复制,复制以后应该是这个样子的,诶反过来,嗯。好了,那你放过来以后,大家可以看到,为什么说我们的这个ES并不是真正的实时呢?因为当你把数据落盘之后,你才能够进行我们的查询,那么当然它的性能会比较慢了,对不对?哎,就是这个意思,而且呢,我们将这个segment呢,写入到我们的磁盘文件当中啊,这边有一个我们的概念,这个概念我们称之为叫flash,咱们叫flash,诶,就是它了。
09:24
好吧,同学们有这么一个概念啊,来。好了,这个操作呢,我们称之为叫做flash,把我们内存当中的我们数据给它刷写到我们磁盘当中,就是这样的啊,可是大家想一想,如果你再把这个我们的内存中的数据对象给它刷写到我们flash的时候,突然机器宕机了或者断电了,那么内存中的数据不也就丢失了吗?这个时候如何保证我们的数据安全呢?对不对?对于这个问题啊,我们ES软件学习了数据库当中的处理方法,它增加了一个特殊的模块叫。
10:02
你可以理解为就是日志文件啊,所以呢,在这个地方大家可以看到,当我们写入索引的时候,这边还有个东西干嘛呢,我们写上咱们叫做translo。哎,传输到一个日志啊,在这里面,而我们对应的磁盘当中也会有这样的一个文件,哎,所以放过来,这个呢,我们是两份应的,所以它我们就可以用红色来表示了,哎,它是一份文件,这个是我们磁盘当中的一个对象,哎,就这么回事了,那好了,那么在这种情况下,大家可以看到我们现在就需要考虑一件事情了,考虑什么事情?当我写入到内存当中的时候,我们还需要做一件事情,把我们的数据给它往这个日志里面去放,写入请求到达我们分片的时候,先写入到我们的索引当中,就是我们炉行当中的文件,然后呢,创建好索引,此时索引还在内存当中,那么接下来我们去写这个叫传log,写完传log之后,我们刷写我们的数据,将我们数据从我们内存中刷到磁盘里面,然后磁盘诶我们保存成功,然后将请求反馈给用户,那这个时候我们的translog给他清空就可以了。
11:09
这个穿log其实它的目的很简单,就是为了什么呀?它就是为了保证数据的安全,那这个过程呢,我们也叫做flash啊同学们,咱们这个也叫flash,那接下来我们再说一下,在这里面有几个关键点需要大家注意,和数据库不同的是,数据库啊是先写入我们的日志,再写入内存,而我们的ES呢,是先写入内存再写日志,那么一种可能原因呢,是我们这个内存写入啊,会有很复杂的逻辑,很容易失败,为什么呢?比方说分词呀,比方说过滤啊,转换呀,那么这样的话,它会导致逻辑非常复杂,有可能就会出现问题。那么为了避免我们的穿lo中有大量的无效记录,因为如果你先写log,然后转换失败,你这个数据不就无效了吗?所以啊,为了避免这种情况,避免减少恢复的复杂度和提高速度,所以呀,我们就先写内存,再写日志,哎,这是我们需要注意的。
12:02
还有一个呢,当我们写入到内存当中的时候,我们说过了,我们的数据并不能够被搜索,它必须要把我们的数据刷写到我们磁盘当中才进行操作,这个操作呀,你会发现它的性能就会稍微的有点低,那你说老师那低的话我们该怎么办呢?这个时候啊,我们告诉大家,其实我们可以在中间呢再加一层,什么叫加一层呢?就意味着我们中间还可以加一个叫做操作系统的文件缓冲区。所以大家可以看到来咱们拷贝,拷贝以后,我们在中间我们加一层,那么加的这个一层呢,这个颜色呢,我稍微再变一变,诶咱们叫这个颜色,这个我们称之为什么呢?咱们叫O。操作系统的一个什么缓冲区来说,他一个开始。不太大了,给它变小点儿,变小点就可以了,好,这个颜色呢,咱们用黑色吧,醒目一点啊,嗯,好了,那你说这个是干嘛用的呢?这个其实就是把我们内存中的数据啊,在写入磁盘之前,先给它往这个里面放一份,那么在这种情况下,他先不着急往我们的磁盘里面放,先放到我们的系统文件的缓冲区,所以拷贝拷贝以后放到这里面,我换一个颜色啊,放这里面。
13:18
所以我们的箭头从这个地方,哎,走到咱们的这个地方,当你走到这儿的时候,由于你的translog里面现在已经有数据了,有数据的话,数据相对来说就安全了,那我只要保证这个缓冲期能够提供我们的服务,那咱们查询不就快了吗?为什么?因为你并不需要真正的写入磁盘呢?你只需要在这个位置打开我们的搜索,那么我们的性能就可以得到提高。老师,那什么时候把这个segment往这里面放呢?这个时候我们说一下每一秒来做这个事儿,这个操作咱们称之为叫做refresh刷新,它会导致我们的内存中的数据对象给它保存到我们缓冲区的数据对象,最后再会刷写到我们的第四个当中,这个flash时间呢,其实也是可配的,这两个都是可配的,这个呢是我们半个小时啊,像这个呢,就是一秒了。
14:13
它就是一秒了,这个呢,是我们的半个小时,哎,30分钟就是这样的。啊,那其实啊,大家想想你在刷鞋的时候,你的这个穿log也得刷鞋嘛,对不对,他得刷鞋是这样的啊,还有一个问题,如果你的穿lo太多了,就是它也会导致它的刷写,大家想想是不是这样的,哎,应该是一样的,这个思路上应该没有什么太多的变化啊,就是这样,所以呢,我们需要大家能够明白的就是说我们的refresh,我们的flash这些操作,其实目的很简单,就是能够保证数据安全的同时,还能够让我们的性能得到提高,这样的话,我们可以在文件当中就进行我们的数据的处理,还可以在内存中做数据的查询,这不挺好吗?对不对?同学们,那还有一个问题,如果我们不断的在刷写,不断在刷写的话,你这个Dis这个磁盘文件不就会很多吗?对不对,它可能就会很多呀,可能就不是一个两个了,就可能会很多了,那么在这种情况下,我们还需要考虑一个文件的合并问题。
15:15
什么意思啊,把这些我们的文件段啊,给它合并在一起,这样的话减少咱们文件的数量,你的效率也可以得到提高,而且咱们之前不讲过了吗?我们这个倒排索引是不可变的,那就意味着每一次的更新,每一次的删除,其实它都会体现在我们新的索引段当中,而且会增加delete文件,那么在这种情况下,我们合并的时候,就会把那些数据真正的删除,这个咱们之前给大家提到过,大家还记得吗?所以啊,在整个过程当中,我们这里又有refresh,又有SH,其实还有合并的概念,哎,稍微的就有点复杂了好不好,同学们,这个呢,咱们就说到这里啊。
我来说两句