首先说一下什么是网络流控?通过下图来解释一下这个问题。
在这个时候我们需要Producer的速率降低以匹配Consumer的速率,保证数据的安全性。我们可以通过静态和动态的方法来达到这个目的,如下图在Producer后面加上一个限速器:
但是像这种固定限速的方法会导致许多问题,比如Consumer的速率增加时,不能及时地更改,使得系统的效率较低。
因此,我们需要动态的方法来使得系统拥有更好的性能。
动态方法需要一个反馈机制,最简单的方法就是如上图,Consumer经常地发送给Producer一个feedback,来平衡Producer的速率。大部分的动态网络流控方法都存在一个反馈机制,有的是显式地发送一个feedback,有的是应用了具有feedback功能的基础结构。
反压就是当Producer的速率突然增加,使得Producer的速率远高于Consumer的速率,此时下游的Consumer无法及时处理上游发送过来的数据,当缓冲区使用殆尽时,数据将会丢失。
目前,Storm、Spark和Flink框架都有自己独特的解决反压的方法,Storm是通过ZooKeeper来接收下游的信息,如果下游出现反压,则发送feedback给Zookeeper,然后Zookeeper再调节上游的Producer的速率以此缓解反压。
Spark则是通过Rate作为feedback来解决反压。
Flink相对来说,早期版本没有独特的反压机制,而是通过底层的架构特性,自然而然地解决了反压。Flink使用了TCP连接,在TCP的机制中,滑动窗口机制(计算机网络)自带了feedback机制,Flink正是通过TCP固有的特点解决了反压。具体过程如下图:首先是Producer的速率高于Consumer,空的格子都默认是可用缓冲区:
很快下游节点的缓冲区被消耗殆尽,
此时TCP中的窗口机制会限制发送方的发送速率为0,此时上游节点依旧在接收或是生产数据,由于无法发送,很快会消耗进所有的缓冲区。
这时上游节点的速率也被限制,并逐级反馈到Producer,使得Producer的速率降低以匹配系统的Consumer速率。
这篇博客只是简单介绍一下网络流控的背景以及三种框架的反压机制,供有兴趣的同学参考。
参考:
1 https://github.com/flink-china/flink-training-course/
2 https://www.bilibili.com/video/av55487329/