00:00
好,那我们先把昨天的内容做一个回顾啊呃,那昨天呢,我们主要是把这个前面的内容呢,先回顾了一下,之后呢,是聊的这个订单宽表对吧?呃,那订单宽表呢,最重要的它这个逻辑线其实比较简单啊,逻辑线很简单,也就是说我们需要去消费订单表和订单明细表,这两张表呢,是事实表,我们需要对它做一个流的join引啊,我们也看了,昨天带着大家稍微的学习了一下,对吧?有这个window drawing,也有这个呃,Draw啊window draw呢叫开窗啊,窗口与窗口之间draw特别像window draw当中的这个滚动窗口的一个,照它跟它跟那个Spark streaming这边直接按批次draw非常的像。对吧,那之后呢,像还有这个滑窗照影,还有这个绘画窗口招引,绘画窗口照影,大家注意的一个点在于,呃,它是这样子的,它要等到两个流同时满足那个间隔时间,它才会关窗啊,然后把两个窗口装移在一起啊,这个也很合理,对吧,因为你要装引的话,肯定要时间上是匹配的。
01:16
啊,那如果说你直接用会话窗口,哎,不等到两个流都是同时满足的话,那它具有因为会话窗口具有时间不对齐性。所以那个照应就没法照应了。对吧?啊,那所以呢,我们这个要注意一下窗口照应,虽然我们没用啊,但是如果在工作当中你要用到的时候,你要注意一下这个事儿啊,那第二个呢,我们就看到了有in。对吧,它是有阴逗照,它就直接就相当于哎,我用一个流的一个点去join引另外一个流的一个面,对吧?啊,用这个留的一个面啊好。那。这一边转引的时候,那它我们就想啊,正常的我我这个流到这个位置了,那另外一个流上面,那肯定也是到这个点吧,对吧,它俩应该是相同的才对啊,那为什么它能够去照应到这边,也照应到这边呢?那很简单,因为在弗林格当中有状态。
02:15
对吧,那我能照到左半边,是因为你左半边的数据要保存到状态里边,那我能跟右半边也能join,那这个问题就很奇怪,对不对,那什么情况呢?那比方说那我来的时候,这后面数据肯定还没来,所以很明显是要把这条数据也要保留到状态里边,保留这么久,哎,也就是说前面数据需要保留这么长时间,后面数据呢,需要保留这么久啊,就是它需要保留这么久。对吧,所以我们看到他在我们造引的时候呢,需要写一个between,哎,负五到五啊,有一个范围对吧,当然还可以把这个边界排除掉,形成一个开区间啊,默认的是B区间,对吧,之后呢,运用一个叫process draw function就好了。
03:04
对吧,处理这个数据很简单啊好,那之后呢,我们接下来往下聊,呃,等我们双流转引完之后,我们做了一个测试,数据呢也没丢,你再往下写,如果说这个数据都没有出来,你再往下写,最后做测试肯定有问题,对吧?啊,所以呢,我们先把这个测试了,没有问题啊,那接下来呢,我们准备去写这个代码,在这边,我们当时在这写了啊。呃,在我们的这个。DWM层outy的APP,这我们写了大致的思路,对吧,那。先是获取ID,然后根据ID查询信息,然后补充信息,同样的这一套流程,这三步对吧,那我们要做地区sksk trademark category啊,总共要做这么六次啊,总共要做这么六次啊好呃,那这个时候呢。我们想那明显的访问Phoenix这个代码可以被提取出来复用。
04:05
对吧,所以我们开始呢,就写了一个这个。JDBC的一个工具类,而且我们是把它封装成一个特别通用的一个工具类,对吧,也就是说未来只要是JDBC都可以用。啊,不管你什么接力BC对吧?啊,在这里边我们传连接,传查询语句,传一个泛型类的对象,然后泛型类的类型啊,以及是否要转这个。驼峰命名啊,因为你也聊到了,在数据库当中往往都是用这个下划线命名的,那你在我们的扎病里面往往都是用驼峰命名的,所以呢,我们传一个参数可以进行一个转换,对吧,做这个事情啊好,那之后呢,在这个基础上我们又写了一个Du求。啊呃,让获取更方便,因为我们发现啊,在这个查询维度信息的时候,只有表明和我们传的这个过滤条件不一样,其他的整个circle都一样,那我们就可以封装,方便我们后续的使用,对吧?这个意思啊好,那在这个里边呢,我们开始这样写的封装circle,然后呢查询。
05:18
直接返回就好了,呃,但是在这个基础上,我们自然是测了一下,直接访问菲尼克斯呢,用我的虚拟机啊,用我的虚拟机大概是呃,13毫秒对吧,如果说你这个连接不关,大概十三十几毫秒吧,啊呃,那这个呢,我们推算了一下,它一秒钟单个平移度只能处理80条数据。80次访问对吧?啊,那这个平行度,它就是你要非常高的平行度才可以达到。这个流量高峰期的一个数值,对吧?啊,也有可能高峰的时候一千两千类似于这样子的啊。好,嗯,那之后呢,我们又想到用red做一个缓存,因为我们对这个要做优化。
06:03
对吧,所以呢,我们将做了一个缓存,那我们改写了三个地方,第一在我们查分之前,我们先查一下这个。对吧,先查啊好,那第二个问题在。查询我们的Phoenix之后,我们往去写一次啊,往去写一次,还有第三个位置啊,还有第三个位置,什么位置呢?在我们的DMC。DM当中。对吧,我们要把这个数据删掉啊,数据删掉好呃,那关于这个问题啊,这个问题有一个点,正好昨天有一个同学面试的时候,他遇到了一个问题,我给大家说一下,大家可以想一想,这个东西我们应该怎么去做一下。啊,我们怎么去做一下对吧?呃,那是什么样的一个点呢?来听着啊,现在现在我们数据是不是先。
07:05
山的。注意听啊,先删的red,这是昨天网易啊,有个学生去网易面试,然后呢,网易面试官问到的一个问题,好,我们是先删,然后再写入菲en尼斯对不对。再写入菲,那我们要做这个事情呢?主要的原因是在于保证数据一致性。对吧,我们是要保证数据的一致性,好,那这个时候呢,网易他就问了这样的一个问题,说什么问题呢,由于我们是。两个不同的进程对吧,你这个DMC的方式是是属于贝斯。D bapp,而查呢,是属于order y的PP对吧?那有没有可能这样呢?注意听啊来,呃,这边把数据删除了,好,然后这个中间总还有一点时间对吧?呃,那oy的B刚好查了一次这个数据。
08:17
啊,就是在Phoenix执行改之前,还没有修改的时候,还没有修改之前,但是已经删了,在这个之间,介于这个之间,另外一个outy的恰好查了这个数据,又把我们查的数据写到了哪。写到了。对吧,人家问的这个问题,哎,刚好呢,又把这个数据写到了,那此时red里边是不是还是老的数据啊,因为这边。是一个改操作还没有完成啊,还没有执行呢。对吧,但是呢,这一边我们又查了一次,把老数据又查出来,又写回到VE了。
09:04
那大家现在可以想一想,那怎么办嘞。想一想。啊,加个锁15。删除和写入绑定。首先第一如果用事物的是不是也要加锁,而且你要用事物的是不是得把这两个操作。
10:08
写到一起。对吧,是不是要把这两个操作写到一起啊。先写再删好呃,那如果先写再删,那删的时候出错了呢,没删掉啊。是不是也有问题啊,我写成功了,但是删除的时候这块呢,任务挂掉了,没删没删掉啊,再去访问,访问的时候是不是有问题啊,班长对吧?啊,先写也不行啊。呃,你要加加锁的,或者说事物的事物呢,也要加锁,但是我们知道在我们的这个里边,它是那种乐观锁,也就是说只要有其他的操作来了,它会释放掉这个锁。
11:03
虽然是不同的进程,但是用的是同一个工具类,加个标志位应该可以吧。不行,不同的进程工具类相同没用啊,你你两个人还能交互啊,这个肯定不行啊,那你想说事物的,或者说加锁的。写完再查询一遍。那你查没用啊,你在查的时候,那刚才我说了,中间的时候有人查了,他是把老的数据写出去了呀。对吧,呃,刚才还有一个答案说先删再改,再删一次。啊,再删一次,这种一定程度上能解决一些问题啊。还还行,这种方案就是说删两次,我等X写完之后,就是让班长说的先写再删,但是有问题,那我能不能删写删改删了我做两次。
12:05
对吧,删改删做两次就可以防止这种问题啊,但是呢,如果考虑到这个中间挂掉,因为班长说先写再删,我提出来一个点说这个任务如果挂掉,如果不考虑这个任务在中间挂掉的情况,那其实可以,对吧,先写啊这个意思再删re,这个是可以的啊呃,那如果考虑到挂掉,其实我们刚才所说的先删再改,再删其实也不好,因为如果中间挂掉了呢,那数据是不是还有问题啊,中间没删掉吗?对吧?这个没删掉,那其实可以怎么做呢?因为我们现在是针对于维度数据对不对。针对维度数据,那么呃,维度数据啊,你要记一下啊,记一下这个点,防止面试官问到,因为其实之前面试官很少问到这个事情啊,那因为我们存在这个里边呢,是一种维度数据,呃,那么这个维度数据呢,它具有一个特点是缓慢变化,也就是说维度数据更新的操作怎么样。
13:05
并不多,对不对,这是第一个点啊,要明确的,它的一个更新操作并不多,所以这一块呢,很简单,我们可以这样做,这块呢不删这块我不删,我做什么事呢,我直接把数据改了,我往去写一份。直接往写一份更新的数据。大家想这种方案是不是更好一点?对吧,呃,有的人说事物应该是最好的,我也知道事物最好的,但是你要知道在里边它是你要有事物肯定要加锁,对吧,但是呢,它是乐观所。啊,它是乐观锁不太合适吧,对吧,所以这个地方能听懂我的意思吗?这个地方这个地方本来不是删嘛,我不删了对吧,直接干什么往去写一份修改后的数据。OK,能听懂。
14:11
不删,直接更新。出错什么时候出错,你出错的意思是他写成功了,他没有写成功是吗?他成功了,他失败了,是这个意思吗?就是当前这个任务。对吧,那那你想啊,那你在查的时候。在查的时候,是不是red有最新的数据了呀,那就算这一次当前出错也没有问题呀,对吧,因为在当中这个数据我会保存24个小时。对吧,我会保存24小时,也就24个小时之内,你把数据提起来,那我们重新消费,重新消费这条数据是不是还会被写到。
15:05
还是会写进去的,这个是没有问题的。班长,能能听懂这个意思吧,班长。就是假如说他成功了,他失败了。对吧,我这个时候另外一个进程去查数据,能不能保证查的数据一定是对的呀。查到数对的吧,那你任务挂掉了,你要重启,重启之后重新消费,那这个数据是不是又被写到了,会再写一次到这个fhoi。对吧,其他同学能听懂吗?班长你这边呢,因为班长刚才说了还是一样的,如果出错了对吧,这个是没有问题问题的,这个是没有问题的对吧啊这个是比较好的一个解决方案,因为这个事物的话,你跟red去加这个东西啊,不太合适对吧呢?他乐观组啊不太合适对吧?啊,所以一般很少去启用的一个事物啊,所以呢,这边如果人家问到你的时,对吧,其实其实那个点啊很。
16:06
一般不会出现这种情况,对吧,那如果真出现了,我们可以把这块改成这个,不要去删,而是直接把数据改了就好了,对吧,把数据呢写进去啊,写进去包括班长说的那个问题也也没事儿,对吧?啊,班长说挂掉了,第一个成功了,第二个失败了啊,那没关系,因为接下来24个小时用户去访问的时候,访问这个维度的时候,这个维度是没有问题的,那你重启,重启之后呢,会把这个数据重新消费,最终呢,也会写到pix,那这样的话,保证数据的一个最终一致性,对吧,而且在中间查,有人来查这个数据的时候也没有问题,对吧?是这个意思,那这个就搞定了啊好。呃,那这是我们之前所讲的一些东西啊,那另边还有一个点,最后我们是不是看到了,哎,我问一下大家,最后咱们是不是看到这个,呃,用red之后查询的速度,只要有了再查一次一毫秒还记得吗?
17:09
还记得一毫秒这个事儿吗?没问题吧,哎,他他要他需要这个一毫秒啊呃,但是这个时候我们我们想啊,我们是有用户维度,然后呢,地区维度,呃,然后呢,还有这个什么,呃,SKU SKU trademark category。对吧,六个维度啊,至少六个维度,而且我们只查开率个三啊,如果说你要把开这个二一都查进来,就是八个维度,那我们就按六维度算啊呃,当是呢,显示一毫秒,那可能不到一毫秒,那这样呗,六个维度访问六次对不对,假如说都在red,所有数据都在缓存了,所有数据啊都在red缓存了,那我我。简算一下,我算毫秒。也就是说一条数据来了,因为一条数据要访问菲hoenix或者六次嘛,对吧,一次呢,一毫秒我全部都算在所有的数据都在ready有对吧,它是最最简约的时间啊,然后呢,也要五毫秒,五毫秒的话,那也就每秒钟咱们能处理的数据单个并度处理什么。
18:19
200条。对吧,也就是说一秒钟处理数据200条,这样的话就不会产生这个反压,如果说你要低于处理的你你的数据过来的速度超过200条,假如说300条对吧,400条这种情况,那呃,是不是产生了反压,处理不过来了嘛,就只能积攒在这个内存这块,对吧?是这个意思,好呃,那。怎么办呢?也就是说对这个内容啊,还要做优化,因为单个边路200条,这个效率太低了。对吧,单个变异度一秒钟处理200条,那你十个变异度也才2000条,对吧,100个变异度也才200条,比较低啊,这个这个处理的效率就比较低,所以对此呢,我们对这个内容还要再做优化啊,还要再做优化,因为呃,那有有的最后啊,最后你要注意我们给大家说的高峰期的数据量大概就是一千两千条啊,其实按照这个来说,我们放的就够了,但是面试官。
19:19
问你,他说你们这么小的数据量放在里不就够了吗?为什么还要用第二种优化?当然现在我还没说啊,第二种优化是什么?那这个问题大家觉得你应该怎么答?啊,考一下大家。其实假如说我们现在的数据量跟我们现在用的方案写到做旁路缓存已经完美契合了,也不会产生这个反压,对吧,然后呢,你面试的时候肯定说了你用了第二种方案嘛。
20:04
对的啊。对了,格局要大啊,对了啊,这个没问题啊,看来大家都都领会了啊,就是说咱们目光要目光放在现在还要更长远一点,对不对啊,要有格局啊,包括副总说的也没问题,我们现在正常的呢,高峰期可能是一天两天,但是我如果搞活动呢。对吧,如果我搞活动嘞,活动的时候是不是有可能也会数据量更大,对吧?啊,还有未来增长,我们数据量会增长的,我不能说稍微增长一点我就改,稍微增长一点就改,对吧,那你做测试,包括生产环境做测试啊,你可能现在假如说高峰期是2000。那你在做压测的时候,各种压测的时候,你包括卡不卡做压测对吧,大家也做过,你就是拿2000来测吗。不可能吧,对吧,起码得至少得翻个倍吧,那有的公司是五倍十倍这样去测对吧?啊,因为我们希望公司在大力的发展,对吧,所以说这个要注意一下,那也就是说接下来我们对当前这个代码再要做优化,还要做优化啊对吧。
21:18
好,那这个时候呢,我们把它截掉。
我来说两句