购物网站分为几个模块,室内设计素材,wordpress主题安装后,应用商店下载安装到桌面1. 背景 Apache Flink 和 Apache Storm 是当前业界广泛使用的两个分布式实时计算框架。其中 Apache Storm#xff08;以下简称“Storm”#xff09;在美团点评实时计算业务中已有较为成熟的运用#xff08;可参考 Storm 的可靠性保证测试#xff09;#xff0c;有管理平台… 1. 背景 Apache Flink 和 Apache Storm 是当前业界广泛使用的两个分布式实时计算框架。其中 Apache Storm以下简称“Storm”在美团点评实时计算业务中已有较为成熟的运用可参考 Storm 的可靠性保证测试有管理平台、常用 API 和相应的文档大量实时作业基于 Storm 构建。而 Apache Flink以下简称“Flink”在近期倍受关注具有高吞吐、低延迟、高可靠和精确计算等特性对事件窗口有很好的支持目前在美团点评实时计算业务中也已有一定应用。 为深入熟悉了解 Flink 框架验证其稳定性和可靠性评估其实时处理性能识别该体系中的缺点找到其性能瓶颈并进行优化给用户提供最适合的实时计算引擎我们以实践经验丰富的 Storm 框架作为对照进行了一系列实验测试 Flink 框架的性能计算 Flink 作为确保“至少一次”和“恰好一次”语义的实时计算框架时对资源的消耗为实时计算平台资源规划、框架选择、性能调优等决策及 Flink 平台的建设提出建议并提供数据支持为后续的 SLA 建设提供一定参考。 Flink 与 Storm 两个框架对比 StormFlink状态管理无状态需用户自行进行状态管理有状态窗口支持对事件窗口支持较弱缓存整个窗口的所有数据窗口结束时一起计算窗口支持较为完善自带一些窗口聚合方法并且会自动管理窗口状态。消息投递At Most OnceAt Least OnceAt Most OnceAt Least OnceExactly Once容错方式[ACK机制](http://storm.apache.org/releases/1.1.0/Guaranteeing-message-processing.html) 对每个消息进行全链路跟踪失败或超时进行重发。[检查点机制](https://ci.apache.org/projects/flink/flink-docs-master/internals/stream_checkpointing.html#checkpointing) 通过分布式一致性快照机制对数据流和算子状态进行保存。在发生错误时使系统能够进行回滚。应用现状在美团点评实时计算业务中已有较为成熟的运用有管理平台、常用 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 集群参数 参数项参数值CPUQEMU Virtual CPU version 1.1.2 2.6GHzCore8Memory16GBDisk500GOSCentOS release 6.5 (Final)3.2 框架参数 参数项Storm 配置Flink 配置VersionStorm 1.1.0-mt002Flink 1.3.0Master Memory2600M2600MSlave Memory1600M * 1612800M * 2Parallelism2 supervisor16 worker2 Task Manager16 Task slots4. 测试方法 4.1 测试流程 数据生产 Data Generator 按特定速率生成数据带上自增的 id 和 eventTime 时间戳写入 Kafka 的一个 TopicTopic Data。 数据处理 Storm Task 和 Flink Task 每个测试用例不同从 Kafka Topic Data 相同的 Offset 开始消费并将结果及相应 inTime、outTime 时间戳分别写入两个 TopicTopic 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 开启 ACKACKer 数量为 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 会对每条消息进行 ACKFlink 是基于一批消息做的检查点不同的实现原理导致两者在 At Least Once 语义的花费差异较大从而影响了性能。而 Flink 实现 Exactly Once 语义仅增加了对齐操作因此在算子并发量不大、没有出现慢节点的情况下对 Flink 性能的影响不大。Storm At Most Once 语义下的性能仍然低于 Flink。6.4 Flink 状态存储后端选择 Flink 提供了内存、文件系统、RocksDB 三种 StateBackends结合 5.11、5.12 的测试结果三者的对比如下StateBackend过程状态存储检查点存储吞吐推荐使用场景MemoryTM MemoryJM Memory高3-5 倍 Storm调试、无状态或对数据是否丢失重复无要求FileSystemTM MemoryFS/HDFS高3-5 倍 Storm普通状态、窗口、KV 结构建议作为默认 BackendRocksDBRocksDB on TMFS/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.