00:00
好,那刚刚才想到了,那我们呢,不需要做驱虫,那我就直接开始写代码了,但是呢,呃,在这个里面我们还是多练一点这个驱虫,因为在我们做这个我们现在说的驱虫啊,是第一个对于level join之后的结果做驱虫啊,对吧?这个呢,其实对于我们当前这个需求,我们已经分析过了,我们可以不做这个驱虫,对吧?我们可以不前面做这个驱虫啊,这个没关系啊,呃,但是呢,由于我们的驱虫方案会比较多一些,而且呢,后续的需求,特别这个从这个开始,对吧?时间久我一直在强调这个啊,就越来越复杂了,如果说呢,你前面都不做这个驱虫,包括第二个啊。第二个也是计这个用户数对吧,那其实也可以不去重对吧,我还是统计这个用户数嘛,可以不去重,那么到了这个需求就很复杂了,你又要考虑驱虫。又要考虑其他的对吧事情,而且我们说了这个时间久是相当复杂的一个需求,所以呢,我们可以把这个难度给它拆开啊,比如说现在的去重,我们呢,支付,虽然支付跟下订单这两个呢,可以不做驱虫,但是呢,我们还是做一下,我们提前把这个东西去练一练,那这样的话呢,到了10.9这个需求是不是稍微能简单一点。
01:20
对吧,因为你现在不考虑,我告诉你10.9这个需求,我们要求什么呢?订单数跟订单总金额。要求订单金额,那当你要求订单金额总金额的时候,你告诉我这两个。不去重。能不能行对吧,假如说他还有一个数据金额对吧,二二十三块五,好,那这个呢,也是23块五,因为它是同一个订单明细嘛,那他俩要不要去拢,如果你要求这个总金额的时候,他俩是不是必须要去拢?只保留一条吧,如果你两条都保留了。那不完了吗?你不是double了,你这个金额就不对了。能明白吗?
02:00
对吧,所以呢,呃,虽然我们七八这两个需求在对于这个left join之后的结果,它这个去重呢是非必要的,但是呢,我们在这里边还是保留着这个驱虫逻辑啊,大家要明白我们这样设计,那有的人可能在想。那你这个都不需要了,你刚才说了不需要了,你还写那不浪费吗?对吧,不是这个意思啊,就相当于我们再多练一练嘛。对吧,因为level驱虫呢,我们以前也没有接触过啊,Level join这个东西呢,都是在项目当中。才接触的啊,所以呢,如果说放在时间九,那时间九的难度就过大,对吧,我们想把它的一些功能呢,诶给它摘出来,这样呢就好一些,对吧,这样就好一些,是这个意思能明白吧,啊所以呢,支付我们也要做这个系统,但如果生产环境当中啊,生产环境当中你就不用做了,能明白吧,对吧,就尽量因为你不能去找你少一步操作。对吧,你相当于少一步操作呀,那会肯定会更好一些。
03:01
对吧,啊,那就可以不需要咱们这块呢,是因为课程设计,我们希望呢,把这个呃,一个复杂的特别复杂的需求里边的一些重难点呢,给它择出来。对吧,给它摘出来啊好,那接下来呢,我们就来考虑这个问题啊,就是说这个系统我们到底该怎么做呢。对吧。这个驱虫我们到底该怎么做呢?大家有没有什么想法?我们如何能保证?第二条数据输出呢?啊,关键我还提示大家,呃,我们有可能呢,还有一类这样的数据。还有一种这样的数据,什么数据呢,它啊。比如说1003吧。好,他的数据呢,是这样子的。
04:01
1003啊,这个金额不金额的,其实无所谓的,对吧?啊。这是什么意思呢?就是说这条数据啊,他没有参加活动,也没有领券。什么都没有,那他呢,也就这么一条,对吧,正常照只有一条,因为level没有数据嘛,对吧,你把这个情况呢,都得考虑上,那想一想我们这个驱虫该如何做,也就是说我如何把。这一条。这叫。以及这条数据拿到我只要这三条。对吧,因为我要的肯定是一般来说啊,我们去重要的这个最后一条结果吧,对吧,如果说你要考虑这个事儿,那这个呢,我们应该怎么去做呢。啊,思考一下啊,大家自己想一想,这个东西呢,应该怎么去做,对吧。
05:01
前面呢,它数据这样传过来了,值这个数据你不用考虑,因为我们data stream对吧,啊可以把这个数据。干掉。啊,嗯,因为我们已经转化为空了,你转化为阶层的时候对吧。你直接呢,呃,把这个非阶层格式数据给它过滤掉就好了,抓个异常对吧?啊,这个数据得到好处理啊,那关键就是问题在于,诶,他来了,他来了我要这条,这条不要。怎么做?有没有什么想法对吧,大家可以思考一下啊。啊,可以想一想这个问题应该。怎么办呢?啊,那我们就把这个粘过来啊,有同学提到这个答案说雷总对吧?呃,来,我们把这个看一下。他说什么呢?说写在里边,让这个后来的去代替原来的。
06:00
啊,这个点啊,那我们一个一个来讨论啊好,嗯,那你的意思是这样呗,啊,当然这个大家也能理解啊,嗯,先来的数据呢,把这个写到里面。对吧,好,那后来的数据呢,再来了,那我就再写啊呃,K呢很简单,就是用这个。唯一的键去同对吧啊,就用all the detail ID有没有问题对吧,就是你ready key是不是用all the detail ID啊。对吗?你red key是不是要用all detail ID,对,还不知道可行性,你没有往下想啊,那你写到以后接下来呢。啊。是我我把这个数据写到了啊,我也把这个数据写了啊,然后呢,写这条数据,把这条数据覆盖掉了。然后呢?
07:01
然后呢?你你写到,然后呢。啊呃,然后云总提了一个叫。CP。啊,用CP来做我们的一个驱动,那你CP的规则是什么呢?云总,你说CP对吧?那你能不能想一下这个CP的规则是什么呢?啊,你匹配的CP的规则是什么呢?
08:06
或者说还有没有其他同学有什么思路都可以来表达来说一说啊。对吧,关于这块的一个去除问题。雷总,你可以继续想,你后续呢,你写的你,我的目的不是要写的,我为了驱虫啊。对吧,你写的。干干嘛呢,然后呢。然后又从给他读过来。是吧?那你第一条数据读不读呢?那那你当你写了这条数据的时候,这条数据要不要呢?读不读呢?我问你。
09:13
啊。你第一条数据。在第二条数据之没来之前,好,那如果是这种情况呢,他永远没有第二条数据呢,它只有一条数据呢。所以我我为什么写这个呀,我让你多考虑考虑吧。对吧,雷总你说的在第二条数据没来之前都保留着,那我如果是1003那个订单呢。他没有第二条数据,他只有一条,因为他没有参加活动,也没有去领券,他只有一条,那怎么办呢。对吧,那我刚才写这个白写了嘛,我还特意写这个,你就多想一想啊,对吧,我还特意让大家想这个问题之前我还加了一条数据。
10:04
对吧,啊,然后我们看方总的这个,我把它粘过来啊,还粘过来,粘过来之后呢,大家可以一起来看到啊。他说let join的左表数据有这个过期时间啊,定一个。电视器。啊,在此时间过后,还没有数据来照应的话,就输出此时的数据,右表为now。啊,你这是啥呀。没懂,好像答的不是我们这个问题。我们现在消费的数据没有招进来呀。啊,我大概应该能懂这个方总什么意思了啊,大概的看了一下啊,他应该是结合着前置来说的啊,他说level呢,有这个过期时间。
11:06
啊,有过定时间对吧?好,那这是一个前提啊,这相当于是一个前提条件对吧,那么呢,在我们下游做驱虫的时候,我可以干什么,我可以定一个定时器。啊,我可以定义一个定时器,好呃,那如果说在此时间过后还没有数据来交易是什么意思呢?你看啊,就指的这一条吧。如果说这么长时间都没有来招引,那就没有第二条数据,那就把他自己输出,那如果说方总我继续问你,那有数据来照应了呢,他来了第二条呢,我怎么办?我来了第二条怎么办?对吧。我来了第二条怎么办?就是有两条了,现在有两条,我现在要的就是对于这两条数据怎么去重嘛,对吧,在你不光要考虑这两条数据怎么去重的问题,你还得考虑有没有可能他level抓的数据没有不存在,他只有订单与订单明细,他只有这一条,你也要把这种情况带上去考虑。
12:11
你不能想着他都是。有多条数据的,那其中呢,有的订单,它就这么一条数据。对吧,那我们应该怎么办呢?啊。好,哎,民总说了,利用状态做这个驱虫,后面来的数据。后面来的数据判断状态里边有没有,有的话呢,去掉将新的存进去啊,如果没有的话直接存进去啊,那什么时候输出呢。
13:06
啊,再把明总跟方总两个人的一结合,是不是就可以了?对吧,利用状态编程来做这个驱动,好,首先呢,那我们的。答案就有了,对吧?啊,其中一个答案是这样子的,那我们呢。啊,写一个状态,状态window档的数据放到定时器里边啊,那我们把这个,然后来一条和这个比较比完的那一条,对啊来我们看这个啊,其实就是总结这个,那我们的数据呢,按照首先你要按照all的detail ID进行分组,对吧,因为它是用于驱虫的这个组件。对吧,凹的ID本应该没有重复的,但是呢,它居然出现重复了,所以我们要把它干掉啊呃,怎么说呢,写一个状态,状态为none的数据呢,放到这个。定时器里边。啊,放到电视,放到电视器里边,这有问题了,状态为no的数据放到定时器里边。
14:06
啊,你这个表述的太差了啊,我们重新写一下,就是状态为难的时候。呃,注册定制器吧。对吧,啊呃,状态文档的时候写一个状态,那当然数据存状态啊,对吧,啊数据存状态。对吧,把数据呢,从他状态里边啊呃,然后这样。然后来一条数据和这个比较流管的那一条放大状态。对吧,然后状态为none的时候呢,去注册定时器就好了。对吧,你刚才表述的是什么,放到定时器里边,这个有点害怕啊,就这都疯了,那是还能放在把数据还能放到定时器里边了,对吧,应该是这样子的啊,就是说呢,我们按照订单明细ID做分组,那么接下来呢,我写一个状态。
15:04
对吧,呃,然后呢,来了数据之后,我把这个数据呢,放到这个状态里边。好,然后接下来后面再来的数据,我给你状态里边数据呢,做比较留完的哪一个。对吧,啊,六版的那一条啊,考虑到乱序呢,咱们是不是可以比较一下这个时间啊。考虑到乱序数据问题,咱们是不是可以比较一下时间?没毛病吧,啊,可以比较一下时间啊好呃,那什么时候注册这电视器呢?状态那就第一条数据来的时候我就注册定视器。对吧,我就注册一个定时器,当定时器响了,我就把状态里面数据输出。当电视器出发。对吧,走。诶,走。输出。状态中的数据。
16:02
对吧,电视机响了则输出状态状数据,因为你要知道咱们前面所做的这个join,还有let join。我们是不是都给了?弗join的一个TTL时间,大家还记得吗?对吧,那你那个时间呢,是按照公司当中最大的延迟给定的,也就是说你们数据之间就整个的对吧数据。来的时间应该在这个范围内,那假如说你前面呢给了五秒,那这边呢,我是不是可以注册一个五秒的定时器,因为呢,你前面left join还有join这块给的是五秒的时间,那我觉得你应该做过调研过程当中呢,五秒钟之内,对吧?这些数据呢全部能够到齐,那下游呢,我定时器也给个五秒钟,我第一条数据来到最后一条数据来,是不是应该在五秒之内到齐?是不是应该在五秒,你前面给的五秒嘛,那我就认为你后面呢,也要在五秒之内所有数据到齐。
17:02
对吧,所以第一条数据来的时候呢,我定义一个。定时器把数据呢放到状态里边好,你后续有数据来,你就把状态里边数据呢做个替换,当然比较一下时间,考虑到乱序数据问题,对吧,比较一下时间,把这个时间大的放到状态里边好,最后呢,不管怎么样,定时器呢一定会想D响了以后,你就把状态数据输出就行了,对吧?那如果类似于这种情况,那你输出的第二条,因为它时间更大,如果类似于他。那中间的没改过,就第一条数据来了,你就放在状态里面了,是不是直接把它输出就好了。能明白吗?这是我们说的,对于never join。针对于。Love drawing。出现。重复数据问题对吧?呃,这个是方案一。
18:07
方案一对吧,我们定义一个状态。一个状态啊呃,将。行。数据存入。状态对吧,我们写全了啊,这数据存在状态里边,然后来一条数据呢,和这个进行比较对吧?呃,留晚的那一条放到这个。状态里边啊,留碗的那条对吧,放在这个状态里边啊呃,之后呢,状态为囊的时候。这个用一个分号隔开吧,对吧,状态文档的时候呢,我们去注册这个定视器,当电视器出发的时候呢,我们输出状态中数据,这是第一种对吧?好,那既然刚才我们在说第一种方案的时候呢,已经提到了。啊,已经提到了。
19:01
您提到一个什么点呢,就是我们刚才所提到的在这啊,嗯,你呢,数据过来了,我们可以注册一个定时器,对吧,定时器的时间呢,我们可以把它定死。因为前面类似于这种重复数据,对吧,它出现的一个时间是有限的,不是说哎,未来两天后还会出现这么一条,他不会。对吧,那这个你就实时我不考虑这个数据也可以,对吧,你可能整个数据流卡了,某一项数据卡了两天。那也不可能一条数据卡两天,那你整个的从这条数据往后都两天,那你这个早早该处理了,对吧,这种情况我们不考虑啊,我们搞正常情况,那正常的呢,你应该在。Join所给的TTL时间内你应该到齐对吧,所以呢,我们第一个。电视器。啊,定一个定视器就好了,对吧?好,那既然这种情况的话,我们就有第二种方案了。第二种方案对吧,你的时间是固定的。
20:00
那我们能不能这样呢?呃,开一个窗口。开一个窗口。对吧,然后呢,呃,用使用。全量聚合函数。取出。时间最大的一条数据进行输出。对吧,我们取出时间最大的一条数据进行输出。OK吧,那是不是也可以?对吧,我们取出时间最大的一条进行输出,其实跟上面这个定时器呢一样。啊,跟上面这个定时器其实是一样的。因为DC的时间,那我可以用于开窗。对吧,呃,你用定时器呢,只不过是什么。一条一条的进行比较啊呃,那这个呢,其实我们用增量聚合也可以。
21:07
开一个窗口使用全量聚合函数呢,就是比较使求时间最大的,那这边呢,其实我们可以使用什么呀,使用增量聚合。啊,使用这个增量去换数啊,嗯,每台需要数据保存一次,对吧?啊保留。这个就是保留。这个不叫取出了对吧?啊,每次呢,你就保留时间最大的一条啊,最后呢进行输出。对吧,这个要最后才输出啊,啊这个也一样,这个呢是全量这函数,它是到最后才会触发计算嘛,对吧,这种方式是不是也可以啊,来聊比较一下,我保留时间最大的就行了,对吧?好呃,那这个地方呢,还有。我们把另外两种写一下啊,还有一个什么呢。就是我们说的方案三那个问题啊,方案三啊,那这个呢,我们聊一下,如果那比如说我们现在是。
22:04
All in four。All the detail。对吧,然后呢,All the detail activity以及all the detail carbon这四张表啊,加一个base c吧,五张表进行关联,那重要的点呢,就在于它里边有一个activity和这个carbon这两张表,对吧?呃,那如果。后续需求。没有用到。Left。Join。啊,以后的字段。啊啊,右表吧。右表的字段。那么则可以只保留第一条数据进行输出,对吧?这也是一个驱虫,什么意思啊?来看我给大家举个例子。
23:03
比如说。这样,哎,我还是拿这个吧。拿这个数据来举例子啊好,那这边呢,你是不是参加了一个活动啊,比如说这个活动的activity啊。Activity相关字段,我把它写一下。呃,当然了,它是弄直对吧,啊,这个activity的字段,我我把它写在这吧,这样好一点。可能大家看的更清楚一点,我来说明一下这个问题啊,还的相关字段啊,我用多少个开啊,再来一个什么金额啊。优惠了12块五,当然呢,它是一个档值,上面呢是那值对吧,下面呢,有具体的12块五优惠的啊啊,我把这个活动呢,给它粘到最后吧。因为它是后转移进来的,对吧,我把它粘到后面啊好。我第三个驱虫的方案指的是什么意思呢?比如说我现在呢,接下来需求我要求GMV。
24:08
对吧,呃,我就直接拿着这个求啊,拿这个23块五求。我呢,后续计算我确实需要用到这个具体的数据字段,不是说像刚才我们求人数对吧,人数这种呢,甚至你都可以不用做驱虫。那么假如说我确实也用到这个字段了,他确实也要做曲轴。但是呢,你这个字段没有被用到left join右边的表没有被用到。啊,那也就是说这两条数据我任取一条是不是都可以能明白这个意思吗?就是假如说你不用这个字段的时候,就是left join右边的表你后续的需求当中没用到这个字段,你做的需求没用到这个字段,但是呢,你用到前面的这个具体字段呢,你驱虫工作呢,确实要做。
25:00
啊,实打实确实要做,但是这个时候是不是这两条数据我任意保留一条就够了。能明白吗?这个意思。能不能听懂?可以听懂的话给我扣一。对吧,就是这个呢,你必须要去重。但是呢,你没有必要非得保留最后一条。对吧,因为我呢不需要用到left join右表的字段,对吧,你的活动购物券,我这个需求呢不涉及。那我是不是可以按顺序取第一条数据啊,对吧?啊,那也就是说乱序了怎么办?乱序了也无所谓啊,乱序了你是不是把这个数据取到了,本来我应该取这条第一条数据,那你把这个数那无所谓啊,你这个都不用,他俩的区别就在于这儿,对吧,你也不用考虑乱序,那取第一条数据是不是简单呀,对吧?搞一个搞一个状态,然后呢,状态为钠,我输出,状态不等于钠,我就不输出。
26:14
能明白吧,是不是这意思,你状态不等于那我就不输出啊,你等于那我才输出。能明白吧,对吧,这是驱虫的第三种方案,这个呢,其实一三用的会比较多一些啊,因为第二个呢,还得开窗啊,特别的是像我们DWS层本来就有开窗。对吧,你要开窗,你可能两个都用事件时间,那你这个wordma就会乱了,就会乱了,我们尽量在一个代码当中提取一次我。OK吧,啊,所以第二种呢,其实用的比较少啊,一三会用的比较多一些。第一种方案是取最后一条,而第三种方案是取第一条,对吧?这两种呢,到时候我们大家都用一下啊,在文档当中呢,其实我们都写的是第一种方案啊,这个下单支付都用的第一种,但是呢,呃,我们既然是讲课嘛,练习对吧,所以呢,我希望两种呢都给大家去。
27:13
写一写啊,两种都去写一写可以吧,啊这个呢,我们可以。保留。最后一个这个呢,我们可以保留第一个对吧?啊保留第一个啊,两种呢都去用一下。总可以吧,对吧,是这个意思啊好,这是我们。所说的关于这个核心的去除问题啊,但是在生长环境当中,我再强调一下,在生长环境当中,如果你求的是这类似于这种人数对吧,用户数,像这个用户数,像这种指标的话,那么你都可以不做去重,直接求就好了。对吧,我们这块呢,是为了将下面这个需求难度呢给它降低啊,那驱虫工作呢,我们就已经做过了,大家呢肯定会好一点,你写第二遍第三遍的时候,对吧,肯定能好一点啊,那第一遍刚才让大家想想了好久,对吧?啊嗯,当然挺不错的啊,大家呢都在想这个问题,然后呢,提出自己的一个方案啊,但是有的方案呢,可能不太行,但是呢,你多琢磨,你后面呢,你也可能会发现这个不行,因为课堂上时间有限嘛,我没有给特别长的时间,那你公司当中开发,你不可能说就给你一个两三分钟,让你把这个需求。
28:21
想明白,那不可能。有可能我们。想完这个需求了之后,我们开始着重写,写着写着发现不对了,我还重新改,都有可能对吧,甚至软件的开发哪有那么哪有那么好的事儿呢,就一次性把这个问题全部都考虑到了,那不可能对吧?得慢慢的不断的去改进啊,这才是正常的合理的啊,所以呢,有大能能想到一些方案。啊,但是更重要的就是说未来呢,你不能光想,你还得要动手。对吧,你得尝试着去写一写。再多想一想,这个东西到底行不行对吧,然后呢,去写一写啊,看具体的行不行啊,好,那这是我们所说的这个驱虫的方案,OK吧,当然在文档当中呢,也有介绍啊。
29:07
第一遍。啊,要产生这个。计算。对吧,然后呢,去重的思路,第一个呢,这边违建开窗啊,还是按照违建分组,对于这个维护状态和定时器这两种,对吧?呃,在文档当中呢,没有说这个第三种,第三种呢,我给大家额外扩展的,因为在未来生产环境当中,大家是有可能会遇到这样的需求的,因为你有一张预处理表,对吧,把所有的表达都关联到一块儿了,但你不是说所有的需求都会用到。所有的表。有的学者呢,就用不到。那。你就可以用。第三种方案进行一个续重,因为这样的话时效性会更好,因为你第一种第二种方案呢,都有一个延迟,对吧,它延迟输出啊,而第三种方案呢,没有延迟,我只输第一条嘛,你后续的我不要了,我直接干掉对吧,所以它的时效性会更好一点啊,那如果你不需要用到level join右表字段,那么其实可以用第三种方案是最好的。
30:04
懂吧,啊好,这是我们所说的这个驱虫的一个思路啊。
我来说两句