00:02
好了,那我们就继续往后研究了啊呃。大家再来想想啊,就现在我们把这个精确一次做完以后啊,应该是这个,就是先保证你这个数据不丢啊,把这个做完以后,大家想想我这个代码现在还有没有什么问题。就现在我们有没有真正的做到这个数据呢,可以保证它不丢。大家琢磨一下。啊,这个问题其实其实我们这边还会有一个问题啊,这个问题隐藏的就比较深了啊呃,就是一般可能会这个想不到哈,我们就一起来这个分析一下吧,呃,其实上午我们研究的个就是后置提交偏移量啊,那我们为什么后置提交偏移量呢?就是要保证你的数据不丢失。对吧,就从我们整个的这个流程角度来讲,其实我们这样这样这么去做呢,已经是非常非常OK的了。啊,非常OK的,就是我在你把数据写到卡不卡之后,然后呢,我再去提交这个offset,这个也是非常OK的了啊,但其实这里面的话呢,还会有一个小问题啊,这个问题就呃隐藏的比较深了啊,大家想想。
01:11
我们说把数据写到卡不卡,然后呢,再次去提交opposite。那我们从这个代码层面来做的话呢,我们只能是保证你写出卡不卡的这个动作,你看了哈,这是写出卡不卡吧。这也是写出卡不卡对不对,然后这个是写出卡卡,然后呢,这也是写出卡不卡,我们只能是保证你写出卡不卡的这个动作执行了以后,然后呢,最后呢,再去执行我的。Offset提交。对吧,就说白了,从你的这个代码层面来讲的话呢,确实你是先执行的往卡夫卡写,然后呢,再执行的什么提交这个offset。是这样的吧。对不对,从流程上来讲没什么问题,但是呢,你仔细琢磨一下啊,现在其实我们还不敢完全保证数据是真正的写到卡不卡的。就是你看的是代码上面它就执行了,但是他有没有真正的把数据就给你写,写到卡不卡写成功了呢?这个是不敢保证的。
02:06
那么这里面我们会涉及到一个什么问题呢?涉及到的是一个卡不卡写数据的一个流程,诶对了,有同学说到是这个落盘这个事对不对啊,那我们需要去分析一下这个卡不卡写数据的一个流程啊,这个卡不卡写数据啊,比如说我这个作为一个生产者来讲,把数据呢,发送给你的这个,呃,就是卡不卡。他是怎么去处理这个数据的。他是直接就把这个数据给你这个写到这个磁盘中了吗。写到你这个分区的那个磁盘里面了吗。是不是啊,同学们,你想想这个事儿。啊,其实不是的啊,大家应该都有印象哈,就是个卡不卡这个写数据那个流程。对吧,来这个我们简单画个图看一下啊。好,简单画个图,我们一起来这个分析一下这个事儿啊。呃,这个是之前的,我来重新新建一个啊,呃,不用新建的,我记得我们之前有啊,我来找到它啊,对吧,把这个打开啊。
03:11
呃,打开以后我们一起来这个分析一下啊。啊,这个是之前的,我就不再说了啊,我们来做一个重新新建一个啊。呃,来,这就是我们的这个Spark这个实施项目啊,好来,那我们先说这个事啊,就是卡不卡这个写数据的一个流程啊。卡卡不卡这个,呃,写数据流程啊,就是卡夫卡的一个这个生产流程吧。对吧,生产的这个流程啊,生产呃消息发送吧,啊消息这个发送流程啊黑。好,那首先的话,我们得有一个得有个啥呀,我们得有一个生产者是不是好,那我们来拿一个这个生产者啊,把它拿过来。
04:02
好,假设这是我们生产者啊呃,生产者好,呃,那我们这个生产者的话,我们要去这个发送数据。对吧,那你发送数据的话,你要往你的某一个topic里面去发送数据啊,那我们就来这拿一个这个topic过来啊,假设这是我们的这个topic啊,呃,这样啊,好看一点啊,我把它这个放到上面啊。行,这是我们的某一个topic啊呃,那我们的这个某个主题的话呢,它可能会有什么呀。这个某个主题啊,它可能会有这个多个分区,是不是,那我们就模拟多个分区吧,啊大家拿一下,比如说我们有这个三个分区啊,三个分区叫这个partition好杠零。OK,再来一个什么partition杠一啊,好,再来一个partition杠二。可以吧,就是我们总共有这个三个分区。
05:01
好呃,那现在的话,我们就要把这个数据呢,往你这个卡不卡的这个分区里面去发了啊OK,那你说我在发送的时候,我这个生产者啊,我要去这个发送这个消息,对吧,我有这个很多个这个消息要去发送啊,我们画一个这个箭头。好,我们有很多消息要去发送来,我再去拿一个这个表示我们的这个消息啊,Msg message啊。好,这是我的消息啊,来,我们就复制几个吧,对吧,能表达这个意思就行了啊。就是我有很多这个消息呢,要去做这个发送发送啊,我就这样画吧。对吧,这样来画啊。好吧,就这样啊,我给你要什么发送很多个消息,那么大家想想啊,你说我这个消息我是直接就哦发到你这个对应的这个什么分区里面了吗?同学们。
06:00
是这个过程吗?不是吧啊,它不是这个过程的啊,它不是这个过程的,它是怎么做的呀,首先啊,我们在这个往分区里面去发送之前呢,它的这个消息呢,其实是先会什么,先会发送到我们的一个就所谓的什么缓冲区的,对不对啊,它其实呢,是有一个什么呀,是有一个这个缓冲区的。对吧,我把它拿过来啊,这个东西我们就叫做那个什么缓缓冲对吧,缓冲啊,缓冲吧,缓冲啊。Bach啊,我们就叫Bach吧,对吧,它其实是有一个这个Bach好,那我们这个Bach的话,它里面为什么会对应我们这个每一个partition,就是你的每一个分区呢?我都会有一个BA啊,那就是我这个partition就是BA扯杠零吧,对吧,我的零号分区的一个BA扯,这是我这个一号分区的一个BA啊。啊,这是我这个二号分区的一个BA,然后呢吧,然后接下来你这个消息往过去发的时候呢,就是它会什么呀?呃,走一个什么,走一个这个分区器啊,就其实这个过程中的话,我们会有一个这个分区器啊,那这个细节我就不说了啊,他为什么经过你的分区器,经过你的什么序列化器等等一些,最后呢,就会决定了我这个消息啊,到底要往哪一个分区里面去发。
07:12
对吧,那比如说呃,我把这个颜色呢,稍微这个改一改,比如这个改成一个。对吧,我们这个对比的去看啊。好对比着去看啊行就这样,这是我的这个三个区,那我这个每个消息啊,比如说我会经过计算,那么假如说我上完以后呢,我的呃,这样吧,我这个颜色我就不动了,好吧,我把这个这个改一改啊,这个改一改。啊,这是一个蓝的啊,然后呢,这是一个。啊,这个再来一个颜色啊,行吧,就这样啊,你看啊,那我经过你这个呃,分区去计算以后呢,那我这个消息呢,算出来,比如说假设啊,这个消息呢,是要发送到这个二号分区的,对吧,然后呢,这个消息呢,是要发送到这个。这个零号分区的好,那么同样这个消息的话,就要什么假设啊,它是要发送到什么这个一号分区的。
08:05
对吧,啊,当然这个我们只是一个假设的情况。能听懂我的意思吧,我们只是一个假设的情况啊行呃,那我这个刷出来以后,你要往哪个这个分区发送以后呢,它其实呢,还不会什么直接往这里面去发,而是什么呀,而是呢,先发送到你这个BA里面,等你这个发送到这个BA里面以后呢,诶,它才会什么再把这个消息呢,从你的BA里面拿出来,然后呢,发送到你这个对应的这个分区里面。这个大家应该都是知道的哈,对吧,这个过程我给你这么简单画一画啊,你要这个明白这个过程。这个没问题吧,同学们好,那么你这个事情知道了以后呢,接下来我们就可以去分析一下了哈,在我们当前这个项目中,我们存在的这个问题你看好了啊,我们现在是做了这样的一个操作,我们从代码层面,我是先去往出写了,然后呢再去做了什么opposite提交对不对?来我们说一下啊,我们的代码层面。好代码流程啊,代码流程是我们先去执行了,就是卡不卡的一个什么散,对不对,那么这个完事以后呢,我们再去什么做的,就是opposite的一个什么提交。
09:12
这个大家能看懂吧,这是我这个代码的流程,OK,好,但是呢,我们认为是你做了一个发送消息了,比如说我把这个消息呢就发走了,对吧,发走以后呢,紧接着接下来我就去什么做这个opposite提交了,那么大家想想啊,它这里面有没有可能存在这么一种情况,就是我调用了这个send以后呢,我的消息呢,确实也发走了,但是呢,它仅仅只是发送到了你的这个败里面了。就目前而止呢,目前的话呢,他还没有真正的把消息呢,写到你的这个topic中,就说白了,这个流程呢,还没有走对吧,还没有走,但是呢,因为你从这个代码流程角度来讲的话呢,他已经调完方法了,那调完方法以后呢,那我就什么紧接着我去提交这个off了。那么假如说诶,你的消息呢,还没有真正的发送到你的这个topic中的时候,我就把oppositeet给他提交了,对吧,这个off已经提交成功了。
10:02
那么这个时候,哎,比方说我要触发了什么,触发你这个拜师的消息呢,要往这个塔梯上去送了。那么这个时候,假如说我的卡不卡呢,因为一些情况呢,坏掉了,对吧,卡不卡呢,因为某些情况什么挂机了啊宕机了。就是这个消息呢,没有真正的去发送到你的这个帕提声里面,那么大家想想,如果说存在这种情况的话,是不是还会导致我这个消息其实没有真正的写入到你的卡不卡呀,对吧,你只写到我这个缓存里面的,那你写到缓存里面,你还没有做落盘的呀,那你没有做落盘的话呢,如果说我的这个整个卡不卡的这个集群都故障了。那你这个数据可能就没有了,但是呢,我们的opposite呢,还是提交了的,那我的OPPOSITE1提交。对吧,我的一提交,然后呢,你的数据呢,又没有写成功。那这不就又漏掉数据了吗?对吧,是不是又出现一个漏消费的问题了呀。能听明白这个过程吗?同学们啊,所以说你把这个过程一分析啊,那你就会知道,其实我们目前我们这个代码中啊,它还存在一个问题,就是卡不卡这个消息发送的一个问题。
11:07
什么导致的这个问题呢?就是这个缓冲区导致的这个问题。明白吧,啊呃,那这个问题的原因呢,就是因为我们卡不卡它这个现在发送的方式啊,就这种发送的方式,它默认采用的都是什么呀,异步的方式来去发送的,当然我们也知道它有同步的方式,对吧,但是呢,如果说我们不干预的话,它都是什么,都是一个异步的方式,那么异步发送的话呢,它会先发到这个缓冲区中,然后等到你这个缓冲区写满了,或者是到达指定的时间了,这个时候才会真正的把数据呢刷到你的这个block中。那这里面有个条件,一个是写满了,或者是一个什么达到指定的时间了,那这两个条件我们之前在写这个卡不卡工具类的时候呢,我也给你提到过,对吧,大家应该还有印象哈,我们再来看一下。呃,一个是找到我们这个生产者啊,就这两个对吧,一个是你的bad side,一个是你这个link Ms,这就是如果说你的缓冲率达到这么大了,那我的消息就要写到你的这个磁盘中,如果说诶,我超过这个时间了,那我这里面的消息呢,也要拿出来,然后呢,往这个磁盘里面去写,就它有两个条件。
12:09
对吧,那你毕竟是你是有这个条件去什么去控制这个事情的,那就有可能我们在整个流程中,你的两个条件的都没有满足的情况下,你的消息呢,还不会往他那面去写,但是呢,我的offset已经提交了。那等你满足了这个情况了,你再去写的时候呢,诶我的整个卡不卡故障了,那数据就没了。对吧,数据就没了啊,所以说呢,现在就会存在这个问题,那下面就对这个问题的一个描述。啊,那你把这个清楚以后呢,你就会发现我们这个辛辛苦苦对吧,从各个方面,然后呢,想方设法的去解决,这个就是精确一次,我们先做到了这个不丢数据,对吧,我们耗费了这个很大的精力,然后呢,专门自己去定制了一套这个opposite这个管理方案,目的呢,就是为了能够后置提交这个offset。对吧,但是最后呢,你发现被自己人给摆了一道是不是啊,被卡夫卡给摆了一道,没想到这哥们还会背后捅我一刀。
13:04
对吧,没想到有这个问题是不是啊,行吧,不过这个倒也不严重哈,我们是可以解决的啊行,那这个问题提出来了,提出来以后呢,接下来大家想想这个问题呢,应该怎么去解决。好吧,大家思考一下啊,这个问题怎么解决,那这个问题的话,我就先呃分析到这儿啊。
我来说两句