00:00
好了,我们来上课啊,呃,那我们还是先把这个昨天讲的东西呢,做一个简单的回顾哈。嗯,啊,看文档吧啊。呃,昨天我们主要是讲了一下这个日活宽表啊,这个日活宽表这个现在已经算是完成了。啊,然后呢,又把这个订单订单这个宽表呢,也这个讲了讲啊,一起来看一下吧。这个日活款表的话,呃,首先你要知道,就是我们在整个这个任务中啊,我们需要去完成哪些功能。我们这一开始呢,就做做了这个分析啊呃,第一个功能就是这个做驱虫操作。对吧,然后第二个是做这个维度的关联。然后最后一个呢,是写入到这个olp里面啊,但这个我还没还没有做啊,这个等我们讲完呃ES以后呢,再来回头去做它啊。啊,那所以说呢,目前来讲的话呢,我们的这个任务呢。主要就是两两个功能啊,一个是驱虫的功能,一个是维度关联啊,这个驱虫啊,再来这个说一说啊,我们怎么驱的虫来着。
01:06
我们是两步啊,第一步呢,呃,先把你的这个每一次访问啊。对吧,先把你的每一次访问中,诶,你不是有这个N多个页面吗?我们先把它这个过滤成这个一个啊,那这个过滤的一个条件是什么呢?就是只要你是这个包含这个上业ID的啊,就你这个上页的那个ID是不等于空的,那就说明什么?说明你肯定不是我本次访问的一个入口,那我就可以把你干掉了。对吧,你看比如说我一天访问了很多次,那我的每一次访问呢,我都可以这么只保留一个页面,对吧,只保留一条数据。好,那你这个做完自我去充以后呢,那我会得到嗯,你每一次访问的其中的一条数据,但其实最后的话,我们并不要这么多哈,我们只要一个就可以了啊,所以说呢,我们还要什么再去做一个就是第三方的一个审查。啊,因为如果说呃,你不拿这个第三方来去做这个状态的一个维护的话,呃,你光靠这个我们的任务是很难去维护的啊,因为你想想这一个人呢,他一天访问跨度是很大的,对吧,比如说早上八点钟,然后呢,中午一点钟啊,下午的什么这个九点,这个七点钟啊,甚至于什么再晚一点都有可能跨度很大。
02:16
是吧,那就是没法什么对他的一个数据呢,做一个什么全局驱虫啊,所以这个我们只能是借助一个什么第三方的一个主将,然后呢,帮我们去做这个驱虫的这个操作啊,行,那我们选择的是这个red啊,就是我们要把这个。当日啊,所有这个访问的,就所谓所谓的什么这个日活用户啊,然后呢,给他什么记录到这个red中啊,比方说呃,你这个人啊,或者这个设备,你第一次访问的时候呢,那我就什么到这里面去看一看有没有,如果说这里面没有记录你对吧,那我就把你记录进来。那也就代表着你的这条数据呢,我就要了啊,因为我就什么计划拿这条数据呢来去表示你。对吧,那我就会把它写到这个olp里面。
03:01
啊,那么至于你今天后续的这个访问啊,那么我也是同样的,做完这个自我审查以后呢,我也到这个red洞的去看一看,诶,我一看时候发现已经有这个人了,对吧,我一看时候发现什么已经有这个人了。好,那么这种情况下呢,这个数据我就不要了。对吧,所以说这最后呢,我们最后我们就可以达达到什么效果呢。对于这个一个设备啊,或者是一个用户,你一天中的多次访问对吧,每一次访问的什么多个页面啊,我们最后呢,都可以把把它什么做成这个一个。这就是我们最后想要的一个效果啊,像这个驱虫的思想,呃,我们目前呢,就是采用的这种方式啊。呃,那这个具体的代码的话,嗯,这个自我审查很简单啊,就判断一下这个商业ID是不是为空就行了,这个第三方审查的话呢,稍微会,呃,麻烦一点。啊,因为你又要去做万年了嘛。对吧,然后呢,在这个话题里面,我们还重点去呃研究了一下,就是我们要选择哪一种,来我们再来看一下吧,啊,我们要去选择哪一种什么呀类型,然后呢,进行这个数据的一个存储啊。
04:09
上面有分析啊,嗯。好在这啊,那我们一开始分析的话呢。我们觉得说这个list呢,和这个呢,好像都差不多。对吧,好像都差不多,然后呢,我们就先暂时呢,把他们这个都诶呃放到我们这个备选的这个方案里面。然后呢,最后我们在这个写代码的时候,你比如说啊,我现在呢,想去做这个审查了啊,那我审查的方式就是我现在去把你这个中维护的这个所有的mid呢,给它取出来,对吧,这个也是一个道理啊,取出来好,取出来以后呢,我们去判断一个是否包含。那么按照你这个判断的这个结果呢,再来决定我是不是要把这个当前这个m mid呢,加入到你的中。那同样的也要去决定我的这条数据呢,要不要给他保留下来。对吧,像我们写的这个这个代码啊,你不管是用这个list也好,或者使用这个set也好,他们这个原理呢,都是一样的。
05:04
啊,思想都是一样的,但是呢,这种代码它是有问题的。啊,有什么问题呢,就是你放到这个分布式环境中。对吧,那很有可能会有什么多个并行度,然后呢,同时进入到你的if中,就是我们同时都做了这个应判断,发现我们都判断成功了,对吧,那就意味着这个代码或者是这个代码我就要执行多次。其实对于这个中你放的这个数据来讲的话,倒无所谓,你执行多次也无所谓,顶多就什么会有这个重复的数据呗。对吧,但是呢,你只是做这么做这个状态的一个维护的啊,我又不拿不拿你去做这个统计啊,说这个问题不大啊,但是呢,比较严重的问题是因为我们会按照你这个判断的结果呢,去决定我的数据呢,要不要保留下来。对吧,这个问题就比较严重了呀。本来我只是要只要你的什么一条数据,但是最后呢,因为你的呃,这个并发啊,导致了什么呀,这个多个并行动作同时都判断成功了,那把这个多条数据都保留下来了。
06:00
就相当于你一个人被统计了多次,将来你在这么统计日活的时候,你一个人呢,被统计了多次,比如说统计了四次,统计了三次。对吧,那你最后这个统计的这个日活的结果肯定是不对的。能明白吧,啊,所以说呢,这么写啊,你就用list也行,用这个set也行,都不可以啊呃,那。我们把这个说完以后啊,我们就给大家去说了一下,呃,在这个set中呢,它有一个比较好用的一个方法啊,叫这个SI。这个我们看似它是做了一个添加的一个操作啊,但实际上呢,他还帮我们做了判断的操作,就是我们可以把我们的判断和这个添加啊组合到一起。因为它这个SI的它会什么呀,帮你去做这个,把这个元素往这个就是你的K中去加的时候呢,它会有一个结果,如果说我加成功了,我就给你返回个一,如果说我加失败了呢,我就给你返回个零。对吧。啊,而且你看一下我们的一行代码就搞定了啊,我们并没有一个这个if判断是不是好,那如果说你这个一行代码,或者是你的一个方法就能够搞定的话,这个时候你就算有这个很多个并行度,你们就算这个并行度呢,同时要去执行这个方法,但是呢,你到了层面以后呢,你们几个肯定是排着队去执行的啊。
07:19
理解吧,那就说白了,你的这四个并行度动,只有一个是会成功的,它会返回一,剩下的只要你排到它后面的,肯定都是返回个零啊。对吧,那么你拿到这个结果以后呢,你再去做这个结果的判断,如果你是一,我就加进去,如果你是零的,那我就不加进去了,这样我就能够保证对于每一个设备或者说每一个用户来讲,我最后呢,只保留你的一条数据。对吧,这么去做呢,就解决了这个问题好吧,行,这个倒也不是说这个有多高大上的一个东西啊,大家主要就是有一个意识啊,什么意识呢?就是当我们再去写一些这个分布式的这种代码的时候呢,你就要考虑到这个并发问题理解吧啊,你要考虑到这个并发问题的啊。
08:04
行,这是我们的驱动操作啊呃,然后至于这个后面的这个维度关联的话呢,这个就很简单哈,就是把你的需要关联的这个维度数据呢,从你的这个维度层啊,从这个ready呢,把它调出来,调出来以后呢,你需要用什么字段,你就把它提出来,提出来以后呢,补充到这个对象中就完事了。对吧,所以这个维度观点还是比较简单的哈,行,这我就不多说了啊好。呃,然后呢,我们现在做到的就是把这个驱虫完事了,把这个维度关联完事了,然后至于往后面写,就是写到这个OVIP啊,这个我们暂时还做不了。明白吧,所以说我们现在就是这一步呢,还没有去做啊,等我们讲完这个ES以后再去做啊,因为大家还不会啊好呃,那最后这个状态还原也是啊,这个是等我们讲完这个ES以后,就是你数据写到ES以后呢,再来考虑这个问题啊,现在先不考虑啊。好了。呃,再往后呢,我们讲的就是订单的这个宽表了啊。
09:04
这个订单款表的话呢,呃,我们也是简单分析了一下啊,我们需要做什么事。主要是两回事啊,两个两个功能,第一个就是还是这个维度的关联。呃,因为我们将来统计你这个订单相关的这个指标的时候呢,呃,避免不了会用到一些这个维度的数据啊,比如说我们举的例子还是那个什么性别呀,对吧,什么年龄啊啊,什么什么地区啊啊等等等等一些啊,你要什么东西,你就提前把这个维度呢给它关联好。OK,所以说呢,呃,我们首先去做的事情呢,就是把你的order info啊里面呢,去补充了很多维度啊,还是你这个用户的维度,还有什么这个地区的维度。好,那把这个维度补充完成以后呢,接下来我们要做的事情就是这个双流的一个draw。对吧,那这个双流装引的话,呃,就是把你的这个order info这个流跟什么高跟这个order detail这个流,然后呢,我们要把它什么关联到一起。啊关联到一起,然后呢,生成这个宽表。
10:01
是不是好,那昨天我们就研究到了这个话题啊,来这个我们就回到代码中来去看,呃,那我们再去做这个双流招引的时候。首先啊,你要先明白的就是我们有哪些种这个装印的方式。啊,这是我们首先去说的啊,转移方式你也知道啊,就最常用的就是内连接和外连接。啊,然后外连接的话又分什么左右,还有什么这个全外。对吧,那么你心里面要一定很清楚啊,就是每一种它这个连接方式啊,它的这个特点是什么,它怎么取结果集的。对吧,你只要把这个先记住了以后呢,将来诶,当我说遇到我需要你现在去做一个什么连接了啊,不管是这个数据库层面也好,或者说我们这个实时处理层面也好。那你要想明白,我最后希望得到什么结果,我的结果中我想要什么数据,我是全要呢,还是说呢,我基于什么,基于某一个表,然后呢,这个表全要,其他的怎么做这个匹配,还是说我要取交集?对吧,你就什么基于你的这个需求,你就可以什么选择什么对应的这个招新方式。
11:03
所以说这个东西是一定要放到你的脑子里面的啊。这都是基本功。明白吧,你别觉得说那不就一个方法吗?我直接去掉呗。你调归调,但是你调不同的方法,你得到的结果是不一样的呀。是吧,啊,所以这个东西一定要把它记清楚了啊OK,呃,那我们知道这个装阴方式以后呢,接下来我们就是去做这个装阴操作啊,但是呢,对于我们目前这个流来讲的话,你肯定还是装赢不了的。啊,大家一定要记住啊,Drawing一定是KV结构的数据才能够去做这个drawing。理解吧,啊,一定是KV结构的才可以去做,去做join,因为你放在这个数据库层面,你说我的两个表,我现在想去做这个join了,那你在join的时候,你要写个条件,条件是on,对吧,你的哪个字段跟我的哪个字段,我们之间做一个关联。就是你要派出一个代表,他要派出一个代表,你们两个去做这个对接的。那同样你放到我们流里面也是,你说我是两个流对吧,如果说我就是一个两个普通的流,我里面就放了什么具体的数据,具体的数据你说来你们join一下吧。
12:08
他哪知道谁跟谁去做这个招啊。对吧,你没有对接的那个人啊,啊,没有对接人转移不了。啊,所以说呢,我们需要什么,先把我们的数据呢,给它处理成这个KV结构。对吧,比如像我们这个order info,那我派的代表呢,就是我的订单ID,诶像这个order detail,那我派的代表呢,就是我在订单,呃,在这个详情中,我所记录的那个什么订单的ID。对吧,因为你的每一个详情都属于我的某一个订单的详情嘛,所以说呢,他们两个字段是可以什么关联的。啊,因此的话,我们先把数据呢,处理成这个,诶KV结构的好,那处理成这个KV结构了以后呢,我们就可以正常的去做这个招引操作。对吧。啊,那接下来就是分析你要用哪一种装银的方式啊,那我们是这么来分析的啊。呃,因为我们想了啊,你从这个数据库层面来讲的话呢,它里面的数据和它里面的数据是一定能够关联成功的。
13:06
对吧,就不可能出现那个关联不成功的这个情况啊,一定是能够关联成功的,那我就觉得既然你们一定能够关联成功,那我就直接使用这个装一就完事了,就是内连接就完事了,反正你们都能关联成功嘛。对吧,好,那我们也确实使用了这个装银的,使用这个内连接的方式去做了,做完以后呢,我们去测了一下,好像也没有发生什么问题。对不对,那就其实正常情况下啊,一般情况下都不会有什么问题,都是能够什么正常装印成功的。但是呢,呃,在这个实时处理层面吧,就有很多。你不可避免的一些这个问题或者什么,你这个很多什么。叫叫什么呀,叫这个不确定一些什么因素啊,你比如说就这个数据延迟这个事儿啊,这个其实有时候挺致命的啊,你别的说,那你你别觉得说那不就数据这个晚来了一会儿吗。对吧。是数据是晚来了一会儿,那得看你放到什么场景里面,你比如说放到我们刚才那个装的场景里面。
14:04
那就会有问题。对吧,因为我们招引的是两个流,那你说我一个流的数据已经来了,我的另外一个流的数据呢,还没有来。对吧,那你说他们两个能装印成功吗?装印不成功,因为你同一个批次的数据,他才能够去做这个装。对吧,所以说你本来啊,人家从表层面我是可以正常招印成功的,但是呢,放到你这个流处理层面,因为我的这个数据延迟了,导致我最后呢,没有招印成功,那这不就不行了吗。对吧。所以说啊,我们想到了这个情况以后呢,那我们就不能够再去使用这种装引这种方式了,因为它呀内连接嘛,我只取你的交警。是不是比如说你出现在这个不同的批次里面了啊,你在同一个批次的,你装印成功了,这没问题,但是呢,我出现了不同批次的数据,本来我跟你呢,也能够装印成功,但是呢,因为我们不在同一个批次。你们是招印成功了,然后呢,我呢,没有人跟我再去招引,那这个数据我就丢了。
15:01
对吧,最后结果里面就没有他,那没有他你肯定就不对了呀。是不是,所以说我们就不能再去使用这个内连接啊,那我们想的就是说。要把这个交易成功的和这个什么没有成功的数据呢,都得给我出现到我的这个什么装易的那个结果中,然后呢,我再对我的这个结果呢,展开这个处理。对吧,所以说我们最后我们分析的就是应该得使用这种方式叫for after drawing,就是两表的数据呢,我都要,嗯,两张表的数据我都得要。对吧,就是最后我们得到了这样的一个结果。好,那你看啊,这两个结果你作为一个简单对比,你就能发现出来,如果你直接用的是内连接啊,那它给你返回的值里面就是你的order INF for al t,就这个是一定是装成功了,它是有值的。但是呢,我们使用了这个full after join以后呢,它给我返回的结果,它并不是一个直接就是一个什么order in for啊,或者什么order detail,而是什么呀,通过这个option做了一个什么包装。就说白了啊,这个是可能有可能没有,这个也是可能有可能没有。
16:06
对不对啊,这样就可以把我们这个成功的还是不成功的数据呢,都给你什么放到这个结果中,那你再去什么对这个结果呢,做出这个针对性的处理就OK了。明白吧,好行,呃,这是我们最终选择的方案啊,当然呢,我们在过程中呢,也给大家这个去简单说了一下这个别的方案啊,就比如说扩大什么这个采集周期。啊,你比如说这个五秒钟一个批次啊,那你这个,呃,正常情况下你都能在同一个批次里面过来,那有可能呢,诶,我超过这五秒钟了,我这个跑到另外一个批次里面了,那这个时候你可以怎么把这个批次扩大,对吧,我扩大成十秒钟。是不是啊,如果说你这个还觉得不行,那你再扩大啊,我扩大成什么15秒钟。是不是,但是呢,你这个扩大到多少比较合适呢?就是你敢保证你的数据就算延迟他也不会超过多少秒钟吗?如果说你敢这么去保证的话,那你这个扩大这个采集周期是可以的,如果你保证不了。
17:03
那你这么做还是有问题。明白吧,啊,同样啊,还有一个方式就是什么使用这个窗口啊,这个窗口也是啊,这个窗口其实反而还不如这个扩大采集周期啊,因为窗口。他麻烦的点在哪呢?你这是一个周期对吧,这是一个周期,我的窗口是你多个周期嘛,对不对,这是一个周期啊,这是一个周期的数据啊,那假如说我的窗口是,呃,两个采集周期,比如说这么大。对不对,比如说这么大啊,好,那么首先。来首先啊,我的第一个批次过来以后,它在我的窗口里面。对吧,假如说我的窗口在这儿啊,第一个批次来了以后呢,它在我的窗口里面,那么他们里面数据呢,会做一个什么噪音操作。OK吧,等我这个第二次,第二个批次来了以后呢,因为它还在我的窗口里面,这个东西呢,还在我的窗口里面,所以说呢,它里面的数据呢,跟它里面数据,跟它里面数据,他们什么都要去做这个装音操作,你能明白我的意思吧,因为你都在我的这个什么窗口里面,我是完整的数据,那我都要怎么再去做一次这个噪音操作,那就会有什么呀,会有这个重复的这个操作啊,就会生成什么重复的数据,对吧,那你还要去考虑这个数据去重。
18:15
是不是,而且你这个窗口范围你给多大呢,这也是个问题。那你就一定要保,一定要保证这个两个周期的数据,我就能够解决延迟了吗。对吧,你要不要把这个窗口再往大了搞搞呢。是吧,啊,所以这都是一个问题。OK吧,行,所以说呢,对于这两个这个方案来讲的话呢,我们暂时肯定是不采用的啊,因为他解决不了这个根本性的问题啊,所以说我们还是什么自己来去解决吧,对吧,自己来去解决啊行,那我们最后的这个解决方案是什么呢。就是我们在把这个结果都保留下来的情况啊,我们再去什么针对性的去处理。啊,针对性处理,怎么针对性处理呢?呃,我们让这个双方呢,都去做两步操作啊,第一步操作呢,就是我到这个缓存中啊,去找一下有没有这个对的人啊,就是我们提到的这个缓存的这个方案啊,这个我们画了个图,是不是把这个图打开吧,我们再来简单看一看啊。
19:19
好,来看一下啊,就这种方案,就比如说诶,你们来了以后,你们在这个同一个批次中呢,你先正常的去做你的这个招音操作啊,那么成功的数据呢,我就可以什么,呃,这个先维护起来,或者什么写写入到这个ES啊都可以明白吧,看你是直接写还是最后这个统一去写啊都行好,那么对于我的这个同一个批次中的这个OD来讲啊,如果说他已经是被装移成功的数据,那么他就不用再去处理了,理解吧,但是OI呢,是要做其他的处理的,因为。OI对OD是一对多的,明白吧,就是我的OI呢,跟你的OD虽然说已经招印成功了,但有可能他还能够跟别的数据再装印成功。
20:01
对不对,所以说呢,这个OI呢,它就是什么写到缓存中,然后呢,去等一等这个OD。明白我的意思吧。同样的。OI呢,他还得什么呀,到缓存中去找一找,有没有在等他,你比方说我的OD的数据呢,我先到了,但是你OI呢,你晚了,那你来了以后呢,你不仅要跟你同一个批次的去做这个招引,那你还得什么呀,到缓存中的去读一下,有没有在等你,同样道理,你还得再写到缓存中去等一下别人。理解我的意思吧,啊,那么对于这个OD来讲的话,是这样子的啊,如果说我在本批次中就已经什么跟你的OI交易成功了,那这个数据就不用再去做任何处理了,因为你的OD它只能够跟OI去做招引。只能招一次,就是你的每一条这个detail的数据,只能够跟你的order info招一次,它不可能招多次的啊,这那么对于这种比如说我没有招印成功的数据,那么他要干嘛呢?首先呢。他要到这个缓存中去找一找,有没有人在等他,如果说有,诶,他们两个招印成功了,好,那么他也就不用再去做什么处理了,因为他已经找到对的人了。
21:08
那假如说这个对吧,我来了以后呢,你看啊,我也是一个OD吧,那我要到这个缓存中了,看看有没有人在等我,一发现诶没有人在等我,那如果说没有人等我,就说明我来找了,来找了以后干嘛呢?那我就要去等别人,我就要去等他,所以这个时候他就要进缓存了。明白我的意思吧,这个时候他就要进缓存了,好吧,啊,这就是我们这个最后的一种什么思想,就是相当于啊,他们两个人,他们两方的这个多做两步操作,一个是找到缓存中找人,再一个什么把自己写到缓存中,方便别人去找你。理解了吧,就相互去找啊,就这种方案,然后呢,我们最后呢就可以呃解决这个问题。OK吧,行,这是我们昨天已经分析到的啊,然后呢,呃,稍后啊,我们就可以把这个通过代码给它这个转化出来啊,通过代码给它实现出来,然后把这个双流双流招引呢,给他这个解决完好吧,行,那我们就先回顾到这吧。
我来说两句