Apache Flink 和 Apache Storm 是当前业界广泛使用的两个分布式实时计算框架。其中 Apache Storm(以下简称“Storm”)在美团点评实时计算业务中已有较为成熟的运用(可参考 Storm 的 可靠性保证测试),有管理平台、常用 API 和相应的文档,大量实时作业基于 Storm 构建。而 Apache Flink(以下简称“Flink”)在近期倍受关注,具有高吞吐、低延迟、高可靠和精确计算等 特性,对事件窗口有很好的支持,目前在美团点评实时计算业务中也已有一定应用。
为深入熟悉了解 Flink 框架,验证其稳定性和可靠性,评估其实时处理性能,识别该体系中的 缺点,找到其性能瓶颈并进行优化,给用户提供最适合的实时计算引擎,我们以实践经验丰富 的 Storm 框架作为对照,进行了一系列实验测试 Flink 框架的性能,计算 Flink 作为确保“至 少一次”和“恰好一次”语义的实时计算框架时对资源的消耗,为实时计算平台资源规划、框 架选择、性能调优等决策及 Flink 平台的建设提出建议并提供数据支持,为后续的 SLA 建设提供一定参考。
Flink 与 Storm 两个框架对比:
流计算框架Flink与Storm 的性能对比
Storm | Flink | |
---|---|---|
状态管理 | 无状态,需用户自行进行状态管理 | 有状态 |
窗口支持 | 对事件窗口支持较弱,缓存整个窗口的所有 数据,窗口结束时一起计算 | 窗口支持较为完善,自带一些窗口聚合方法,并 且会自动管理窗口状态。 |
消息投递 | At Most Once At Least Once | At Most Once At Least Once Exactly Once |
容错方式 | ACK机制:对每个消息进行全链路跟踪,失败 或超时进行重发。 | 检查点机制:通过分布式一致性快照机制,对数 据流和算子状态进行保存。在发生错误时,使系 统能够进行回滚。 |
应用现状 | 在美团点评实时计算业务中已有较为成熟的 运用,有管理平台、常用 API 和相应的文档, 大量实时作业基于 Storm 构建。 | 在美团点评实时计算业务中已有一定应用,但 是管理平台、API 及文档等仍需进一步完善。 |
评估不同场景、不同数据压力下 Flink 和 Storm 两个实时计算框架目前的性能表现,获取其详 细性能数据并找到处理性能的极限;了解不同配置对 Flink 性能影响的程度,分析各种配置的 适用场景,从而得出调优建议。
通过对“输入-输出”这样简单处理逻辑场景的测试,尽可能减少其它因素的干扰,反映两个框 架本身的性能。
同时测算框架处理能力的极限,处理更加复杂的逻辑的性能不会比纯粹“输入-输出”更高。
如果用户的处理逻辑较为复杂,或是访问了数据库等外部组件,其执行时间会增大,作业的性 能会受到影响。因此,我们测试了用户作业耗时较长的场景下两个框架的调度性能。
实时计算中常有对时间窗口或计数窗口进行统计的需求,例如一天中每五分钟的访问量,每 100 个订单中有多少个使用了优惠等。Flink 在窗口支持上的功能比 Storm 更加强大,API 更 加完善,但是我们同时也想了解在窗口统计这个常用场景下两个框架的性能。
Storm 仅能保证“至多一次” (At Most Once) 和“至少一次” (At Least Once) 的消息投递语义, 即可能存在重复发送的情况。有很多业务场景对数据的精确性要求较高,希望消息投递不重不 漏。Flink 支持“恰好一次” (Exactly Once) 的语义,但是在限定的资源条件下,更加严格的精 确度要求可能带来更高的代价,从而影响性能。因此,我们测试了在不同消息投递语义下两个 框架的性能,希望为精确计算场景的资源规划提供数据参考。
为 Storm 和 Flink 分别搭建由 1 台主节点和 2 台从节点构成的 Standalone 集群进行本次测试。其中为了观察 Flink 在实际生产环境中的性能,对于部分测内容也进行了 on Yarn 环境的测试。
参数项 | 参数值 |
---|---|
CPU | QEMU Virtual CPU version 1.1.2 2.6GHz |
Core | 8 |
Memory | 16GB |
Disk | 500G |
OS | CentOS release 6.5 (Final) |
参数项 | Storm 配置 | Flink 配置 |
---|---|---|
Version | Storm 1.1.0-mt002 | Flink 1.3.0 |
Master Memory | 2600M | 2600M |
Slave Memory | 1600M * 16 | 12800M * 2 |
Parallelism | 2 supervisor 16 worker |
2 Task Manager 16 Task slots |
Data Generator 按特定速率生成数据,带上自增的 id 和 eventTime 时间戳写入 Kafka 的一个 Topic(Topic Data)。
Storm Task 和 Flink Task (每个测试用例不同)从 Kafka Topic Data 相同的 Offset 开始消费, 并将结果及相应 inTime、outTime 时间戳分别写入两个 Topic(Topic Storm 和 Topic Flink)中。
Metrics Collector 按 outTime 的时间窗口从这两个 Topic 中统计测试指标,每五分钟将相应的 指标写入 MySQL 表中。
Metrics Collector 按 outTime 取五分钟的滚动时间窗口,计算五分钟的平均吞吐(输出数据的 条数)、五分钟内的延迟(outTime - eventTime 或 outTime - inTime)的中位数及 99 线等指标, 写入 MySQL 相应的数据表中。最后对 MySQL 表中的吞吐计算均值,延迟中位数及延迟 99 线 选取中位数,绘制图像并分析。
Storm 开启 ACK,ACKer 数量为 1。
Flink 的 Checkpoint 时间间隔为 30 秒,默认 StateBackend 为 Memory。
保证 Kafka 不是性能瓶颈,尽可能排除 Kafka 对测试结果的影响。
测试延迟时数据生产速率小于数据处理能力,假设数据被写入 Kafka 后立刻被读取,即 eventTime 等于数据进入系统的时间。
测试吞吐量时从 Kafka Topic 的最旧开始读取,假设该 Topic 中的测试数据量充足。
Identity 用例主要模拟“输入-输出”简单处理场景,反映两个框架本身的性能。
输入数据为“msgId, eventTime”,其中 eventTime 视为数据生成时间。单条输入数据约 20 B。
进入作业处理流程时记录 inTime,作业处理完成后(准备输出时)记录 outTime。
作业从 Kafka Topic Data 中读取数据后,在字符串末尾追加时间戳,然后直接输出到 Kafka。
输出数据为“msgId, eventTime, inTime, outTime”。单条输出数据约 50 B。
由于同一算子的多个并行任务处理速度可能不同,在上游算子中不同快照里的内容,经过中间并行算子的处理,到达下游算子时可能被计入同一个快照中。这样一来,这部分数据会 被重复处理。因此,Flink 在 Exactly Once 语义下需要进行对齐,即当前最早的快照中所有 数据处理完之前,属于下一个快照的数据不进行处理,而是在缓存区等待。当前测试用例 中,在 JSON Parser 和 CountWindow、CountWindow 和 Output 之间均需要进行对齐,有 一定消耗。为体现出对齐场景,Source/Output/Sink 并发度的并发度仍为 1,提高了 JSONParser/CountWindow 的并发度。具体流程细节参见前文 Windowed Word Count 流程图。
上图中橙色柱形为 At Least Once 的吞吐量,黄色柱形为 Exactly Once 的吞吐量。对比两者可以看出,在当前并发条件下,Exactly Once 的吞吐较 At Least Once 而言下降了 6.3%
Identity 和 Sleep 观测的都是 outTime - eventTime,因为作业处理时间较短或 Thread.sleep() 精度不高,outTime - inTime 为零或没有比较意义;Windowed Word Count 中可以有效测得 outTime - inTime 的数值,将其与 outTime - eventTime 画在同一张图上,其中 outTime - eventTime 为虚线,outTime - InTime 为实线。 ? 观察橙色的两条折线可以发现,Flink 用两种方式统计的延迟都维持在较低水平;观察两条 蓝色的曲线可以发现,Storm 的 outTime - inTime 较低,outTime - eventTime 一直较高,即 inTime 和 eventTime 之间的差值一直较大,可能与 Storm 和 Flink 的数据读入方式有关。
蓝色折线表明 Storm 的延迟随数据量的增大而增大,而橙色折线表明 Flink 的延迟随着数 据量的增大而减小(此处未测至 Flink 吞吐量,接近吞吐时 Flink 延迟依然会上升)。 ? 即使仅关注 outTime - inTime(即图中实线部分),依然可以发现,当 QPS 逐渐增大的时候, Flink 在延迟上的优势开始体现出来。
使用 FileSystem 和 Memory 作为 Backends 时,延迟基本一致且较低。
使用 RocksDB 作为 Backends 时,延迟稍高,且由于吞吐较低,在达到吞吐瓶颈前的延迟陡增。其中 on Yarn 模式下吞吐更低,接近吞吐时的延迟更高。
由 5.1、5.5 的测试结果可以看出,Storm 单线程吞吐约为 8.7 万条/秒,Flink 单线程吞吐 可达 35 万条/秒。Flink 吞吐约为 Storm 的 3-5 倍。
由 5.2、5.8 的测试结果可以看出,Storm QPS 接近吞吐时延迟(含 Kafka 读写时间)中位 数约 100 毫秒,99 线约 700 毫秒,Flink 中位数约 50 毫秒,99 线约 300 毫秒。Flink 在 满吞吐时的延迟约为 Storm 的一半,且随着 QPS 逐渐增大,Flink 在延迟上的优势开始体现出来。
综上可得,Flink 框架本身性能优于 Storm。
对比 5.1 和 5.3、5.2 和 5.4 的测试结果可以发现,单个 Bolt Sleep 时长达到 1 毫秒时, Flink 的延迟仍低于 Storm,但吞吐优势已基本无法体现。
因此,用户逻辑越复杂,本身耗时越长,针对该逻辑的测试体现出来的框架的差异越小。
? Flink 提供了内存、文件系统、RocksDB 三种 StateBackends,结合 5.11、5.12 的测试结果, 三者的对比如下:
StateBackend 过程状态存储 检查点存储 吞吐 推荐使用场景 Memory TM Memory JM Memory 高(3-5 倍 Storm) 调试、无状态或对数据是否 丢失重复无要求 FileSystem TM Memory FS/HDFS 高(3-5 倍 Storm) 普通状态、窗口、KV 结构 (建议作为默认 Backend)
RocksDB RocksDB on TM FS/HDFS 低(0.3-0.5 倍 Storm) 超大状态、超长窗口、大型 KV 结构
综合上述测试结果,以下实时计算场景建议考虑使用 Flink 框架进行计算:
要求消息投递语义为Exactly Once的场景;
数据量较大,要求高吞吐低延迟的场景;
需要进行状态管理或窗口统计的场景。
本次测试中尚有一些内容没有进行更加深入的测试,有待后续测试补充。例如:
Exactly Once 在并发量增大的时候是否吞吐会明显下降?
用户耗时到 1ms 时框架的差异已经不再明显(Thread.sleep() 的精度只能到毫秒),用 户耗时在什么范围内 Flink 的优势依然能体现出来?
关于 Flink 的更高级 API,如 Table API & SQL 及 CEP 等,需要进一步了解和完善。
分布式流处理框架——功能对比和性能评估
intel-hadoop/HiBench: HiBench is a big data benchmark suite
Yahoo的流计算引擎基准测试
Extending the Yahoo! Streaming Benchmark
本文选自《不仅仅是流计算 Apache Flink实践》
更多Flink博文:
更多Flink原理知识:
更多实时计算,Flink,Kafka等相关技术博文,欢迎关注实时流式计算:
原文:https://www.cnblogs.com/tree1123/p/11510282.html