00:01
呃,上午呢,咱们是写了一个这个JDBC的一个工具类,对吧,然后呢,查这个Phoenix表的数据,同时呢,把它再次封装了一下啊,这个封装呢,其实为了方便我们当前这个项目去用。对吧,呃,那一般有时候呢,像这种东西啊,呃,有时候取名叫handle了。对吧,呃,那当然这个名字的不同啊,不是说严格意义上就他们俩就必须得这样区分,因为类名说实话你随便取啊,那一般呢,像YouTube这种东西啊,是通用的。通用的,通用的就是你换项目也能用。啊,就是你换一个项目,它照样还是能用的,对吧?好,那如果说他这个叫handler,它呢也是通用的。啊啊,但是它通用范围是什么呢?是你当前这个项目,诶,也就是说跟你的业务呢挂钩。啊,跟你的业务会挂钩,能理解吗?啊,但是呢,我们就没有那么讲究,都写的是这个YouTube OK吧?啊,当然这个也还好,也没有那么严格,对吧?啊,都是属于这个工具类反复调用的这种嘛,对吧,就是说你写一个地方就为了复用啊呃,那并且呢,上午我们也测了它的一个速度,对吧,当我们只查一次,就是每一次呢,都获取新的链接去查询,对吧,也就是说你获取新的链接的时候,创建了新的客户端,相当于。
01:29
你呢,每一次客户端呢,都没有这个原数据信息,所以呢,它查询效率相对来说会比较慢一些。当我们用同一个连接进行多次查询的时候,诶,这个效率呢就变高了。嗯,那是因为我们当时分析了一下读数据的流程,对吧,他先找ZK。然后找Meta表之后呢,他会把Meta表缓存下来啊,那下一次呢,我就不用走这两步了,我直接找数据,那这个少了两次远程的发送请求加响应的一个过程,那这个效率必然。
02:06
会提高对吧,但是我们当时分析了,你那是八。八的话呢,一个冰度我们就算。100条。对吧,啊,100多一点吧,啊,这个我们就算100条,呃,对于如果你To B的企业来说是够的,但是如果TOC你的数据量,如果说你有个。两三千。那你在此基础上,你还得。再优化优化。对吧,因为你两三千的,你一个病都有100条。那么你3000,假如说你高峰期3000条每秒,那是不是要30个病度对吧,才可以保证你数据呢,在高峰期的时候没有延迟。对吧,你才能保证这个事儿啊,那嗯,30个变异度呢,对于咱们中亚云公司来说啊,有点高,说实话,因为整个的机器台数都不多,因为你整个的合数都不多,OK吧,所以呢,这个情况下咱们呢。
03:04
就是。不要那么高的一个变异度,那我们就在此基础上呢再做优化,那我们现在提这个访问维表优化,大家有没有什么思路呢。就是你觉得这个地方我们可以加。加什么优化呢?嗯。大家有没有什么好的点子呢?哎,想想点想想办法对吧。有没有?多线程。嗯,多线程可以啊,多线程。
04:01
嗯,但是有一个问题,你的map这个函数它是单线程的。啊,这个map函数它是单线程的,你懂吧。就是说呢,呃,你多线程我理解你的意思对吧,那么你第一条数据来了诶。因为一个现场,第二点数据来了,再开一个现场对吧,但是。对于我们的这个。Map方式而言,它是单线程的,什么意思呢?就是你第一条数据来了,如果第一条数据没有处理完,Map呢,它不会放第二条数据进来,这个函数这个特点对吧?所以在这个时候呢,你要用多线程,你得换函数,但是其他的函数呢,目前来说我们又不太了解,对吧?所以多线程呢,我们暂时先放一放。啊做暂时先放一放,还能不能想到其他的方案呢。
05:01
我觉得。就是这个方案大家应该可以想得到呀,批处理。你批处理。你效率还低吗?对吧,我现在要提高效率,你批助理。会影响到我的效率嘛,对吧。就这个方案,大家应该能想到呀。我们已经第二次接触了。这个地方已经第二次接触了。就当然并不是我们自己所写的代码。啊,是我们用的代码里边,人家是这样干的。一次查询把表数据缓存起来。对了,云总。啊,还得是云总啊,还得是云总啊,每一次每一次答的都非常好啊,云总应该在咱们班学的就挺不错的啊。嗯,那你看啊,我们当时。
06:03
Flink circle去关联这个维表lookup draw还有印象吗?我们是不是可以给这个look draw加一个catch,大家还还有没有印象?对吧,那我可以把它缓存下来,然后呢,我下一次查询就不用从这个呃去买搜去查了,对吧,不用发送这个请求了啊,那么我直接从本地不这个缓存当中去取这个数据,诶那这个不很好吗?对吧,这是一个,那第二个你再看看H我们所抢的。他的一个读的流程,为什么。同一个链接查第二次比第一次要快呀。因为它缓存了原数据。对吧,它缓存了原数据,诶,那我们就想点子,就随着这个源码当中,人家做的这样的方式,我们来想点子呀,对吧,那你缓存原数据,我能不能把你查的数据我给缓存下来呢。
07:07
对吧,我把你已经查的数据给它缓存下来。是不是,那这样多好呀。那我第二次查的时候,你第一次可能用一个八毫秒对吧,但是我再对这条数据查询的时候,我效率就会。快很多了,对吧,所以呢,在这个基础上呢,咱们加一个缓存,自己整一个缓存对吧?嗯,但是云总所说的缓存没有问题,但是我们并不把整张表缓存起来,如果整张表缓存起来,我就没必要把数据放到什么PI了。能懂吗?我就缓存热点数据对吧,就是呃,我读到的数据呢,我把它缓存起来,然后呢,我给他一个倒计时,假如说呢,倒计时一天对吧?啊,那你过了一天,就是这条数据被用了,那一天都没接下来一天没有人用这个数据,诶那我也是正常把它删掉。对吧,我还是把它删掉,我只存热点数据,我不存所有数据,因为如果我存所有数据,内存可能扛不住。
08:07
能懂吧,啊就不不把整张表存下来,存这种热点数据对吧,好,那也就是说呢,咱们的思路就这样子的。啊,呃,加一个什么呢。这个list这个我们就不聊了,对吧。哎,那看一看咱们的这个。啊,这是代码思路分析啊在这啊,这是Phoenix的一个工具类,对吧,这个我们也写过了,不聊了啊呃,这里面我们都写完了啊。就在这叫旁路缓存的一个优化啊,旁路缓存的优化啊,那什么意思呢?是这样子的,我们要加一个缓存啊,那我们把这个稍微给大家去聊一下,首先呢,我们正常的现在呢,是我们的主流,对吧,这是主流啊。那接下来呢,我们的事实表他一直在来嘛,对吧,每来一条数据呢,我们要去查一下这个Phoenix。
09:07
要查一下这个Phoenix没有毛病吧,好,呃,那这个呢,我们可能认为它的效率比较低,因为我刚才看到测的是八毫秒对吧,那么此时呢,我们这样第一次呢,你查这个菲尼X,查完之后呢,我们干什么事啊?把它写到这个。啊不不是不一定非得啊,我们呃写调缓存吧,当然已经暴露了,我们要用red了,对吧,当然我们待会会分析一下,呃,为什么不用本地的内存对吧?我们会给大家分析啊,大家呢,知道这块呢,我们将会用这个red啊好,那之后呢,再进行一个返回,那我正常查的时候呢,我先查。如果有了我就返回对吧,嗯,那如果说red没有。啊嗯,那我就查菲enix,从菲ix找到这个数据之后呢,我们给它写到。
10:00
对吧,做缓存就跟我们之前所提到的这个。查查peni斯对吧,它读流程,先找ZK,再找Meta表,道理是一样的啊,因为没有,没有的话,我们把这个Meta表数据呢给他。放到这个。本地的缓存里边对吧,它是在客户端的缓存里边啊,啊,那另外呢,我们也可以加一个这个内容,这个呢倒比较好理解,因为我们毕竟是一个内存,呃,你无论是还是本地的内存,那起码比你。从Phoenix查询肯定要快一些,对吧,毕竟我是内存数据库嘛,就算你用的是啊,那如果你用的是这个本地的内存,那肯定会更快了,对吧?好,那我们分析一下,就是我们在这个。本地内存加这个里边啊,怎么去选择的问题啊,怎么去选择的问题啊,首先呢。我们要考虑这几个点。啊,考虑什么呢?呃,第一。我们这个缓存的使用对吧,第一缓存呢,可以设置过期时间。
11:07
就是我们选用的这个缓存这个东西呢,得有得能够设置这个过期时间。对吧,因为如果你不设置过期时间,那么你就相当于存的是永久的数据,对吧,这就不好了,这就不好了,你有很多冷数据,可能这个用户读了一次,就是下了一次订单以后,对吧,正常的,诶访问了这个用户信息,我举个例子啊,因为有未来呢,用户这也是一个微表嘛,他可能也会用得到,对吧?啊呃,那我读取完用户这个信息以后,我可能接下来这个人呢,一个月没有访问过这个平台。那如果说你是永久的,那你这个一个月不白存了嘛,没有什么意义,对吧?啊,存了并没有给我们提高多大的一个效率啊,不好。对吧?啊,所以呢,我们要有过期时间,只存热点数据啊,假如说你一直读,那我们就可以更新啊,就采用这个读数据之后就更新这个TTL的方式,对吧?这个我们自己可以做啊好,那避免这个浪费资源,那当然这个呢,你用red是不是可以做到,因为red呢可以设置这个TTL啊,那我们用这个。
12:13
本地的内存能不能做到呢?比如说本地内存呢,我们可能用一个哈希map,对吧,类似于这样子的放在一个集合里面,因为我们可能不止一条数据嘛,对吧,那他能不能做到呢?其实本地的内存里边也可以做到这个事儿。啊,也可以做到这个事儿啊,因为在我们的代码里边啊,其实提供了有很多这种东西叫什么呢?我给大家找一个。其实有很多啊,叫Li ru catch,你看这个地方呢,有很多l ru catch,对吧,德鲁伊的工具类啊,这是卡夫卡卡夫卡啊呃,然后呢,像这个上包诶Java包下的,哎,也有对吧,呃,Lo。这个啊,这个弗Li里边的table planner对吧?呃,MYSO的一个连接器,诶,它都有这个ru catch,那这个东西到底是个什么呢?嗯,包括克house这边也有,你看啊,这个我选中的是不是克house包下的呀,它都会有这个l ru catch这个东西有没有同学知道?
13:13
就这个东西,有没有同学听说过这个Li ru k这个东西。有没有?有听过的吗?啊,那我们看啊,它其实呢,本质上就是一个叫。Link的哈希map,首先呢,它也是一个哈希map啊,呃,他是干什么事呢?呃,他是这样子的。你里边呢,可以给定一个阈值啊,这是初始化的容量对吧,最大大小初始化容量,然后呢,扩容因子啊,就扩容更重要的呢,就有一个什么呢?呃。这是扩容,扩容到最大对吧,还有一个东西。还有一个东西。
14:00
啊,就是。那你是一个哈希map?如果我超过了这个最大值对吧?呃,那怎么办呢,我们叫。移除掉一些东西,就是毕竟我是内存嘛,对吧,内存对吧,我给你一个最大值,但是你要超过我这个最大值的时候,我要删掉啊,他用的呢,最近最少使用的一个算法,基本上就是这样啊,就是还是消除掉这种冷数据,也就是说第一个点啊。第一个点。本地缓存跟这个。什么呢,跟我们的。Red。他都可以做到这个事儿,都可以设置这个过期时间啊,当然了直接过期时间,那我们本地的缓存,假如说你用一个l ru catch对吧,那你可以设置最大保存多少条数据,然后呢?嗯,超过这个值之后它会删,它会自动删数据,它删的数据是那个最低频使用的。啊,就是他删的是最近最少使用的这个数据,对吧,他不会删热点数据,哎,刚访问的这个数据不会删,所以呢,他俩都满足啊,他俩都满足不会说把所有数据都放在缓存里边,这个OK啊第二个点。
15:13
这个事情呢,大家也应该能想到,怎么算呢?大家还记得我们当时在测那个lookup draw的时候,我加了catch,如果说我刚访问完18AT的硅谷这条数据,然后呢,我注意啊,我加了catchche,我加了kche啊,然后我把18AT的硅谷这条数据给改了,我再去。查询它返回的是修改前的还是修改后的数据啊。这个还有印象吗?我们发现它返回的是修改前的还是修改后的数据啊,假如说我们加了catch。很明显还是这个修改前的数据。对吧,还是修改前的数据,那这个点呢,就提醒我们要注意,那如果说你这个存的数据未来可能会发生改变。
16:09
对吧,我们刚才说了,像这种catch呢,你最好在这种诶根本就不会变的数据,只会新增没有修改,那如果这种表呢,你可以直接加catch非常好用,对吧,加速查询。好,那如果这种改变的。对吧,除非你对这个数据的要求不高。你可以把时间设置短一点去用对吧?好,那要不然的话你就不能用,你要对这个要求比较高,你就不能用对吧?好,那也就是说我们想啊,我们的维表数据它会不会发生改变。就是我们这个维表数据,它会不会发生改变,我问大家。会不会?我们的维表数据很明显它是会发生改变的。
17:04
对吧,好,那所以呢,我们要求加的这个中间的缓存这个东西哦,那呃,我们。两个要求,第一,你要板呢,跟着变。对吧,你准备修改Phoenix数据的时候呢,你得把我缓存数据给改了。对吧,第二。要不然呢,你能把我缓存的数据给删了也行,诶你看啊,我本来呢,来了一个修改的数据,对吧,改数据,我本来要准备改这个非那数据了,现在呢,这个缓存里边有。对吧,缓存里边是有这条数据的。那如果说我只改它那不行对吧,你起码也能操作这个位置,诶把它给改了。把它给改了,或者说呢,你把它删了,你简单一点就把它删了,对吧,删了之后呢,你反正会重新读,读的时候没读到,你又会去找到这个Phoenix,又把这个新的数据是不是写到了缓存里边。
18:05
对吧,好,那这个要求可不是这两者都能办到的一个事情啊,你比如说我们用。对吧,用来做这个事情,就独立缓存服务啊,用来做这个事情。可不可以呢,可以。可以,因为你看啊,我们如果要加这个东西啊,那我们加读数据是不是在这儿往这儿写吧,对吧,那大家告诉我,如果我修改了这个数据,我要去删,我应该这个代码写到哪。我准备去删这个数据,我的代码应该写到哪?就是呃,那这边呢,在读Phoenix之前,我先读缓存对吧?好没读到我拼接circle,诶然后呢,从Phoenix里边去查询,查询好以后呢,我再给他写到缓存,这是读缓存对吧,这是写缓存,好那如果发生了修改,我呢要去删缓存,我应该写到哪?大家想一想。
19:21
维表数据。发生了修改的操作,我呢要去把缓存当中的数据给它删了。对吧,那我应该这个代码应该写到哪对吧,那我们说了,读代码写在这儿,写代码写在这儿对吧?那。删除数据的代码写到哪,该写到哪。写到读缓存的前面。
20:01
再想一想,不对。不对。你看你这都是来查数据的,你调用这个方法是不是查数据啊,你查数据你怎么知道这个数据是修改呢。啊。你你怎么知道这个数据是一个修改操作呀。所以肯定不对呀,我刚才说了,当我们知道要去修改一条数据的时候。我呢?去删除缓存当中的老数据。啊,重新再想一想。应该写到什么地方?
21:08
读之后写之前不对不对,还是没有get我所说的一个点。还没有get到,没有get得到。还差点意思啊,再想一想,再体会一下我所说的事儿啊,就是注意如果数据。发生了。改变。要主动清理缓存。维表数据发生了变化,我要去改这个数据。你这是读数据,哎,对吧,我要去获取维表数据,那我怎么知道它是一个改数据呢。
22:08
嗯,想一想。应该写到哪?啊,我再等几个答案,如果还没有的话,我就公布了啊。我们应该写到什么位置?还是不清楚是吗?数据写进Phoenix之前从macel读取的呢?对了啊,云总说的不错啊,就是我们得知道这个数据它是修改的还是说是。新增的对吧,那这个要在哪写呢?注意在DMC个方程这个类里边啊,在这我们呢,要去判断这条数据,哎,如果这不是写到Phoenix吗?对吧,那写到Phoenix的时候呢,我们是不是知道它是什么类型。
23:13
对吧,如果发现这条数据是一个更新的类型,那我们是不是在这个写入之前,我应该把ready数据去删一下。能明白吗?也就是说实际上删除数据呢,应该写在这个位置。能明白吗?其他同学。能不能明白了。懂吗?就是你你DMU,就这它永远都是什么。他他是查数据啊,我是查这个维表数据啊,你懂吗?我查微表数据,你怎么知道我是更新呢,还是什么情况对吧?那我刚才说了,我一直在想调当数据更新的时候要去删数据吧,那我怎么知道这个维表数据进来之后,它是新增的还是更新的呢?那我是不是在这儿要看当前的数据类型啊。
24:16
对吧,所以它的删除操作呢,应该写在这个位置去删。其他同学能不能明白了?嗯。OK吗,这个点。所以跨度比较大啊。在哪里写进缓存在这儿啊,班长,我刚才写那么大字,这是读,这是写。对吧,班长我刚才这么写了吗?在这个位置读这个位置写写缓存对吧,而在。
25:01
这个位置山。啊,在这个位置删。写数据肯定在这儿啊,对吧,就是我正常的先读,我如果读到了是不是正常直接返回了,如果没读到是不是往下走啊,没读到说明re,没有嘛,没有的话,我是不是从菲查到,查到以后呢,把它写到。缓存里边对吧,写缓存在这儿啊,这是写缓存的。对吧。明白吗,班长?这有先写再删,没毛病啊。难,难道不是先写吗?嗯,你看啊。班长,你是不是有什么误会?呃,这边呢,是菲尼克斯。这边呢,是我们的缓存。
26:03
啊好,那我呢,比如说我新增目前呢,先是新增一条数据啊,因为刚开始呢,同步全量数据肯定是新增嘛,对吧,我写了一个18。爱的硅谷。硅谷对吧,好,那么接下来呢,我去查了一次。查了一次怎么样呢?诶先查缓存吧,没有没有呢,查Phoenix,诶有了有了之后呢,把这个数据写到缓存吧,18爱的硅谷。好,呃,那我再查再查是不是缓存有了,直接返回对吧,因为我不走菲尼了,因为缓存有对吧,直接返回再查,一直查都是走这个缓存对吧?好,那突然呢,来了一个什么,来了一个更新,诶我把这个数据改了,我改成那个18大写的A对吧?诶硅股啊,比如说我就这样改了。改了之后,那一定要删那个缓存,对吧,或者说你修改缓存也可以啊都行对吧,好那么。
27:04
你看18的硅谷,那起码这如果你不做其他事,你只把这改了,这两面不一致啊,这是不是我们说的lookup join里边加catch所携带的问题啊?对吧,好,那你修改了数据,那我干什么事呢?我要把这个数据删了,然后呢,把这个A改了,改了以后你再查啊,你再第三次查,查一查二查三,对吧,第三次查,第三次查呢,还是走先走缓存,缓存没有对吧,因为我已经删了,刚才这个数据来的时候,我已把这个数据删了,删了以后呢,我查没查到,我是不是还是走菲尼查询,然后接下来呢,他又把这个数据18大写的AI的硅谷写到哪了。写到缓存里边了,他是这个逻辑啊,不还是先写再删吗?有什么问题吗,班长。对吧。它是两个程序啊,它不是一个程序。懂吧,他肯定是这个逻辑,其他同学呢,能不能明白?
28:06
我们所说的,我估计这两个东西大家应该能明白,在这儿加一个读缓存,在这儿一个写缓存啊应该问题不大对吧,但是呢,诶到这儿来扇,感觉好像又有点绕了。啊,那你要知道我们一直说的,当你数据发生更新之后,他才要去删这个数据。对吧。啊,那所以呢,你在哪儿知道数据更新呢?在这儿呢。这才知道数据是否更新啊,对吧,所以呢,删数据是在这个位置啊,在这个位置好,那这个点呢,你要注意一下,你考虑这个点的话,那本地的缓存就不行了,为什么?因为你要本地缓存,那你肯定在这儿搞一个哈希map吧,对吧?好,那你要删呢,你要在这个位置去删,那这是两个不同的进程里边的类,对吧,他俩又又挨着走,那我怎么在这块写个代码,把这个类里边一个哈希map给它删掉了啊。
29:06
不太好整吧。对吧,你说真逼着写,能不能写呢?也能写,因为进程与进程可以通信,那这个就很麻烦了,你在这个代码里边还写RPC通信啊,这就很麻烦了,对吧,一般我们不考虑这个事儿,所以呢,用独立。这边就有两个缓存的选型对吧,一个呢,堆内存,就是我们说的map,还有一个呢,独立缓存服务,比如说memory catch red,当然我们选用,我们肯定用red,因为我们学的是red,对吧?好,那这个呢。对比一下,像堆缓存对吧,性能更好,效率更高,嗯,那你本地缓存嘛,对吧,肯定是更快,但是难于管理其他进程,无法维护缓存当中的数据。对吧,这是刚才我们所说的一个点,而独立缓存服务呢,会创建连接对吧?呃,性能比这个堆内存要差一些,但是呢。便于维护和拓展。
30:01
对吧,因为它属于一个第三方,你呢这个数据。假如说你这个下单需求用到了这个维度,对吧,你把它写成了,那我另外的。我这个支付我能不能复用啊。可以对吧,我退单退款,假如说你都有这样的需求,那都可以服用,如果你用的是。堆换成呢?不好意思,复用不了了,复用不了了,对吧,你每个人都要维护一份,对吧,从这个角度来说,咱们是不是用这个。独立缓存服务更好一些啊,而独立缓存服务呢,我们所学习过的是啊,那么我们就。用的对吧,OK吗这块。我先把这个解掉。
我来说两句