00:00
了解了所有不同类型的k state它的具体的应用案例,那接下来呢,我们还要介绍另外一个比较重要的概念,那就是状态的生存时间time to live啊,那简写也非常的有名,TTL这个概念可能我们在其他的一些大数据组件或者工具里边也曾经见过啊,那比如说像里边也有TTL的概念,他说的是什么呢?啊,在link里边主要就是因为很多状态,我们在实际编程的时候,很多状态它都会随着时间的推移逐渐增长啊,就比如说像我们使用这个k set啊,K它可能是无穷无尽的啊,我们当前以这个用户作为K做了一个分组user。哎,那我们当前的用户是在不停增长的呀,那所以我们当前保存的对应的这个kid state就会越来越多,那如果说对于状态不加以限制的话,那它最终状态不停的增大就会导致内存耗尽,哎,那所以一个优化思路就是说,诶,我们在代码里面直接调点clear方法吗?之前我们说过啊,所有的状态都有点clear方法,直接可以清除状态。
01:11
但是我们想啊,你假如说现在是我们就是因为user。越来越多了,导致我们的这个状态越来越大,那我就不能直接在代码里边把所有user对应的那个k state全部清空啊,那有些我可能现在还在还要用,所以这个时候怎么办呢?弗link就给我们提供了这样一个机制,就是可以配置一个生存时间TTL,如果说状态在内存里边存在的时间超出了这个范围的话,那就直接清空,哎,所以因为我们知道KC,它不是按照每个K对应的都保存一份。状态实例吗?诶,所以这样的话,就是某个用户如果太长时间都没有对应的数据到来了,哎,都不再去使用它对应的状态了,那把这个用户的状态直接清掉就可以了,而不是把我们在代码里边定义的所有用户的对应的P都清掉好。
02:05
呃,那这样一个TTL在底层上到底是怎么去实现的呢?呃,我们自然能够想到可以有一个进程,哎,不停的扫描当前我们所有的状态,然后看诶是否到这个TTL了,是否过期了,但是我们知道这种方式肯定对于系统资源的耗费是比较大的啊,而且是做了很多无用功,所以我们这里的解决方案就是状态的失效,不需要立即删除。而是我们给每一个状态添加一个属性,这个属性就叫做失效时间,那它的失效时间是什么呢?就是每一个状态创建的时候就设一个失效时间,当前时间加上TTL。就是当前创建的这个时刻,然后加上TTL的时间,就是这个状态将要去失效,将要被删除的这个时间,那到点的时候呢,也不要直接就删啊,到点的时候只要标注一下它已经失效就行了,那等到我们某某一个进程啊,要扫描要去清除当前的内存空间的时候,我们把所有失效的状态直接做一个清除就可以了,那如果说之后啊,对于这个状态呢,又有了访问或者修改操作,我们就可以把它的失效时间进行一个更改,进行一个调整啊,那这样的话,每一次更新失效时间就可以保证一直在用的状态始终可以有效,那长时间不用的状态就可以失效了。
03:35
啊,那在代码当中呢,如果我们想要配这个TTL,主要就是要创建一个state t TL config这样的一个对象,然后接下来把它添加到我们定义状态的那个描述器里边去,这样的话接下来就可以开启TTL功能了啊接下来我们还是在代码里边简单的来说一下吧,啊,之前我们在k state test这个文件里边啊,讲了所有k state的基本的一个使用方法,那这里面我们也可以简单的说一下TTL这个东西到底怎么去配啊,那我们就。
04:10
以value seat作为例子吧,因为我们是基于它的script要去做一个配置啊,所以这里边我们把这个value seat script把它单独的拿出来,这个是deskscript。啊,后边我们也把value script传进去啊,这就是相当于前面我们定义的这个描述器单独的提出来了,那后边怎么样对于这一个value state能够开启它的TTL设置呢?那就是基于value script去调一个enable time to live这个方法,然后这个方法里边我们看到就要传入一个state t TL conflict啊,所以这里边关键就在于。我们需要去。配置TTL。那就是要创建一个它的配置项。啊,那我们自然想到,那就直接去new一个呗,New一个state TTL con,我们点进去看一下它需要传什么样的参数给它的构造方法。
05:09
诶,但是很悲剧啊,我们这里边看到它是private,是私有的构造方法,所以很显然现在它又需要用其他的一些设计模式啊,去构建相应的对象了,我们看一眼哦,里边看到了,里边有builder。这显然又是一个建造者模式,那我们现在怎么样去获取它的builder呢?里边有一个静态方法叫做new builder啊,它可以返回一个builder对象,这里边要传入的呢,是一个time类型的TTL,也就是设置一个当前的状态可以生存的时间啊,那所以接下来我们这个过程就非常简单了啊,直接在这就不是去new一个state TL con了,而是我们应该去调用它的new builder方法,里边需要去传入一个time啊,那当然了,这个time我们需要引入,这里引入的time我们需要注意一下啊,就是我们可以看一下new builder里边的这个time。
06:08
它并不是我们之前window in time.time就是定义时间窗口时候的那个time,它是在flink API common下边的time,所以这个我们一定要注意啊,一定要引对,所以这里边我们引入time,它是flink API common time.time比如说这里边我们就定义一个呃,十秒钟。哎呀,这个时间稍微的有点短啊,就十秒钟就失效了,或许我们可以把它调成十分钟啊,或者说一个小时,这个都是可以的,然后接下来呢,那就需要调一个它的build的方法把它创建出来,当然了中间还可以调一些其他的配置项,比如说我们看啊这个,如果上面啊构造的时候我们没有传入这个TTL时间的话,也可以调set t TL,然后后边呢,还有两个比较重要的设置项,那就是一个可以set update type。
07:00
这个update type又是什么呢?里边传入的就是一个更新的类型,我们看就是传入state t tl.con然后update type。这里面可以调用的主要就是两种,On read and write,或者是on create and write,这说的是什么呢?诶,这主要指指的就是什么时候更新当前状态的失效时间啊,就是他所说的就是更新类型。也就是说我们当时说这个失效的时间是如果对这个状态有了操作,诶,我们在用这个状态了,那这个失效时间肯定就要往后推嘛,所以一般情况下默认啊,我们就是创建这个状态的时候,我们要更新它的失效时间,然后呢,对这个状态有写入操作的时候。也要更新这个状态的失效时间,而如果说只是对他做一个访问操作,只是读了一次的话,是不更新的,所以这种情况那就是所谓的on create and right。
08:04
那如果说我们只要对它做了访问,这也要更新它的失效时间的话,那就把它修改成on read and write啊,就是在有些时候,可能这样的话就是表示当前的状态还在使用啊,就不要让它失效。那另外还有一个我们看到叫set state visibility,那这个说的又是什么呢?我们看这里边传入的是。State d dl conig.set visibility里边那一个是never return expired,另外一个是return expired if not cleaned up,哎,这什么意思呢?这主要就是因为之前我们说状态的清除并不是一旦失效,马上实时的就把它清空了。而是只是先把它标注成已经失效的状态,所以这里边就涉及到一个问题,如果说他已经标注成失效了,这个时候又要去访问这个状态,那到底是返回值还是不返回值呢?哎,所以这两个选项就是一种是never,那就是永远不返回,一旦它已经失效的话,那就绝对不要返回它的值了,另外一个就是只要它还没被真正清空,那即使失效了也返回它的值啊啊,那所以这里边默认的当然就是永远不返回了,这就是我们对于state t TL conig的一个配置使用啊,那我们可以把它叫做conig,这里边就需要传入对应的config就可以了。
09:30
有了这样的一个配置,那接下来呢,我们设置的这个value state,它的TTL时间就变成了十秒钟,也就是说,呃,如果说这里边我们某一个user,它十秒之内没有去更新对应的value state的话,那它的这个状态就直接失效了。啊,这就是关于状态生存时间的基本用法啊,那这里我们还需要注意的一点是我们所说的时间,这里配置的十秒钟其实是处理时间,呃,是以当前的系统时间为准的,目前flink当中TTL的设置只支持处理时间。
我来说两句