00:00
刚才我们把程序写完了,接下来呢,我们测试一下啊,不过在测试之前呢,我们先来看一看啊,因为我们现在呢是用的for it r DD,所以啊,它里面呢,就没有那个时间戳了,有的时候可能看起来就不舒服了啊,所以我们这样,咱们在这里呢,咱们加一个打印啊,打印一下,咱们叫做就直接来吧,咱们叫做day啊,然后呢,写上一个U,然后再写上一个我们的广告,好吧,然后再写上一个我们的count,诶把它打印一下啊,然后呢,我们下面呢,我刚才呢也稍微的改善了一下,因为有些地方这个数字啊,这他我当时没有写啊,比方说我们的这些数字啊,包括一啊,这东西容易写乱了,呃,其实所谓的写乱呢,就是因为都是JDBC嘛,传参呢,各方面就容易可能混了,那为了避免这样的错误呢,我加了一些数字,这个呢,我们就不再说了啊,同学们下来看,自己看一看,然后呢,我们现在呢,就准备把它执行一下啊,咱们看一看,咱们的这个结果跟我们预想的是不是一样的,所谓的结果呢,就是说我们因为默认情况下。
01:00
咱们这边的黑名单中是没有任何数据的嘛,对吧,刷新一下没有任何数据,然后这个表里面也没有任何数据,那么在最开始的时候,这个表里面会不断的增加统计数据,当我们的数据不断增加,不断增加达到它的阈值的时候,这个时候怎么办?是不是就应该在这边增加黑名单了,对不对,当我们的黑名单数据越增越多,越增越多的话,那么所有的数据就不再发生变化了,因为全都加入到黑名单来,我们来验证一下啊,那我们这里呢,这边是生成数据,这边呢是消费数据,我先给他消费,因为消费的话没有任何的这个结果嘛,所以我们先来啊,呃,我们先来稍微的等一下。OK,然后呢,我现在呢,准备的这个位置啊,大家可以看到我现在呢,这边有数据啊,其实是一些历史的遗留数据啊,这个呢我们来,我把这个呢给它稍微的清空一下啊,咱们清空里面没有任何东西,现在呢我们也给它清掉,清掉以后应该就没有东西了,那我现在呢给它来啊,我们在这里呢生成数据,咱们运行。
02:00
运行以后,我们现在呢,不断的去生成我们的数据,生成数据之后,那么一旦数据生成,我们这边就会消费数据,那么我们在诶已经出来了,出来以后大家看一下我们刷新,刷新以后你看这就是我们的数据,你看我们的3536对吧,刷新刷新以后5165对吧,你看数据会越来越多,咱们刷新刷新啊咱们稍微等一下,等一下以后,诶数据会发生变化,哎哟,咱们那个是30个是吧?诶可能还得等一会儿啊嗯,咱们稍微的再等一等吧,啊这个好像,诶现在数据量越来越多了,大家会发现这就是我们现在统计的这样的一些我们的数量对吧?诶数量这个已经到了22了,这个一号用户啊,现在基本上快要到了咱们刷新。刷新25 20那也差不多,那么我们这个如果到达30的情况下,应该会拉入到黑名单当中,诶大家看已经到30了,那我们在这看一下,点一下刷新。你看我们的这个一的这个用户的已经加入到黑名单了,对不对,那我们再刷新,刷新以后再来啊,再来这边28了也基本快了,这边29了也基本都差不多了,刷新刷新以后32,然后呢,这边30你看都有了吧,那我这边呢,来咱们刷新,你看1256这四个用户现在已经进入到黑名单当中了啊,所以啊,这就是实现了我们的一个功能,就是我们的数据在不断的去统计,不断的去统计,然后呢,一旦超过预支就拉入到黑名单是吧?火线刷新刷新以后你看所有的用户就全都进来了,咱们总共就是六个用户嘛,对不对,因为我们是那个随机数是生成零到五的嘛,加了个一就是一到六,那么一到六现在就都有了啊。
03:38
好,这个呢,我们就演示到这里啊,这是我们给大家演示的一个小功能啊,但这个功能啊,说是小功能呢,其实主要是它的程序有点复杂,这个复杂并不是逻辑多复杂啊,而是我们当前的这个代码写起来比较麻烦,那么好,那我们现在就准备呢,在我们测试成功之后,把这个代码呢做一个简单的优化,那么哪些地方需要优化呢?首先大家会发现在我们这里会有大量的一些什么呀,我们的这个JDBC操作,其实这个JDBC操作就那么那么几步,比方说第一个写社文,然后呢传参数,第三个执行,然后关闭资源,所以这个操作基本上是一种固定的写法。
04:20
那既然是一种固定的写法,那我们为什么要每一次都要去写一遍呢?恰恰是因为这样的代码太多了,所以导致我们会感觉这个代码量比较多,对不对?但其实就是一些固定的步骤,那这个怎么办?其实大家看我们课件,我们课件当中啊,咱们这边会有一个什么东西呢?来咱们叫做,嗯,咱们在这里呢,叫做JDBCU,这个里面大家可以发现它里面就有什么呢?哎,把这个封装的方法,把我们的单条数据插入insert,那么这个insert的操作呢,就会在这里面有connection,有circle,有参数,诶你把参数呢,以数组的方式给我传进来,然后呢,把这个circle给我写上,那么只需要一行代码,这事就解决了,这也就意味着我们根本就不用像之前一样,还得这么去写一大堆,不用就一行一句就可以了,顶多这个舌口纹呢,需要去考虑考虑对不对,所以我们这个呢,给大家改善一下吧。
05:15
我们这里拷贝啊,拷贝以后呢,我们写上一个requirement啊,这个其实还是一对吧,那我们这里加个一得了,然后我们点击OK,然后放过来啊。呃,放过来之后呢,我现在呢,我们需要稍微的变化一下,那么所谓的变化呢,是需要先根据课件当中把这个东西啊,我原封不动的我们来拷贝啊,咱们原封不动的拷贝,拷贝到咱们那个YouTube当中去,放到下面来。放到下面来以后,大家可以看到这是我们prepared statement,然后呢,我们这边就有一个我们的插入,那么connection circle和那个参数对吧?那么除了这个单条数据插入以外,我们再来往下看,咱们叫JDBC啊,咱们的U点,我们叫执行,然后要传一个连接对象,然后再传的蛇口纹,那这个蛇口纹呢,在我们这个位置就是有了,对不对,所以啊,我们拿过来啊,咱们拿过来。
06:11
我们把这个拷贝吧,嗯,拷贝我们写在这儿啊。咱们叫做circle,诶放过来以后把circle放进去,然后呢,我们的参数呢,它就写上一个R,然后写上一个括号,这里我们写上UU,诶这么写就可以了,对吧?那所以呢,你大家看啊,我们点一下里面是不是就有这个close这个东西啊对不对,它如果有这个close这个东西的话,那咱们就不需要了嘛,对不对,那所以我们这里呢,这个connection的关闭呢,我们给他来啊,这个咱们都不要,所以这样的话,我们代码量是不是就简化了一些,对不对啊,只不过这个circle感觉有点长,但是其实我们的代码呢,就简化了很多啊,然后我们接着往下啊,下面呢,是我们的查询数据,这个查询数据呢,大家会发现我们这个查询数据呢,其实就是判断它有还是没有啊,所以呢,那我们完全呢,就可以把咱们这个拿过来啊,判断他有还是没有,所以咱们拷贝。
07:08
拷贝以后拿过来在咱们的这个地方给它封装一下,嗯,放到这儿。好了,放到这以后,我来确定一下,那其实传个连接,再传个circle口,再传个参数,然后得到一个布尔值,呃,所以呢,我们这里呢,给它来啊,那么这个地方来去掉我们叫做a flag,嗯,它等于jdbc u点我们叫is,然后把连接对象放过去,连接对象放过去以后,剩下就是蛇口纹了,这个蛇口纹呢,我们直接给他拿过来啊。咱们写上咱们叫circle,哎,放过来,那么circle呢,就给它放到这里,那么咱们这个参数叫做R,然后括号,括号以后看看啊,咱们叫做day u的广告,OK,那现在呢,这个flag有了之后,大家看一下,我们直接呢就把这个地方拿过来了啊。放到这里,咱们叫flag,这个咱们就不要了。
08:03
那么有了之后,那我后面这个地方呢,其实就不需要了吧,对不对,哎,这个咱就不需要了,把这个呢给它来close掉,好,那么我们来回过头来,回过头来,我们简化之后这个flag,那这个是update,这个update呀,其实也可以在咱们上面这个地方执行,为什么呢?因为它的这个插入啊,其实本身执行那个修改也是完全可以的啊,所以呢,我们这里呢,来咱们操作一下,同学们叫做它咱们来放到这儿,咱们点咱们叫execute update,然后把这个circle文给他拿过来啊。好,那我们写上circle,诶我们这个最好别冲突了,咱们写上一个它咱们叫CIRCLE1。和那个connection好,然后呢给它放过来,放到这边,然后呢,我们的参数呢,跟刚才是一样的,也是四个啊来阿瑞,然后写上我们的count day,然后我们的U,我们的广告好了,你这么写完以后,这个呢,我们就不需要了啊,来把它关掉啊,把这个呢都去掉,这样的话代码量就少了很多啊这个然后这个呢是我们查询,这个查询我们依然是判断它是否存在嘛,对不对,所以啊跟前面其实就没有什么太多区别了,那我们这里再来,然后呢,把这个呢我们来拷贝啊,拷贝以后拿过来翻过来,这个写上一个叫CIRCLE2。
09:25
然后呢,这个叫CIRCLE2,然后呢,这个叫FLAG1,然后呢,我们这这边呢,就是FLAG1,这就是它了,嗯,然后呢,这个是day u和广告没问题啊,就是我们这块也是对的,那么然后把这个呢,我看看啊,把它拿过来吧,嗯。拿过来以后看看这个CIRCLE2,那是不是应该放到这儿了呢?嗯,放到这边啊,然后把CIRCLE2放进去,那这个就不需要了,诶把这个都去掉啊。好,那么现在呢,这边是一个我们A指标也都删掉啊,咱们也都删掉。然后下面呢,是我们的insert这个其实你看跟跟前没有什么太大区别呢,同学们你会发现是不是没有什么区别啊,所以我们的insert呢,咱们直接拷贝啊。
10:09
来直接我们拷贝,拷贝以后这里面给他一个咱们的CIRCLE3,嗯。来咱们的CIRCLE3,然后放到这里,然后呢,里面是user和user没问题,那么update close,诶都是一样的啊,所以这个代码就可以简化了,简化以后那么就剩下最后一个了,这个呢,就是增加数据,那增加数据不跟这个又差不多了吗?所以呢,来拷贝,拷贝以后拿过来啊,咱们放到这里,放到这里面写上一个CIRCLE4吧,嗯,把这个CIRCLE4放到这边,然后呢是day啊,咱们叫做U,咱们叫做day,咱们叫做U广告,还有那个叫count。好了,那我把这个circle呢给它放过来。好,放到这边。行了,那这个时候就执行呗,那执行以后它不就不需要了吗?好同学们,现在呢,我把咱们这个程序啊,就做了一个改善,你改善以后你会发现呢,其实就没有那么多的代码了,只不过就是这个搜课文呢,需要把它给它写上,基本上就是一些我们的什么,我们的一些方法啊,这些都是我们封装好的。
11:16
所以啊,在工作当中其实会有一些很多重复性的代码,这个我们如果封装好以后,对我们的提高开发效率是非常有帮助的啊好,这个呢,我们就说到这里,咱们就不演示了,因为这都是我们现成的封装啊,这个咱们就不说了,那我们回过头来我们再说一个啊,刚才我们是通过这种封装的工具类来提高咱们的开发效率,其实在咱们整个的程序的执行过程当中,还有一个地方我们需要考虑效率的问题,什么地方呢?就是我们当前的这个位置。咱们的RDD,它的这个for it方法。For each这个方法它会什么呢?它会每一条啊,它会每一条啊数据,它来创建连接啊,创建连接,所以大家会发现这个地方有一个叫get connection,它会创建一个连接,那么如果你创建一个连接的话,本身没有问题,而且你有数据库连接池,这个本身是挺好的,可是你的数据量太多了。
12:21
你太多的情况下,你这个连接可能是不够用的,那么这样的话你可能就会需要长时间的等待,有可能会导致出现问题,所以呢,我们希望干嘛呢?你不要每条数据创建个连接,这样的话不是很合适。那我们怎么做会更好一些呢?对不对?就你现在怎么做,你每条数据就是创建一个连接,当数据量多,你的连接对象就多,你的资源消耗就非常的厉害,那我们怎么能够减少资源的消耗,怎么能够提升我们的性能呢?对不对?那我们告诉大家,这里我们只要什么呢?就是不要每一条创建就挺好的,哎,老师,那简单了,你把这个connection你提出来不就完事了吗?对不对?你提到外面来不也就可以了吗?
13:08
首先大家记住啊,你如果咱们假设你把它提交到外面来,然后在里面去用它,行不行呢?我们告诉大家有问题,为什么有问题啊,这个for it记住了同学们,这个我们的for each方法,它是我们的RDD的算子。所以呢,我们算子之外啊的代码它是在啊,它是来在我们driver端执行的,在driver端执行。而我们的算子内啊,算子内的代码它是。是在我们的execute端执行,所以啊,这样它就会啊,咱们叫涉及我们的B包操作啊,那么我们driver啊,咱们driver端的数据就需要传递到我们的execu端。
14:08
啊,咱们的端,那么需要我们的数据进行我们的序列化。这个咱们之前都讲过吧,对不对?我们的driver的数据是不是应该传给我们的excuor端来做序列化呀,这个咱们之前讲过,但是问题就在这儿了,咱们的连接对象啊,咱们说一下数据库的连接对象,它是不能序列化的,它为什么说不能够做序列化呀?为什么为什么说不能够做序列化,是这样的,同学们,我们大家学买SQL应该都学过,如果有一台机器买SQLA,现在有另外一个客户端B,我们的B如果想连接A的话,是不是需要授权呢?你有权利访问我才能够访问嘛,对不对,我给你授权。那么如果不给你授权的话,你是没有办法访问的,那好了,我现在A我信任B,那我给你授权让你访问,但是呢,你把这个连接对象你序列化之后给了C了,然后呢,这个C呢反序列化,如果它能连上的话,那你的授权还有意义吗?没有意义了,为什么呢?因为这个C我们A又不知道。
15:14
咱们A哪知道C是什么东西啊,根本就不清楚对不对,所以在这种情况下我们就有风险,所以啊,我们的连接对象是不能被序列化的,包括以后你们学什么red那种东西,那种连接都是不能被序列化的,所以说你提到外面这个事儿是不行的啊,你也只能放里面,可是如果你要放里面的话,你性能又低,你放外面的话又不行,那该怎么办呢?对不对?所以啊,我们这里说一下我们的RDD,哎,咱们的RDD它提供,嗯,它提供了一个算子,可以啊有效,咱们叫做提升啊,咱们叫做提升我们的效率,嗯,那什么算子呢?大家看一下叫RDDDR,我们叫做for partition。
16:02
这什么意思呢?就跟我们当时学RDD算子当中那个map partition是一个意思,它会以一个分区为单位进行数据的处理,那么也就意味着在这里面我们拿到的数据是什么样子的呢?来啊,我们这里呢,写个括号啊,咱们写个括号,呃,这个括号呢,我们拿过来,咱们写上,咱们叫做迭代器。他把一个分区的数据给他拿到手里了,啊,就是这么回事儿,那这个我们拿到手里之后,那我接下来呢,我要对这个数据进行处理就可以了,所以啊,咱们这里呢,其实可以用这种方式来做,那这个里面咱们再来点点以后咱们叫for it对吧?诶就for it,那这个时候呢,诶你再把这个拿过来就可以了啊,来拷贝,拷贝以后放过来啊,所以呢,大家会发现呢,我们这个for跟我这里的for意就是两回事,这是一个集合中的方法,这是一个RDD的算值,它涉及到数据的传递和序列化,而我这里是不涉及的,所以如果你把连接对象你放在我们的这个位置,然后在这个地方给它关掉,咱们的close,你这种方式的话,它是以一个分区为单位来创建连接对象,那么这样的话呢,我们说了啊,性能就可以得到提高,它不是一条数据创建一个连接,而是一个part创建一个连接啊。
17:26
所以这个算子的作用就很简单了啊,来就是它,嗯,那么我们可以一个分区创建一个连接对象,连接对象那么这样啊,这样可以减少,可以大幅度大幅度,嗯,咱们叫大幅度减少我们的连接对象的数量啊,连接对象的数量提升我们的效率啊。提升我们的效率,所以啊,这是我们需要去关心的,刚才呢,是通过那个工具类U来简化咱们JDBC的操作,现在呢,我们是通过算子呢,来简化我们的这个连接的操作,其实目的很简单,都是为了提升性能,对吧?那我现在呢,这么写之后,你把这个代码再拷过来就可以了啊,所以我这个呢,就给大家说一下,咱们就不再去把每一步都拷贝过来了,咱们就告诉大家有这么一个方法,有这么一个算子就可以啊,这个呢,我们回到咱们之前给大家讲的内容当中,咱们回来回来以后在咱们输出的这个位置,大家看他就有这么一句话,咱们当时啊,并没有详细的去讲,他就说了。
18:33
我们在这个地方说了常见的用例呢,是把数据写入到MYSQL的外部数据库当中,他说注意连接是不能够写在driver层面的,诶,我们说了,你如果把代码写在我们driver层面,把那个具体的对象的使用放在execuor端,这样的话就涉及到序列化的问题,但是它不能够序列化啊,如果写在for中,则每个RTD中创建一个数据的一个什么连接,那么这样的话得不偿失,性能会下降的非常厉害,所以增加这个叫for is partition在分区中创建,这是每个分区创建一个连接,这样的话性能可以得到提高,这也是我们需要给大家去讲的,好吧,同学们,就是我们用这种方式就够了,你把这么下面的代码呢,原封不动拷贝过来就可以了啊。
19:23
好了,这个需求一啊,咱们说到这里其实就够了啊。
我来说两句