00:00
那接下来我们来聊一聊,呃,比较常见的一个反压。那可以说你只要开发flink,肯定经常呢,或者说曾经碰到过一个反尼亚的情况。那首先呢,这就对大家提出了一定的要求,第一个你要基本理解它反压的一个原理。你知道原理,你才能去解决它,第二一个就是你要知道怎么来定位问题,哎,瓶颈在哪里,是谁出了问题。是哪里写的不行?第三一个你定位到了,你接下来要知道它的一些解决思路。这是咱们分这三个方面给大家介绍一下。那首先呢,关于法尼亚的一个介绍,这边推荐大家看这一篇那个。Flink官方的一个中文学习网站啊,上面介绍的比较详细啊,这边我是打开了。那这篇文章呢,是呃,OPPO大数据平台的一个负责人张俊老师的一个分享啊,写的还不错。
01:04
非常好啊,不是不错啊,那么首先咱们了解第一个背景,咱们挑重点讲啊,咱们也不去对比一些其他框架的反压实现了。呃,首先咱flink的反压机制啊,它是有一个分水岭,是1.5版本,1.5之前呢,它是基于TCP实现的一个。呃,反压那么1.5开始呢,他用的是一个机制,信用机制。那咱们直接看这个1.5的啊,那我找一找。咱们看这张图简单来理解一下啊,咱们如果你想了解更加深入具体的,你可以好好的品读一下,这篇文章讲的还是非常详细的,来那1.5开始是基于credit,我们先了解它为什么叫很简单啊,这是你看这是一个task manager的一个task task a,那对面是一个task b。
02:06
呃,首先我们要理解一个。Task,或者说一个算子,或者说呃,就task吧,他往另一个task发数据,中间涉及到一个东西。啊,就是AB。A往B发送。它中间有一个缓冲区,这个大家要理解。比如说A要发给B,他会走自己的一个,呃,输出缓冲区。那么接收这一块,它也有一个缓冲区,叫输入缓冲区,对吧,它的名字就对应于这个。这个是输出啊,这个吧,Result partition,我简称为RP啊。发送端有一个RP,就result partition,那接收端呢,有一个input gate。叫IG。啊,咱们简称嘛,你看就是这个名字input。那么它的基于反压什么叫信用机制呢?很简单,就是比如说他这既然是缓冲区,肯定有大小啊,有大小就是说它有一个上限,那比如说他只能塞三个东西啊,三条数据假设啊,那是不是说他第三条数据发给他B是不是已经知道自己吃不下了。
03:20
对吧,那正常我们想的是,那就第四条再接着发呗,但是发现他发不下,然后再丢弃啊,这种效率就比较低了,这个是1.5之前啊,那么1.5之后他是这样,他每发一条数据,咱们模拟一下这个过程啊。我重新画个图吧,来看这个。AB缓冲区咱们用蓝色表示啊。这个是一个RP,这个叫IG,具体呢,它缓冲区还有分不同级别,咱们先不管了,他这样啊,比如说这里有一条数据我要发给他对吧,那发给他的同时,那B也是会给他一个A响应。
04:09
对不对,哎,说白了就给一个响应,这个响应它会给一个什么呢。就是说我还剩多少,比如说它一共就三个格子。我最多最多我撑死只能接三条,同时在缓冲区缓存三条,那他A在发的时候,他会告诉他哦,我现在发给你这条,然后后面还有几条准备发。比如说后面还有三条准备发,然后B呢。响应的时候就会告诉他,哦,这条我收到了,另外我只能再吃两个。啊,它是会有这么一个交流的,就B主动告诉他,我还只能只能塞两个了,然后呢,这个再继续发,假设这个缓冲区的数据没有被处理掉啊,还在缓冲区里面,他会发送给他,同时告诉他,哦,我除了我这条之外,后面还有两条数据。
05:03
啊,然后B收到了放缓冲区,然后他自己一看,哦,还剩一个格子了,然后再告诉他,行,收到了,那我接下来只能再容纳一个了。好,那接下来。第三条数据也发过来了,发过来之后他还会告诉他,我我还有一条数据要发。然后呢,B就收到了,然后一看哦,自己没空间了啊,就内部的那些申请都申请完了,没空间了,然后也告诉他,好,我收到了,我接下来吃不下了。然后第最后一条他不会发送A就不会再去发了啊。那为什么每发一批都要去应呢什呢,因为这剩的是在不的,因为一条数据是已经处理完走了对吧?啊,所以他每次都要响应,大家大概理解什么叫就说白了就是接收方主动告诉上游,我还能能够容纳多少,还有多少能够接收的啊。
06:02
那A呢,收到这个之后,对方为零,他就不会再接着发了啊,不发了,知道你成受不了。就基本的咱们粗糙的来理解,那么另外深入一点大家去了解,要了解到它这个缓冲区,它本身有一个input channel,还有一个什么partition,对吧?啊,这是有一个初始化的大小,另外呢。它每个这个里面还有一个叫本地缓冲池,还有一个网络缓冲池,这这几个跟这个有什么区别呢?来我咱们标个序号。这个叫一,这个叫二,这个叫三,它是这样的,首先一呃自己先接收是不可能一会儿自己就满了呀,满了的话,他会尝试着向二申请。向二申请。那二申请呢?好,过了一段时间,可能连二都没有余力支持一了,在接下来二他才会去向三申请。
07:04
啊,也就是说他是一步一步申请的。啊,一步一步升级的,那最终是不是这个三也有满的时候啊,对吧?啊。当他这边就内部的申请都申请不到的时候,他返回的就是零了啊,说我塞不下。这个就是一个基本的,咱们粗略的来理解啊,就。咱们用大白话来理解,是这样子啊。那么简单的来说,咱们就是每个task数据都以什么阻塞队列的方式来传输嘛,下游来不及消费,导致队列被占满,这个队列其实就是这个这个这个对吧,来不及消费,缓冲区都塞满了,塞满了之后上游的生产也会被阻塞,什么意思呢?他这里是不是也塞满了?他还发不出去对吧,他自己塞满了啊,一种导致数据源的摄入被堵塞,什么意思呢?很简单,咱们画几个task,一个帧拍不来。
08:00
啊,比如说咱们的一个拓扑结构是这样。那比如说他不行。他自己的输入缓冲区是不是满了。踏板的是不是导致他的上游输出也满了?对吧,上游的输出满了,是不是导致他自己本身的输入也慢慢在堆积数据,是不是这里也满了,那他满了是不是又把这个压力传导给上游。这里的输出又满了。好,他的输出版呢,是不是又影响自己的输入就满了。对吧,因为咱们数据传递是这样,自己是自己的输入接收端接收到数据,经过处理,处理完之后放输出啊,对吧,这是属于一个task manager内部的传输,那像这种是可能是跨task manager传输。总而言之,是不是从这里一直往前传导压力,那如果它是一个source扇子,它的输入缓冲呢,是不?直接的现象,我们可以看到它不再消费新数据了,就感觉跟都堵死了,对吧,就像你开车啊,堵车了啊堵死了。
09:07
所以flink的反压它是一个什么呢?是一个被动的啊,不是主动,他是被动的,而且是呃,咱们不用你去再做什么事情,它自动反应。那一般出现在什么场景呢?短时间的负载高峰,也就是说突然来了个数据峰,比如说你们搞了一个秒杀活动,突然呢,那个活跃在线,同时在线活跃数特别多,下的订单也特别多,一下子大量的数据打过来,那可能就来不及处理啊,这也是正常。接收速率远高于处理的速率,处理不过来嘛,忙不过来,这个大家能理解啊,另外呢,像什么数据倾斜啊,代码写的有问题啊。像这种影响性能的一些问题,可能产生反压。这些,所以说我们反压并不是说呃什么。
10:04
太特殊的东西啊,说白了就性能不行,或者说太快了,它受不了啊,仅此而已,反。另外我们聊一聊它的一个危害。那如果真的我们的程序产生了反连,那会怎么影响什么?大家想一想。首先,第一个影响的就是checkpoint。对不对,为什么呢?呃,比如说这是咱们的一个拓扑结构,这是A算子,这是B算子,它并行都是二,下游是一,比如说这样子啊,这样好理解,那咱们做B这个。呃,唯一的一个task要做checkpoint的条件是什么?是不是上游两个都将Barry传递给他,他才会去做呀,也就是说咱们在Barry对齐的时候,那是不是有可能说。一个到一个一直到不了,有可能吧,那如果你已经产生了,这个是不是解决,就是说数据前面的不动,这个是不是永远到不。那大不了是不是就了咱们切泡的时间呢?
11:03
对吧,就像一条高速公路,本来很通畅,比如说从呃,你从A点到B点,日常不堵车,开车可能就十分钟,那可能某一天呃,放假了,节假日了,或者怎么样,上下班高峰这里堵车了,那你。那你在开车堵车,你从A到B。平常十分钟,现在是不是可能是按小时计算呢?可能要开几个小时,这个道理很简单,第一个直直观的影响,咱们可以看到checkpoint。时间变长了,甚至呢,一直超时失败,一直超时失败啊,另外一个就是会影响状态的大小。状态的大小是什么呢?咱们Barry对齐还是刚才的场景。呃。这个B。要做check point是不是得要求它所有上游同一barrier同一编号的barrier到齐啊,对吧,比如说这个到了下面这个到不了。
12:01
但是你想想上面这个。这个bar后面是不是还有一堆数据呢,这些数据是不是也紧跟着到了B这里啊。那这边B是怎么处理呢?咱们基于精准一次,并且是Barry对齐的场景下,它是会把这些数据缓存在哪里。是不是输入缓冲区啊,就像刚才介绍的对吧,接收端的缓冲区,那么他其实在做状态的时候也会缓冲区的数据一起缓存起来。你看啊。这时较快的barri到了后,它后面的数据也会被缓存起来,不处理,这个放在IG里面嘛,啊里面,那么这些被缓存的数据也会放到状态里,导致check变大,说白了你看影响人家时间变长了,还影响人家变大了,多存了一些数据。那这种呢是十分危险的,就长时间肯定这个导致这个甚至这个作业崩掉啊。资源耗尽。
13:02
对吧,具体的体现表现我们可以看到,诶,这个方怎么突然就经常超,一直在超时啊,对吧,那甚至说我怎么出现了OM啊啊等等,甚至说咱们基于雅安的说容器被K了,这对应的是不同场景啊,你用的是内存状态,后端可能就是OM,你用的是RODB状态,后端可能就超容器限制,还记得那个管理内存吗?Manage的。啊不,Manage的这一块内存memory啊,是不是在堆外啊,它这个的控制并没有非常精确,呃,一不小心就超了,那超出容器大小直接就被雅给切掉了啊,所以这个也是很常见的一个现象。一个是反的影响,总而言之呢,出现的反尼,咱们一定。要先把这个反压的源头找到,并且呢把它解决掉啊,这是咱们对于反压的一些理解啊。
我来说两句