00:01
OK啊来我们接着说啊呃,那到现在的话,我们的这个。基本的分流工作就已经完成了,能听到吧,哎,就已经完成了啊,嗯。那这个代码功能是写完了啊,就是你这个我们想象的这个功能啊,还是来看这个图整治架构啊,就是我们想象的这个功能,就已经把它这个完成了。啊,但其实我们在这个实际做开发的过程中啊,大家注意你完成基本功能。其实都比较简单。啊,问题是你完成这个功能以后,你要去思考一下你的代码,你要去斟酌一下你的这个代码。看看他有没有什么问题。啊,看看有没有什么需要优化的地方。这个工作也是我们需要去做的啊,同学们你可不你可不能说,诶你看我这个功能都通了啊,我这个数据能正常写过去了,那你就觉得这个大功告急了,对吧。其实不是的,因为你测不出来它有什么问题,对吧,所以是你要去什么,去斟酌一下你这个代码有没有什么可优化的点,或者说有没有什么需要解决的问题。
01:06
啊,当然如果说我们有这个测试的话,那你可以怎么让让让测试的帮你去测一下,对不对啊,是不是啊,但是我觉得对于我们这个实时项目来讲,可能这个测试。现在好像也没有人帮你什么专门去做这个测试,对吧,那还是需要我们什么自己去琢磨琢磨。对不对啊,所以这也这也就是怎么大家这个以后写完代码以后呢,有一个过程什么,这个过程就是什么去优化你的代码啊,去什么解决一些什么可能存在的一些问题,好吧,来接下来呢,我们就来做这个事儿啊讲。呃,那这里面的话,我们来,呃分析这么几个问题吧,啊,分析这么几个问题啊,首先第一个问题。我们来看这个数据的一个处理过程啊呃,那我还是看这个图吧,你说我们现在啊,我的Spark streaming从你的卡不卡中把数据消费过来,然后呢,接下来呢,把数据写到我的下一层,写到卡布卡中。对吧。
02:00
这个地方是不是有一个消费的一个过程。是不是是不是有个消费的过程啊,同学们好,那我之前在这个给大家去聊卡夫卡的时候就说过,只要你涉及到消费的过程。那你就会涉及到一个维护的问题。对吧,就是提交了一个问题,这个是一定要跟你什么,跟你的这个消费仅仅。挂钩的啊好,那你想到这个的提交问题。你就得想到。跟提交。相关的两个问题,一个是重复消费,一个是消费问题。对吧,这是非常敏感的啊,就是你看到诶,我要去消费你卡不卡的数据了,那这个时候我就立马要想到我的ET应该怎么提交,我的offet应该在什么地方提交。对吧,会不会导致重复消费,会不会导致漏消费。呃,以后你甭管在什么地方用卡夫卡,只要你从卡夫卡消费数据这个问题,你都得在你的脑子里面去过一遍。
03:02
啊,你问一下自己有没有可能出现重复消费,有没有可能出现漏消费。你的代码中有没有考虑过这个问题?能听明白吧,同学们啊,来,这是我们要研究的第一个问题啊,那我们就先把这个问题呢,给大家这个去研究一下啊,琢磨琢磨啊,其实我们目前这个代码中确实存在这么一个问题啊,来大家想想。如果说啊,我现在呢,从它里面去把数据消费到了。啊,就从他里边把数据消费到我这个实时的这个处理过程中了,然后呢,我就开始去做这个分流啊,去做转化,去做分流,然后接下来呢,我要把数据往出写了,往卡写了。对吧,假设啊,同学们假设我的数据呢,都成功的写入到卡不卡了。那这个时候呢,诶,我要去提交opposite了,因为我们的opposite是什么呀,它自动提交了,对不对,诶它是自动提交的。好,那我自动提交的话,比如说正好,诶你把数据都写完以后,我要什么自动提交了。但如果他提交失败了呢?
04:01
这个时候会造成什么现象?对吧,你想想。还有一种情况。就是我把数据呢,从你的卡夫卡中,诶消费出来了,我还在处理过程中,就是说白了,我还没有把数据往卡夫卡去写的时候,诶我的offset正好到达这个时间了,我提交了,他呢提交成功了。但是我接下来把数据往这个卡夫卡去写的时候呢,诶出现问题了。我数据没有成功的写到卡不卡。对吧,那这个又会导致一个什么问题,你想想。啊,这个不就是非常典型的重复消费和漏消费问题吗?对不对啊,所以说你这么一分析,你就分析出来了啊,所以说来看吧,接下来我们讲的就是一个优化啊优化,那我们想优化成什么,我们想优化成精确一次消费,这个一定是我们要去追求的,就是你从这个卡不卡的消费数据,我一定要做到什么,做到精确一次,就是你的一条消息,我只有可能消费一次,我不可能说诶消费零次,或者什么消费两次,消费N次。
05:05
对吧,消费零次那叫什么漏消费了,消费了什么多次,那就重复消费了,我都不接受,我接受的是精精确确的只消费一次,能不能听明白对吧?这是我们要去最终要做到的一个效果,好,那接下来我们就分析一下跟这个精确一次消费啊相关的东西。首先有几个语义啊,有几个相关的语义,这个大家可能之前也听说过啊,第一个叫什么叫至少消费仪式。啊,第二个叫什么,最多消费。最多消费一次,或者什么最多一次消费都可以啊,然后最后一个就是什么精确一次消费。好,那么先明白一下什么,至少消费一次啊,至少一次消费就说白了啊,我的数据啊,我最少最少得保证消费一次,那也就说白了,他有可能会消费多次。因为我保证的是你只要消费过一次就OK了,对不对,他有没有管,他说那你消费两次消费三次行不行啊,他没有管这个事。
06:00
理解吧,所以说呢,你要保证这个至少消费一次,那我就可以保证我的数据是不会丢失的,我都能够消费到,但是呢,有可能会出现重复问题。对吧,这就是这种语义啊,它所表达的含义好,那么同样你最多消费一次。我管的是你的上限。对吧,就是我的一条数据,你最多最多只能消费一次,那你是不可能消费到两次或者三次的,因为我管的是你的上限,你最多消费一次,但是呢,他没有管下限,就说白了这个数据我有可能消费不到。对不对,我有可能消费不到啊,那么这种情况下,我能够保证你的数据绝对不会重复,你不可能重复消费,因为我管的是你的上限,但是呢,有可能会导致数据丢失问题,就说白了,这套数据我有可能没有消费到。对吧,这个是最多消费一次这种语义,它所表达的含义。那么这两种情况的话,在我们这个,呃,平常这个写代码过程中,我们都会遇得到啊,都会遇得到,但是这两种情况的话,哪种我们都可能接受不了,那我们能接受的应该是最后一种叫精确一次消费。
07:08
就是你的一条消息啊,不多不少,刚刚好就被处理过一次啊,这是我们想要去追求的。能明白了吧,那如果说你达不到这个精确一次消费,那你就绝对会出现上面这两种情况中的任意一种,比如说你重复消费了,或者说你漏消费了。好吧,先把这个相关的语义啊给大家这个提一下,这个语义你们之前应该都听说过吧,以后人家再说到这个什么精确一次啊,什么至少一次,最多一次,你要明白他说的是什么意思。OK吧,行,那你把这个知道以后来接下来我们就来说我们当前这个项目中的问题啊。我们当前项目中就存在漏消费或者重复消费的问题。这两种情况都有可能存在啊,因为什么呢?因为现在我们的OB呢,是交给什么卡不卡自动去维护,并且什么是自动提交的,那你是控制不了他提交的时机的。
08:04
那么他就有可能在你数据写出去之前去提交,也有可能在之后去提交。你这两个位置,如果你控制不了,那就可能可能会导致。精确,呃,就能可就可能会导致你的重复消费或者什么漏消费,这放到语音里面就是至少一次,最多一次。明白吧,来看一下啊,我们先来说我们这个漏消费的问题啊,我给大家画了一个图啊,这个图我们可以打打开来看一看,就其实跟我刚刚分析的是一样的啊。我们先把问这个问题给大家这么分析出来啊,分析出来以后我们再来去想这个解决方案哈,好来,还是回到这儿把它打开你看一下啊,目前我们这个漏消费的问题,我们从你的卡夫卡中,然后呢去消费出来数据,然后接下来呢,我去做这个数据的一个处理,好,那我处理完了,处理的时候呢,我要什么提交outside对不对。处理完我要去提交offset,然后呢,接下来呢,我要把数据呢,写出到我的卡卡,比如说我要什么再写出到我的卡夫卡,或者说呢,我要写出到别的,别的主将都OK啊,我要写到red对吧?我要写到什么H啊,别的主角都OK。
09:07
好吧,反正就是一个是提交,一个是写出,因为你的数据真正的写出了,或者说真正的经过计算了,计算完成了,得到结果了,这个才叫做数据处理完成了。那目前我们的数据处理完成的一个衡量标准的就是你把数据成功的写入到下一层,这叫什么?数据处理成功了,你前面甭管做了什么操作,这个都不算,因为我的下一层没有结果,我就不算。对吧,所以说我的问题就卡到了这两个点上,假设我先把opposite提交了,就假设这哥们是提交成功的,然后接下来呢,我说那你就把数据写出吧,但是呢,我在写出数据的时候呢,失败了。能明白吧,好,那你想想你的数据呢,写出失败了,那我的下一层我就拿不到你的数据。而你的offset就提交成功了。那么对于卡夫卡来讲,他是怎么认定我的一条数据就处理成功了呢?
10:02
对吧?你从我卡夫卡中消费出来的数据,卡夫卡是从哪个层面去认定你消费到的这个数据已经处理成功了呢?他就是从你提交奥赛才去认定的,如果说你把奥提交了,他也收到了,卡普卡也收到了,那么他就认定你当前消费出来的这一波数据已经得到成功的处理。那么。他就不会再给你往出发了,就这个数据你就不可能再消费到了,能听懂吧,所以说你看一下啊。既然你的opposite也提交了,但是我的数据没有写出成功,那你就甭指望了,说他把这个数据再给你发过来一次,这个不可能好说,说这样就出现一个什么问题啊,你先提交了oppositeset后写出了数据,你的提交是成功的,写出是失败的。对吧,那么数据呢,是不会重发的,因为我提交offset了,所以说呢,我就造成了漏消费问题。因为对于我的下游来讲,我其实是没有拿到你的这一波数据的,那不就漏掉了吗?相当于对吧?所以说漏消费是怎么造成的呢?漏消费造成的原因就是先提交了opposite后写出了数据,就造成了漏消费。
11:12
明白吧,好,那怎么解决这个问题啊,同学们啊,有同学立马想到了,那还不简单,你把它再调一下。对吧?对,如果你把他们调一下,那这个问题就得到了解决。好,那我们就来看下一个。重复消费问题对吧,来过来把它打开。你看了啊,现在我是这样子的,我先把数据写出去。对吧,我保证你数据写成功以后,对不对,什么叫写成功了,就是你不报错,你这个代码都成功的执行完成了,然后我再去提交。对吧,这样的话你想想啊,如果说你的数据写出据是失败的,就是你你代码执行到这以后就失败了,失败以后因为我还没有提交opposite了,对不对,你的代码整个都失败了,那我的提交opposite肯定也不会执行了。
12:00
这种情况下,对于卡夫卡来讲,他认定你当前的这一波数据是没有被成功处理的,因为他没有拿到这个提交的,对不对?能听懂我的意思吧,他没有拿到这个提交的upset,他认定这个数据没有处理成功,那他是会给你重发这一波数据的,就是你,你还可以把这波数据呢,再一次消费出来,能理解我的意思吧,所以这种情况下你就不用担心说我输输出数据出问题了,那我的数据丢的问题不会丢了。你能明白吧,不会丢了好,但是呢,它又导致了另外一个问题,就是重复消费问题。你看啊,比如说我的数据呢,写出去了,但是我写出的是OK的,我是写出成功的,我已经写到了我的下一层,对吧,这个时候我说我要去提交oppositeset了,但是呢,诶我提交失败。那么你的数据实际情况呢,已经写到你的下一层了,它是OK的,处理的是OK的,但是你提交ET失败了,对于卡普卡来讲,他认定我当前的这个批次的数据并没有处理成功,他会再次给你发送一波这个数据,那你发送过来以后呢,诶,我又进行了一次处理。
13:08
那我这个数据呢,又要写到你的这个下一层。那你看看这个就会导致同一波数据被处理了多次。就是数据重复的问题,所以说你看啊,你这种情况下,你先写出出数据后提交offset,那如果说你提交失败导致数据呢,会重发,就会造成一个重复消费。对吧。好,那你说我应该怎么解决这个问题啊?啊,有同学想了,那我把它调一下对吧,调一下不就解决了吗?是解决了。对吧,但是你不就又导致了一个漏消费问题了吗?对吧,所以说啊,重复消费问题。怎么解决呢?你就什么通过什么呀,通过先什么呀,先提交后写出来解决,那么这个玩意儿又会导致一个什么,又会导致一个漏消费问题,漏消费问题怎么解决呢?你就什么先通过先写后提交来去解决,那这个又会导致一个重复消费问题,你这绕来绕去你是绕不明白的,对吧,两个人相互解决,但是呢,又会什么同时又导致另外一个问题。
14:13
这肯定不行吧?对吧,啊,这肯定是不行的啊,所以这两个问题它一定是。呃,不能,什么被相互解决的,你能听懂吧,我们得什么各个攻破啊好。行来这个文字呢,我就不再跟你去说了哈,你这个东西可以自己去看看,就现在大家应该是能够明白我们当前这个代码中所存在的问题吧。对吧。应该是能够理解的哈,啊,那如果说你明白这个问题的存在以后,那接下来你就去想一想,我们应该怎么去解决这个问题。对吧,怎么去解决你的这个漏消费问题。啊,怎么去解决你的这个重复消费问题。好吧,大家这个琢磨一下,大家这个思考一下,OK吧,来这个问题呢,我们就先给大家聊到这儿啊。
我来说两句