Storm VS Flink ——性能对比
1.背景
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 及文档等仍需进一步完善。 |
2.测试目标
评估不同场景、不同数据压力下 flink 和 storm 两个实时计算框架目前的性能表现,获取其详 细性能数据并找到处理性能的极限;了解不同配置对 flink 性能影响的程度,分析各种配置的 适用场景,从而得出调优建议。
2.1 测试场景
“输入-输出”简单处理场景
通过对“输入-输出”这样简单处理逻辑场景的测试,尽可能减少其它因素的干扰,反映两个框 架本身的性能。
同时测算框架处理能力的极限,处理更加复杂的逻辑的性能不会比纯粹“输入-输出”更高。
用户作业耗时较长的场景
如果用户的处理逻辑较为复杂,或是访问了数据库等外部组件,其执行时间会增大,作业的性 能会受到影响。因此,我们测试了用户作业耗时较长的场景下两个框架的调度性能。
窗口统计场景
实时计算中常有对时间窗口或计数窗口进行统计的需求,例如一天中每五分钟的访问量,每 100 个订单中有多少个使用了优惠等。flink 在窗口支持上的功能比 storm 更加强大,api 更 加完善,但是我们同时也想了解在窗口统计这个常用场景下两个框架的性能。
精确计算场景(即消息投递语义为“恰好一次”)
storm 仅能保证“至多一次” (at most once) 和“至少一次” (at least once) 的消息投递语义, 即可能存在重复发送的情况。有很多业务场景对数据的精确性要求较高,希望消息投递不重不 漏。flink 支持“恰好一次” (exactly once) 的语义,但是在限定的资源条件下,更加严格的精 确度要求可能带来更高的代价,从而影响性能。因此,我们测试了在不同消息投递语义下两个 框架的性能,希望为精确计算场景的资源规划提供数据参考。
2.2 性能指标
- 吞吐量(throughput)
- 单位时间内由计算框架成功地传送数据的数量,本次测试吞吐量的单位为:条/秒。
- 反映了系统的负载能力,在相应的资源条件下,单位时间内系统能处理多少数据。 •
- 吞吐量常用于资源规划,同时也用于协助分析系统性能瓶颈,从而进行相应的资源调整以 保证系统能达到用户所要求的处理能力。假设商家每小时能做二十份午餐(吞吐量 20 份/ 小时),一个外卖小哥每小时只能送两份(吞吐量 2 份/小时),这个系统的瓶颈就在小哥配 送这个环节,可以给该商家安排十个外卖小哥配送。
- 延迟(latency)
- 数据从进入系统到流出系统所用的时间,本次测试延迟的单位为:毫秒。
- 反映了系统处理的实时性。
- 金融交易分析等大量实时计算业务对延迟有较高要求,延迟越低,数据实时性越强。
- 假设商家做一份午餐需要 5 分钟,小哥配送需要 25 分钟,这个流程中用户感受到了 30 分钟的延迟。如果更换配送方案后延迟变成了 60 分钟,等送到了饭菜都凉了,这个新的方案就是无法接受的。
3.测试环境
为 storm 和 flink 分别搭建由 1 台主节点和 2 台从节点构成的 standalone 集群进行本次测试。其中为了观察 flink 在实际生产环境中的性能,对于部分测内容也进行了 on yarn 环境的测试。
3.1 集群参数
参数项 | 参数值 |
---|---|
cpu | qemu virtual cpu version 1.1.2 2.6ghz |
core | 8 |
memory | 16gb |
disk | 500g |
os | centos release 6.5 (final) |
3.2 框架参数
参数项 | 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 |
4.测试方法
4.1 测试流程
数据生产
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 线 选取中位数,绘制图像并分析。
4.2 默认参数
- storm 和 flink 默认均为at least once语义。
storm 开启 ack,acker 数量为 1。
flink 的 checkpoint 时间间隔为 30 秒,默认 statebackend 为 memory。
保证 kafka 不是性能瓶颈,尽可能排除 kafka 对测试结果的影响。
测试延迟时数据生产速率小于数据处理能力,假设数据被写入 kafka 后立刻被读取,即 eventtime 等于数据进入系统的时间。
-
测试吞吐量时从 kafka topic 的最旧开始读取,假设该 topic 中的测试数据量充足。
4.3 测试用例
identity
identity 用例主要模拟“输入-输出”简单处理场景,反映两个框架本身的性能。
输入数据为“msgid, eventtime”,其中 eventtime 视为数据生成时间。单条输入数据约 20 b。
进入作业处理流程时记录 intime,作业处理完成后(准备输出时)记录 outtime。
作业从 kafka topic data 中读取数据后,在字符串末尾追加时间戳,然后直接输出到 kafka。
输出数据为“msgid, eventtime, intime, outtime”。单条输出数据约 50 b。
sleep
- sleep 用例主要模拟用户作业耗时较长的场景,反映复杂用户逻辑对框架差异的削弱,比较 两个框架的调度性能。
- 输入数据和输出数据均与 identity 相同。
- 读入数据后,等待一定时长(1 ms)后在字符串末尾追加时间戳后输出
windowed word count
- windowed word count 用例主要模拟窗口统计场景,反映两个框架在进行窗口统计时性能 的差异。
- 此外,还用其进行了精确计算场景的测试,反映 flink 恰好一次投递的性能。
- 输入为 json 格式,包含 msgid、eventtime 和一个由若干单词组成的句子,单词之间由空 格分隔。单条输入数据约 150 b。
- 读入数据后解析 json,然后将句子分割为相应单词,带 eventtime 和 intime 时间戳发给 countwindow 进行单词计数,同时记录一个窗口中最大最小的 eventtime 和 intime,最后 带 outtime 时间戳输出到 kafka 相应的 topic。
- spout/source 及 outputbolt/output/sink 并发度恒为 1,增大并发度时仅增大 jsonparser、 countwindow 的并发度。
- 由于 storm 对 window 的支持较弱,countwindow 使用一个 hashmap 手动实现,flink 用了原生的 countwindow 和相应的 reduce 函数。
5.测试结果
5.1 identity 单线程吞吐量
- 上图中蓝色柱形为单线程 storm 作业的吞吐,橙色柱形为单线程 flink 作业的吞吐。
- identity 逻辑下,storm 单线程吞吐为8.7万条/秒,flink 单线程吞吐可达35万条/秒。
- 当 kafka data 的 partition 数为 1 时,flink 的吞吐约为 storm 的 3.2 倍;当其 partition 数为 8 时,flink 的吞吐约为 storm 的 4.6 倍。
- 由此可以看出,flink 吞吐约为 storm 的 3-5 倍。
5.2 identity 单线程作业延迟
- 采用 outtime - eventtime 作为延迟,图中蓝色折线为 storm,橙色折线为 flink。虚线为 99 线,实线为中位数。
- 从图中可以看出随着数据量逐渐增大,identity 的延迟逐渐增大。其中 99 线的增大速度比中位数快,storm 的 增大速度比 flink 快。
- 其中 qps 在 80000 以上的测试数据超过了 storm 单线程的吞吐能力,无法对 storm 进 行测试,只有 flink 的曲线。
- 对比折线最右端的数据可以看出,storm qps 接近吞吐时延迟中位数约 100 毫秒,99 线约 700 毫秒,flink 中位数约 50 毫秒,99 线约 300 毫秒。flink 在满吞吐时的延迟约为 storm 的一半。
5.3 sleep 吞吐量
- 从图中可以看出,sleep 1 毫秒时,storm 和 flink 单线程的吞吐均在 900 条/秒左右,且随着并发增大基本呈线性增大。
- 对比蓝色和橙色的柱形可以发现,此时两个框架的吞吐能力基本一致。
5.4 sleep 单线程作业延迟(中位数)
- 依然采用 outtime - eventtime 作为延迟,从图中可以看出,sleep 1 毫秒时,flink 的延迟仍低于 storm。
5.5 windowed word count 单线程吞吐量
- 单线程执行大小为 10 的计数窗口,吞吐量统计如图。
- 从图中可以看出,storm 吞吐约为 1.2 万条/秒,flink standalone 约为 4.3 万条/秒。flink 吞吐依然为 storm 的 3 倍以上。
5.6 windowed word count flink at least once 与 exactly once 吞吐量对比
由于同一算子的多个并行任务处理速度可能不同,在上游算子中不同快照里的内容,经过中间并行算子的处理,到达下游算子时可能被计入同一个快照中。这样一来,这部分数据会 被重复处理。因此,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%
5.7 windowed word count storm at least once 与 at most once 吞吐量对比
- storm 将 acker 数量设置为零后,每条消息在发送时就自动 ack,不再等待 bolt 的 ack, 也不再重发消息,为 at most once 语义。
- 上图中蓝色柱形为 at least once 的吞吐量,浅蓝色柱形为 at most once 的吞吐量。对比两者可以看出,在当前并发条件下,at most once 语义下的吞吐较 at least once 而言提高了 16.8%
5.8 windowed word count 单线程作业延迟
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 在延迟上的优势开始体现出来。
5.9 windowed word count flink at least once 与 exactly once 延迟对比
- 图中黄色为 99 线,橙色为中位数,虚线为 at least once,实线为 exactly once。图中相应 颜色的虚实曲线都基本重合,可以看出 flink exactly once 的延迟中位数曲线与 at least once 基本贴合,在延迟上性能没有太大差异。
5.10 windowed word count storm at least once 与 at most once 延迟对比
- 图中蓝色为 99 线,浅蓝色为中位数,虚线为 at least once,实线为 at most once。qps 在 4000 及以前的时候,虚线实线基本重合;qps 在 6000 时两者已有差异,虚线略高;qps 接近 8000 时,已超过 at least once 语义下 storm 的吞吐,因此只有实线上的点。 • 可以看出,qps 较低时 storm at most once 与 at least once 的延迟观察不到差异,随着 qps 增大差异开始增大,at most once 的延迟较低。
5.11 windowed word count flink 不同 statebackends 吞吐量对比
- flink 支持 standalone 和 on yarn 的集群部署模式,同时支持 memory、filesystem、rocksdb 三种状态存储后端(statebackends)。由于线上作业需要,测试了这三种 statebackends 在 两种集群部署模式上的性能差异。其中,standalone 时的存储路径为 jobmanager 上的一 个文件目录,on yarn 时存储路径为 hdfs 上一个文件目录。
- 对比三组柱形可以发现,使用 filesystem 和 memory 的吞吐差异不大,使用 rocksdb 的 吞吐仅其余两者的十分之一左右。
- 对比两种颜色可以发现,standalone 和 on yarn 的总体差异不大,使用 filesystem 和 memory 时 on yarn 模式下吞吐稍高,使用 rocksdb 时 standalone 模式下的吞吐稍高。
5.12 windowed word count flink 不同 statebackends 延迟对比
使用 filesystem 和 memory 作为 backends 时,延迟基本一致且较低。
使用 rocksdb 作为 backends 时,延迟稍高,且由于吞吐较低,在达到吞吐瓶颈前的延迟陡增。其中 on yarn 模式下吞吐更低,接近吞吐时的延迟更高。
6.结论及建议
6.1 框架本身性能
由 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。
6.2 复杂用户逻辑对框架差异的削弱
对比 5.1 和 5.3、5.2 和 5.4 的测试结果可以发现,单个 bolt sleep 时长达到 1 毫秒时, flink 的延迟仍低于 storm,但吞吐优势已基本无法体现。
因此,用户逻辑越复杂,本身耗时越长,针对该逻辑的测试体现出来的框架的差异越小。
6.3 不同消息投递语义的差异
- 由 5.6、5.7、5.9、5.10 的测试结果可以看出,flink exactly once 的吞吐较 at least once 而 言下降 6.3%,延迟差异不大;storm at most once 语义下的吞吐较 at least once 提升 16.8%,延迟稍有下降。
- 由于 storm 会对每条消息进行 ack,flink 是基于一批消息做的检查点,不同的实现原理导 致两者在 at least once 语义的花费差异较大,从而影响了性能。而 flink 实现 exactly once 语义仅增加了对齐操作,因此在算子并发量不大、没有出现慢节点的情况下对 flink 性能的 影响不大。storm at most once 语义下的性能仍然低于 flink。
6.4 flink 状态存储后端选择
• 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 结构
6.5 推荐使用 flink 的场景
综合上述测试结果,以下实时计算场景建议考虑使用 flink 框架进行计算:
要求消息投递语义为exactly once的场景;
数据量较大,要求高吞吐低延迟的场景;
需要进行状态管理或窗口统计的场景。
7.展望
-
本次测试中尚有一些内容没有进行更加深入的测试,有待后续测试补充。例如:
exactly once 在并发量增大的时候是否吞吐会明显下降?
用户耗时到 1ms 时框架的差异已经不再明显(thread.sleep() 的精度只能到毫秒),用 户耗时在什么范围内 flink 的优势依然能体现出来?
- 本次测试仅观察了吞吐量和延迟两项指标,对于系统的可靠性、可扩展性等重要的性能指 标没有在统计数据层面进行关注,有待后续补充。
- flink 使用 rocksdbstatebackend 时的吞吐较低,有待进一步探索和优化。
-
关于 flink 的更高级 api,如 table api & sql 及 cep 等,需要进一步了解和完善。
8.参考内容
分布式流处理框架——功能对比和性能评估
intel-hadoop/hibench: hibench is a big data benchmark suite
yahoo的流计算引擎基准测试
extending the yahoo! streaming benchmark
本文选自《不仅仅是流计算 apache flink实践》
更多flink博文:
更多flink原理知识:
更多实时计算,flink,kafka等相关技术博文,欢迎关注实时流式计算:
上一篇: 中医治疗支气管哮喘方法之针灸法
下一篇: 揭九长生不老古方,探求延年益寿秘诀
推荐阅读
-
Storm VS Flink ——性能对比
-
6核战8核谁强!锐龙5 5600X VS. i7-11700K游戏性能对比评测
-
Surface Book VS Surfac Pro 4从价格到性能详细对比
-
酷睿i7-11800H VS.锐龙7 5800H游戏性能对比:秒杀还是反杀?
-
平台相差千元!锐龙7 5800X VS. i5-12600K游戏性能对比:网游仍是AMD绝对优势
-
Storm VS Flink ——性能对比
-
Apache 流框架 Flink,Spark Streaming,Storm对比分析(一)
-
Apache 流框架 Flink,Spark Streaming,Storm对比分析(二)
-
InnoDB memcached插件vs原生memcached对比性能测试
-
laravel5,php5.4 vs phpng(php7)性能对比