00:00
清楚了一个代码经过转换处理之后,我们把自己带入招manager的这个角色,已经知道最后要执行的任务有多少个,诶,那还有一个问题,就是我当前这个招manager还有一个事情是要去向resource manager申请资源啊。那这个申请资源我知道现在有五个任务了,那这五个任务是不是就需要有五个slot来执行呢?大家自然能够想到,那最简单的方式当然是这样了,你既然有五个并行任务吗?这任务不是都可以并行执行吗?那所以我就分配五个资源,一个slot上去执行一个任务,这样不就完事了吗?啊,但是大家会发现。跟我们的实际情况不一样。我当前的这个集群只有两个slot,但是大家会发现我们之前如果要是设并行度是二的话,提交也可以成功啊,没有问题对不对?这里entry class。然后给一个并行,就是二知道得到的是前面我们说的1225个任务,如果直接提交能成功吗?
01:03
哦,现在肯定不能,因为我们又开启NC对吧,NC-LK7777。好,这里我们重新提交一下啊。大家看提起来了对吧,没有问题,我一共只有。大家看一共占用了几个,Slot本身有两个,现在只剩下零了,所以相当于占用了两个,对不对啊,所以五个任务这里面task是五,五个任务只占用了两个,Lo就跑起来了,那这又是为什么呢?好,接下来我们就专门再给大家介绍一下。任务和任务槽,给大家详细的说一下它到底是怎么回事啊。Task和sla的关系啊,那这个其实我们都已经知道了,在flink里边真正干活的人是task manager,那么每一个task manager大家都可以理解成是一个GVM进程啊啊,那这里比方说我们有两个task manager啊,那么它就是两个GVM进程,那么一个进程大家知道可以在独立的线程上去执行多个子任务,多线程嘛,所以每一个线程都可以运行一个任务。
02:11
而这个任务应该运行到什么地方呢?啊,这个任务当然应该单独的分配一段一部分资源,就是给他单独的分配一部分内存,对吧?你要让这个不同的任务之间隔离开嘛,要不然他们互互相之间如果有影响的话,我们数据处理就乱了,所以为了更好的隔离性,我们应该把task manager的内存资源,主要就是内存资源做一个划分。每一个每一块内存资源上,我们就把它叫做一个单独的task slot叫做一个插槽,其实这个概念大家如果要是,呃,我不知道大家有这个经验没有啊,如果有同学,呃,就是玩过以前这个老式的游戏机的话啊,大家还记得以前有这种什么小霸王游戏机对吧,那种插卡式的游戏机。
03:00
大家应该对这个理解就会特别的深刻,就呃插卡式的游戏机那个那个比较老了啊,呃,它就是本身这个游戏机上面有一个卡槽,一般都是有一个啊一个卡槽,然后我们插那种卡带。插上不同的卡带就可以跑不同的游戏,对吧,你就可以在里边这个选择不同的游戏玩啊,那所以这里面大家就会发现了这个卡槽,它其实是什么呢。啊,当然在游戏机里面那是一个接口啊,对于我们task manager来讲,它其实就是一个我当前提供能够运行游戏的资源嘛。对吧,我这里面有一个资源,然后呢,你如果有具体的游戏,有具体的任务来了,我就放到这个对应的资源上去执行,哎,这就是这个所谓为什么叫槽啊,它就是这样的一个概念,所以呃,这个task slot,它是一个task manager,静态的一个一个特性,一个特征,它是对资源的一种划分。那么为什么要划分它呢?哎,那其实主要就是说,既然你要做多线程嘛啊,那线程之间又要做隔离,要分配独立的资源,那一个task manager到底能执行多少个任务呢?到底多线程能多到什么程度呢?啊,当然一方面我们这个Linux系统里边都有这个最大的那个,呃,进程数的这个线程数设置对吧?那另外一方面我这个内存资源你也不能无限分啊,所以这里其实就是要指定一个task manager。
04:28
最多能接收多少个task,换句话说就是task manager可用的内存,我要把它划分成多少份好,所以这其实是一个task manager的静态能力,也就是说我就划分了这么多,就是一个游戏机上我就开了这么多槽,同时就就能开插这么多卡,然后跑这么多游戏,嗯,当然了,有这么多槽你也可以不用,对不对?那槽可以空着嘛,大家可以看到,当前如果我们有五个任务的话,我可以把它一字排开,直接放在不同的槽里边,那这个槽空着就空着了,对吧?那就相当于这个,呃,可能也算一种资源浪费吧,那但是没问题啊,这完全是可行的。
05:10
啊,这就是任务和任务槽的关系。然后接下来他就会想到了,你要这么看的话,那是不是我们之前就一字排开,直接占用这个,呃,五五个这个任务槽就可以了呢?啊任务槽我们再给大家多提一句,就是说它是task manager计算资源的一个固定大小的子集,我们说计算资源主要其实是CPU和内存,那现在。对于这个弗link而言啊,Slot其实它的隔离主要是针对内存,因为CPU这个东西是,呃,没有办法直接去限定它,它只只占用一个对吧,或者说因为你有些CPU就是单核,那怎么办呢?呃,它必须分时复用嘛,啊所以说一般情况是,但是一般建议大家啊,就是配这个task manager的,呃,Slo数量的时候怎么配呢?你按照它的那个核心数量来做一个配置。
06:03
啊,因为如果说你按核心数量配置的话,它最优的调度方法当然就是一个核分配给一个slot,那就不用分时复用了,各自管理各自的就可以了。啊,然后接下来要给大家说的是,我们要解决还是要解决那个问题啊,为什么最后提交之后,他用两个,我们只有两个lo它就跑起来了呢?你现在有六个lo跑起来很正常啊呃,这这五个都能分配开嘛,那为什么五个任务两个slo也能跑起来呢?那是因为。在弗林里边默认是允许。任务之间进行slot共享的。好,那所以这里面大家会看到,就是如果说啊,前面的这个例子,这个是并行度是二对吧,然后最后这个think并行度是一,所以一共是五个任务,那假如说前面这个并行度我们设成六呢。哎,射程六难道总共有多少个任务?那就第一个有六个并行子任务,第二个六个并行子任务啊,Think不变还是一啊,那就是六加六加一,13个任务,难道说13个任务就需要13个slot来运行吗?不是的。
07:08
大家看13个任务可以直接这么运行。就是同一个算子的啊,或者这个算子链对吧,它的并行子任务一字排开,然后不同的算子先后发生的这个任务我可以共享在一个slot里面。大家看下面的这一步操作,可以直接也也跟上面这一个操作共享lo对吧,也是一字排开,排开就行了,然后think随便选一个,因为它可以共享嘛,随便选一个放在这儿就行了,所以最终我们用六个slot就可以把它跑起来。哎,那家想这样的好处是什么呢?啊,这样的好处,呃,其实大家仔细的做一个这个思考,可以能想象得到啊,就是说假如说比方说像我们这个例子啊,Source map,然后后边有这个key之后window操作,那大家想一下,尽管这个source map都已经合并这个算子链了啊,两步操作合在了一起,但是大家想我读取数据,然后做一个简单的转换map map转换这个好像非常容易,非常快,对吧,所以这一步操作是很快就完成的,而后边这个KY之后,然后window做这个开窗的处理,这可能很复杂,对不对。
08:23
诶,所以大家就会想到,如果你做这样的一字排开的话,就有可能出现什么啊,那就是有一些它是资源密集型的任务,它对资源的耗费非常的大,有可能他会一直占据着资源在在那儿去运转,而如果说当前的这个任务比较轻松的话,那可能他跑完之后就没事干了。那就会出现忙的忙死,闲的闲死。我们的资源利用率就不够高了,不光是这里边有空余的,对吧,Slot没有用上,而且你即使是占用的,他也经常是闲着的。这样其实是不好的,那怎么办呢?允许不同的算子进行任务slot共享,那就是如果说你这个呃k window啊,这个操作它资源密集,它占用时间长,那你就大部分的时间你你都来做它嘛。
09:10
然后你做他的空闲期间,诶,只要有有这个做完了啊,有新的数据来了,然后我用这个s map,然后把它读进来就可以了,读进来之后,只要他闲了又可以去其他的这个slot,又可以去做这个对应的window任务,对吧?啊,就是所有的数据来了之后,我都可以让他最高效的利用起来哪一个。哪一步操作耗费的时间长,我的大量时间就都用来做它啊,那别的那个轻松的工作,那我一瞬间搞定不就完了吗?啊,所以这样的话,我们就可以自行分配对资源占用的比例,就可以把最重的活儿平均分配给所有的task manager上的所有的slot,这样就会更高效。然后另外还有一个好处是,每一个slot上就可以保存我们整个的作业管道,什么叫作业管道呢?就是从头到尾所有的操作都在一个lo里面有啊,那这样的好处就是说,即使别的挂了。
10:06
这他还能还还能做对不对啊,就是当前你还能直接去去运行吧,不会出现比方说你像有时候我们一字排开啊,有可能我们的那个任务多了之后,那就是一个task manager挂了之后,那可能那那就那就别的就完全就搞不定了,对不对,那最后你就一定要完全分配分配开才可以啊,那这样的话就是相当于我们整个这个稳定性。鲁鲁棒性啊,这个会更高一些啊,那还有一个好处就是说有了这个操作之后,接下来大家就知道了,我们分配资源应该分配多少呢。其实那就是把这个所有的算子啊,它的并行度来考察一下,用最大的并行度当成我现在要占用的slot数量是不是就可以了。啊,那有些同学想,那这个他的并行子任务可以再再共享吗?那当然不能共享了,你想这个并行子任务,我们一开始的想法就是让他要同时处理不同的数,你要再共享的话。
11:07
那它还能同时处理吗?那就没有意义了嘛,那又变成一个了嘛啊,所以就是它的并行子任务,同一个算子的并行子任务一定要一字排开,所以这个是不能省的,那么最大的算子的那个并行度就是我们当前要占据的slot数量。所以有时候我们也说一个流处理程序,或者说一个作业,它的本身的并行度是多少,那是多少呢?哎,就是其实就是它占据的这个料的数量,就是当前算子里边最大的那个并行度。这就是所谓的slot共享,也就解决了我们之前为什么用两个lo不能跑起来五个任务,因为当前它最大的并行度是二,哎,所以一字排开的话,那就相当于呃,我们只要用两个slot共享起来就可以运行了。这就是中的解释啊,啊,那在这里边我们再给大家总结一下,强调一下slot和并行度的概念,就是这个slot是一个静态的概念,是指task manager具有的并发执行的能力,怎么配呢?啊,通过默认集群里边啊,就是我们那个集群配置文件里边task manager.number of task slots进行配置,对吧?啊,那那这个东西其实一般情况下我们配置了之后就不会改了,因为它是本身task manager的一个基础能力嘛。
12:29
推荐大家是直接用当前机器的核心就是CPU核心数量来作为当前的number of tasks啊啊,那当然了,大家也可以就是。因为你可以去设置那个每一个task manager占用的这个内存嘛,啊,对吧,你也可以根据这个内存空间的大小去做一个分配啊,这个也是可以考虑的,然后另外还有一个概念就是并行度,并行度它是一个动态的概念,它指的是真正执行程序,执行任务,运行程序的时候实际使用的并发能力啊,就是我一个task manager可以有这么大的能力,但是我可以不用啊,对吧,我可以提得起,呃,这个200斤的东西,但是我我可以。
13:11
不一直手里边儿拿着200斤的东西走路啊啊对吧,这个大家很容易理解嘛,所以呃,那么这个配置的时候,在默认参数里边就是parallel.default。那如果说我们还要在别的地方提交作业的时候,那可以用杠P参数来指定,还可以在代码里面去指定,指定并行度有多种形式,它有不同的优先级。那最后我们再用一个例子来给大家说一下啊,啊,比方说这里大家看到。这里有三个task manager对吧?呃,然后每一个task manager有几个slot呢?呃,这里边我们配置的是number of task slot是三,推荐用的是CPU核心个数啊啊,当然一般没有三核的,呃,这个CPU我们这里面只是举个例子啊,所以大家看现在我们可用的资源是几个,可用的就是三乘三九个。
14:01
然后接下来如果我们写了一个很简单的一个程序啊,类似于这个word count,呃是做了这个S之后,Fla map它俩合并成一个一个算,合并这个算子链之后是一个任务了,然后后边呢,做了一个reduce,大家把这个就看成那个sum吧,也也可以用这个reduce来实现啊,最后做了一个think,三个三个任务,三步操作啊,如果说并行度直接我们设一的话。那最终执行是什么效果呢?我们知道所有任务可以做slot共享,所以那么三个并行61的话,一共三个任务。他们全会放在一个slot里面,最终相当于我们的这个并行能力啊,集群的并行能力没有派上用场,比方说我们这个默认的这个。并行度啊,我们什么都没给,什么参数都没给啊,呃,那个代码里边也没有做设置,那用的就是弗link com压文件里面默认的那个para.default1最后的效果就是这样。
15:02
这当然不太好了啊啊,所以我们一般情况啊,要充分利用我们集群的这个资源啊,调把这个并行度调大,当然也是看我们数据量啊,你如果要是这个够用的话,那也就无所谓了。然后我们可以调高并行度,比方说调成二,那么有三种方法,一种是直接改集群的默认并行度,这个其实不太推荐对吧,这个改了其实也没没多大用啊,然后另外一个比较推荐的方法是在客户端提交的时候,或者说我们在这一个网页啊,Web UI提交的时候,杠P参数指定当前的并行度。杠P2,那么这样的话并行度就变成了二,每一个子任务都会有两个,就是每一个算子都会有两个并行的子任务,那么总共就有六个任务,因为不同的算子之间可以共享slot,最终是按最大的那个并行度来分配slot,两个slot就可以了。啊啊,那当然了,我们也可以在执行环境里边全局去做一个配置对吧?Set,但是这个也不太推荐啊,因为这个不够灵活。
16:07
那还是没有把我们的资源利用起来呀,啊,所以最终利用最好的状态是什么呢?那就是你有多少资源,我就直接就是你现在可利用九个。Slot我就直接提交的时候杠P9,把并行度设成九,那就一字排开全占满了,这样的话我们的集群资源就会利用到最大。这就是这个状态啊啊,那当然有时候大家可能会想到,那我think不希望,比方说我写到文件,你如果要这么写的话,好家伙,一个task manager上就写三个文件,至少对吧,然后还要有三个task manager上不同的九个文件,最后我合并都很费劲,我就希望直接写到一个文件里面,那怎么办呢?单独对这个write,比方说有一个这个S啊,我们写文件的这个。方法叫做right s csv啊啊,那这个其实就是保存成一个CSV文件啊,单独把它的并行度设成一,那这样的话最后效果是什么呢?最后效果就是只有一个think任务了,它可以共享,那就随便找一个。
17:12
Task slot跟把它放在里边就可以了,最终还是占据九个slot,所有的都占据,最后只不过是由某一个slot上执行了think任。这就是最终的效果。
我来说两句