00:00
行,同学们好好跟着我来听了啊,接下来这个问题我不知道大家有没有想得到啊,就刚才我一直在说啊,我们认为。你的order info和你的order detail,它们两个的数据是一定能够关联成功的。对吧,因为本来你们就是有关系的啊,那么这个是从你的数据库层面来去讲的,就是我的数据放到我这个数据库里面以后呢,你就去关联吧,一定是能够这个关联成功的。对吧,比如说你的这个order detail,然后你的这个order in for order detail。打开表对吧,这是你的auto detail,然后这是你的auto info,他们一定是能够这个关联成功的。能明白我的意思吧,但是呢,注意啊。但是啊。你到了刘中?就不一定了。啊,你到了留中就不一定了。为什么不一定呢?因为你流中再去做关联的时候,你就想想你的数据是怎么来的啊,这是我的一个流,这是我的一个流,我的数据是源源不断流过来的。
01:02
对吧,那这个时候就会有个问题,如果说诶,我们正好采集了一个周期的数据。对吧,这是你的五秒钟的数据,这也是他五秒钟的数据,假如说诶,正好你的order info的数据和你order detail的数据都在同一个批次出现了,那他们两个一定是能够关联成功的。但是,你就敢保证他们的数据一定在同一个批次出现吗?不敢保证吧,有可能诶,我刚刚下了一个订单啊,这个订单的话呢,我总共有五个明细,那就说白了,这里面我会有一条数据,这里面会有五条数据。对吧,五条数据,那我就开始往过流了,那恰巧我的order info的数据我进入到了这个批次中,我有一条数据,但是呢,因为我的明星呢,有五条数据,诶我在采集的时候呢,我正好在这个批次中,我采集到了四条数据。有一条数据呢,没在这个批次,它在下一个批次在这个位置呢。那么你的这个order in for跟你的这个order detail,你能关联成四条数据,这条数据你在下个批次关联的时候,你发现诶,Order detail是有的,但是呢,没有order info。
02:10
你就关联不成功,那这个时候这条数据就没有了。能听懂我意思吧,这条数据就没有了,好所以说啊,他现在存在的问题你不能说,诶我自己测一下,我看的说那你数据没问题啊,对吧,我看了也是36条数据。不一定的。啊,比如说我们稍微搞点搞点破坏,你就能看到这个效果了啊,那我就人为的让这个数据呢,会有点延迟啊,你看一下这不是我们的,呃,分流数据嘛,来,我在分流的时候呢,我故意啊注意我故意呢让这个。这是我的事实数据对吧,那我在分流完以后呢,我故意啊,就是判断一下,如果说你的表的名字,你看我不是有这个表的名字吗?Equals,它是这个all detail。对吧,他是一个奥detail,那我就。
03:04
睡上一会会。对吧,我故意让我这个auto detail的数据能让他什么。走的慢一点,就是模拟一个延迟啊来这是这个模拟这个模拟延迟啊,数据延迟。然后来吧,啊,模拟这个数据延迟OK,行,那有了这个延迟以后,我们就再次呢做一些测试啊,这个你需要这个测一下啊,看你这个把字重启一下啊。就看你这个,呃,这个这个这个幸运不幸运了啊,如果你运气好一点,这个一次就测出来了,如果运气不好,你可以那什么多测几次啊,如果说实在抽不出来,你把这个时间往大了去调一调,OK吧,行,现在提起来了啊,提起来以后来我们再次去生成数据啊,同学们再跑数据。等这个数据跑完以后啊,那我们就先到这里面,我们去做一个关联啊,看看多少的数据啊,诶我的so口没了是吧,刚刚不小心点了一下,那我这个重写一下吧,拉的心啊好from我们的order info,我叫OI对吧,然后呢,装引上这个all detail,我叫OD啊on OI的ID等于OD的order ID好来跑一下。
04:18
51行数据能看到吧,51行数据啊,来到这个流里面看一下流里面。呃,往下翻啊往下翻。啊,这是刚刚的那个那波数据啊找一下。诶,你看现在还行啊,它也是这个51行数据,是不是说这一次你有没有测出来啊,没测出来呢,再测呗,多测几次啊。多测几次。如果说这个实在测不出来的,你就把那个时间呢,再往大了稍微调一调啊。嗯。这个其实那个时间啊,要刚刚卡到它那个就是采集批次的最后那几秒钟啊,最后那几几毫秒钟就可能会错位了啊行来看一下啊,这个数据已经过来,过来以后我们再来查一下。
05:05
呃,47行啊。这应该也没啥问题。我觉得。哎,这个出问题了啊,你看一下。45了吧,是吧,你看数据都选上了啊,数据你看啊,前面没有啊,你看从这开始选。好,一直到下面看一下四十五行。对吧,但是呢,我的数据库里面呢,你查一下47行。丢了吧,丢了两条数据啊,那么这就是我们在做这个双流招引的时候啊,一定要去注意的一个问题,我把这个句问题给大家去描述一下啊,呃,注意啊,就是这个是从你的从从我们这个数据库层面啊,能理解吧,好,但是从这个流层面,就从我们这个流处理层面啊,因为什么呀,就是因为order info啊和什么呀,和这个order detail好是两个是两个流,明白了吧,而硫的招引。
06:17
留的这个招引啊,只只能什么,只能是,呃,只能是同一个批次的数据。才能什么进行招引,OK吧,那也就意味着如果,如果两个。表的数据进入到不同批次中,就出现什么招就就会什么招,易不成功,明白了吧?所以说啊,你从数据库层面,这个一定是能够装新成功的,但是呢,你从流程面来讲就不一定了,它会错位。对吧,你们没有在什么,没有在对的时间内遇到对的人。错位了对吧,这个弯跑到这儿了,而你是在这儿。
07:01
啊,还有可能就是他他们都跑到他们在同一个批次里面,然后呢,你呢,你能跑到下个批次了,都有可能啊,就是可能是他先到,可能是你先到。对吧,都有可能啊,就会这个招音不成功,OK,好,那你这个招音不成功,我们现在问题是什么?问题是因为你招音不成功,反而丢数据了,对不对?好那么这个注意啊,数据延迟。导致的数据没有进入到同一个批次啊,在这个流在实时处理中啊,实时处理中是。正常现象你能明白吧,那你说这个数据延迟,我我还能决定说你这个不要给我延迟啊,这个你决定不了的。明白我的意思吧,这个你是决定不了的啊,所以说这个数据延迟导致的数据呢,没有进入到同一个批次,在实时处理中是正常现象啊,那我们可以接受,可以接受,因为延迟导致最终的结果延迟,这我是可以接受的,因为你前面比如说我整个处理过程中,比如说预计我三秒钟处理完了,但是你在中间的某个环节呢,你这个延迟了两秒钟。
08:15
对吧,那最后你整个处理完成,你你变成了五秒钟,就是你最后的结果呢,你也延迟了两秒钟,这种情况我是可以接受的,因为你本来你前面就慢了,你慢了以后呢,那我就只能是什么接受了呀。对吧,这个没啥问题,只不过就是你的结果慢了一点点而已,我算出来结果应该也是正确的,但我们接受不了的是什么呀?就是我们不能接受啊,因为延迟导致的数据丢失,就比如说我们目前这种情况。我确确实实是因为数据延迟了,你没有跑到什么同一个批次里面,然后呢,导致我这个数据的延迟,导致这个数据呢,最后什么丢失了,我这个正常关联起来是47对吧,刚刚是,然后你现在看到你是45,那就丢了两个数据。
09:03
对吧,这种问题啊,大家注意,这种问题隐藏的很深,隐藏的很深,你能明白吧,因为大多数情况下,我们的数据呢,它都很很很少会出现延迟,理解吧,就比如说我下单啊,你说我下个订单对吧,那我立马就会什么更改你的订单表,更改你的订单详情表,这个一定是会在什么呀。就是秒级内,就毫秒级,甚至于什么毫秒级内我就完成了一个操作,那你毫秒级内完成的操作,我经过我的什么Maxwell去采集,对吧,经过传给卡夫卡,再传给什么Spark streaming,就是经过层层处理,这个时间啊,肯定不会超过五秒钟的,你能明白吧。他一定会在同一个批次中,所以说你正常情况下你是看不到这个数据丢失的,而且呢,就算数据丢了,他也能够什么正常给你计算出来一个结果,但这个结果肯定是不对的哈。你能明白吧,所以说这种错呢,就比较恶心。因为它你的代码还能正常执行,我也能给你正常出结果。
10:04
然后丢了数据的。如果说你不仔细不看那个数据结果的话,你也发现不了这种问题。因为它不会导致你代码报错。对吧,反正就是给你统计的结果呢,不对啊,就是偶尔呢会诶少点东西,偶尔呢统计的会少一点,偶尔统计的会少一点,有时候呢还是正确的。啊,你就会很纳闷,你说我这个代码他也这个看心情是吧,有时候给我统计是正确的,有时候统计是错误的。啊,其实这种问题在这个代码中如果存在的话呢,如果你还想不到,但是你发现了我的数据,有时候对,有时候不对,你就很头疼。对吧,你得去排查你整个的计算环节,到底是哪个环节出现了这个问题。理解吧,啊,不过现在还好啊,我们这个已经想到这个问题了啊,好,所以说呢,你看一下啊。那你既然存在这个问题了,我们的代码呢,就不能这么去写了啊同学们。怎么写代码有问题,因为啥呀,因为这个招操作,他就是招成功的,我就把结果留下来了,招不成功的数据我直接不要了。
11:09
那不就导致你数据丢失了吗?对吧,就直接导导致你的数据丢失啊,所以说呢,这个招引啊,你是不能用的。OK吧,就是相当于从你的数据库层面来讲,你用他们几个随便都OK,因为我能够保证你的数据肯定能够装移成功,但是到了流程面以后呢,就不是了。对吧,这不是数据的问题了,是你这个延迟的问题了,延迟导致我的数据呢,没有进入到同一个批次中啊,没有在对的时间遇到对的人。OK吧,那你就不能再去这么用了啊,所以这是有问题的主食药吧。那这个有问题的话,大家想想我们应该用哪一种。来去解决这个问题。这两个行不行?
12:02
这两个行不行?注意啊,这两个也不行,因为啥呢,因为它。有一个表要去匹配。只要你是取匹配,就表示他一定会有一些数据是不要的。那这里面我们是坚决不允许不要数据的,你所有的数据我都得要。所以说我们只能是用它。能明白吧,我们用它的话呢,能够解决一个大问题,就是我不会轻轻易易的把数据给你扔掉,就算你招一不成功,这个数据呢,我也给你留下来了。听明白了吧,我也给你留下来了啊,就是你在结果中我还是能看到这个没有招音成功的这个数据的,如果说你用的是前面几种,那你当前你招音不成功,结果中就没有它了。那你结果中都没有他了,你后续你再想挽留,你也挽留不了了,像这个的话呢,我们在结果中我是可以保留下来我这个结果的,就是我这个数据的,对吧,没有交易成功的数据的,那我就可以在后续呢,再去想办法把这个没有招易成功的数据呢,再次去做一个处理。
13:07
对吧,所以说啊,你这么一想,我们应该使用for after drawing。理解吧,啊,但是你光使用它也不行啊,你没有装印成功,就是没有装印成功,那你不能说我把没有装印成功的数据,我也直接写到这个ES,那你写到ES以后,将来你分析的时候发现这里面数据只有一半。对吧,并不是一个什么非常完整的数据。那也不能用啊。是不是啊,所以说呢,我们先用它呀,先保证这个数据呢,能够全部都给我出现在结果中,然后呢,我们再针对没有装移成功的数据呢,去想一个解决方案,把它做一个解决不就OK了吗。对吧,来说说啊,下面我们要把这个代码呢,给他做一个更改啊,嗯呃,我先停一下吧,我们这个分开来说啊。
我来说两句