在 Flink 社区中,一个最常见的问题是如何将集群从开发环境迁移到生产环境时进行规模估算。虽然确切答案取决于具体情况,但这并非建设性的回答。本文概述了一系列问题,帮助得出可用于指导的资源数量。
数学计算与基准建立
第一步是思考应用程序的运行指标,以得出所需资源的基线。 考虑的关键指标包括:
- 每秒记录数及每条记录的大小
- 不同键的数量及每个键的状态大小
- 状态更新次数及状态后端的访问模式
最后,更实际的问题是围绕停机时间、延迟和最大吞吐量的服务等级协议(SLA),因为它们直接影响容量规划。 接下来,根据预算查看可用资源。例如:
- 网络容量,考虑到使用网络的任何外部服务,如 Kafka、HDFS 等
- 磁盘带宽,如果依赖基于磁盘的状态后端(如 RocksDB)并考虑其他磁盘使用情况
- 机器数量及其可用的 CPU 和内存
基于所有这些因素,您可以为正常运行建立基线,并为恢复追赶或处理负载峰值预留缓冲资源。建议在建立基线时也考虑检查点(Checkpointing)期间使用的资源。
示例:数值计算
我将计划在一个假设的集群上部署作业,以可视化建立资源使用基线的过程。这些数字是粗略的'心算'值,并不全面——在文章末尾,我还会指出计算过程中忽略的一些方面。
示例 Flink 流式作业与硬件
示例 Flink 流式作业拓扑
在此示例中,我将部署一个典型的 Flink 流式作业,该作业使用 Flink 的 Kafka 消费者从 Kafka 主题读取数据。然后使用键控聚合窗口算子转换流。窗口算子在 5 分钟的时间窗口内执行聚合。由于始终有新鲜数据,我将配置窗口为具有 1 分钟滑动间隔的窗口。
这意味着每分钟更新过去 5 分钟的聚合结果。流式作业为每个 userId 创建聚合。从 Kafka 主题消费的消息大小平均为 2 KB。
吞吐量为每秒 100 万条消息。为了了解窗口算子的状态大小,您需要知道不同键的数量。在这种情况下,它是 userId 的数量,即 5 亿个唯一用户。对于每个用户,您计算四个数字,存储为 long(8 字节)。
让我们总结作业的关键指标:
- 消息大小:2KB
- 吞吐量:1,000,000 msg/sec
- 不同键:500,000,000(窗口聚合:每个键 4 个 long)
- 检查点:每分钟一次。
假设硬件设置
有五台机器运行该作业,每台机器运行一个 Flink TaskManager(Flink 的工作节点)。磁盘是网络附加的(云设置中常见),并且从主交换机到运行 TaskManager 的每台机器都有 10 Gigabit Ethernet 连接。Kafka 代理运行在单独的机器上。 每台机器有 16 个 CPU 核心。为简单起见,我不考虑 CPU 和内存需求。在现实世界中,根据您的应用逻辑和所使用的状态后端,您可能需要注意内存。此示例使用基于 RocksDB 的状态后端,它稳健且内存需求低。
单台机器的视角
要了解整个作业部署的资源需求,最好先关注一台机器和一个 TaskManager 中的操作。然后可以使用从一台机器得出的数字来计算整体资源需求。 默认情况下(如果所有算子的并行度相同且没有特殊的调度限制),流式作业的所有算子都在每台机器上运行。 在这种情况下,Kafka 源(或消费者)、窗口算子和 Kafka 目标(或生产者)都运行在五台机器中的每一台上。
机器视角 – TaskManager n
上图中的 keyBy 是一个单独的算子,以便更容易计算资源需求。实际上,keyBy 是一个 API 构造,转换为 Kafka 源和窗口算子之间连接的配置属性。
我现在将从上到下逐一介绍这些算子,以了解它们的网络资源需求。
Kafka 源
要计算单个 Kafka 源接收的数据量,首先计算 Kafka 输入总量。源每秒接收 1,000,000 条消息,每条 2KB。 2KB x 1,000,000/s = 2GB/s
将 2GB/s 除以机器数量(5)得出以下结果: 2GB/s ÷ 5 台机器 = 400MB/s
集群中运行的 5 个 Kafka 源中的每一个都以平均 400 MB/s 的吞吐量接收数据。
Shuffle / keyBy
接下来,您需要确保具有相同键(在本例中为 userId)的所有事件最终到达同一台机器。您正在读取的 Kafka 主题中的数据可能根据不同的分区方案进行分区。 洗牌过程将所有具有相同键的数据发送到一台机器,因此您将来自 Kafka 的 400MB/s 数据流拆分为按 userId 分区的数据流: 400MB/s ÷ 5 台机器 = 80MB/s
平均而言,您必须向每台机器发送 80 MB/s 的数据。此分析是从单台机器的角度进行的,这意味着部分数据已经在目标机器上,因此减去 80MB/s 以说明这一点: 400MB/s – 80MB = 320MB/s

