欢迎光临散文网 会员登陆 & 注册

Apache Flink与RisingWave:流处理性能报告公开预览版

2023-07-20 00:13 作者:RisingWave中文开源社区  | 我要投稿

Apache Flink是一个在大数据时代广受欢迎的分布式流处理框架,RisingWave是一个云时代诞生的流处理数据库。

无论时代如何更迭,性能总是一个广受关注的话题。作为一个使用Rust开发、完全面向云环境设计的流处理系统,RisingWave宣称已经取得了相比于Flink十倍的性能提升。

为了得到极致性能,RisingWave已经进行了长达半年的性能测试。在上周,RisingWave团队向50余位社区伙伴分享了私有预览版性能报告。这些社区伙伴中超过一半对Flink拥有3年以上使用经验,并且有不少也是Flink项目的代码贡献者与PMC。我们从这些伙伴中学习到了新的Flink调优经验,同时也收获了不少肯定与鼓励。

在今天(2023年7月4日),我们将公开发布性能报告预览版,供社区伙伴了解RisingWave与Flink项目的性能对比。

注:由于系统版本不断迭代,本性能报告仅代表2023年7月4日之前测得的数据。我们会定期更新报告,让大家更加全面的理解Flink与RisingWave的性能。

开始之前

尽管Apache Flink与RisingWave都是开源流处理系统,使用场景有大量重合,但两者的设计理念有较大差别,直接将两者进行对比其实有失公允。在开始比较之前,我们先概括两个项目的异同,供大家参考。

Flink(flink.apache.org/)作为大数据时代便诞生发展的项目,其设计理念是成为通用流批计算平台。尽管因其高效的流处理而著名,Flink目前正在向大一统系统进化:其不断向批处理、机器学习(Flink ML)、数据湖(Paimon,或称Flink Table Store)、有状态函数(StateFun)等方向发展。与此同时,Flink主要提供类似MapReduce方式的Java API,并在Java API的基础上提供了更高层的Python与SQL接口。

RisingWave(risingwave.dev/)作为流处理数据库,其设计理念是大幅提升云上流计算性能效益。RisingWave与PostgreSQL协议兼容,用户可通过psql、JDBC等连接PostgreSQL的方式来连接RisingWave。RisingWave不提供类似MapReduce的Java API,但提供Python UDF以提升SQL语言的表达性能。

为了求同存异,我们主要对比Flink SQL与RisingWave。

基准测试与环境

我们使用Flink 1.16版本与RisingWave 0.19版本进行对比。

在流处理领域,最常用的基准测试是Nexmark。Flink官方所使用的Nexmark源代码在此:github.com/nexmark/nexm。RisingWave团队实现了基于Kafka为消息源的Nexmark:github.com/risingwavela。由于Nexmark基准测试设计的年代较早,并没有覆盖一些常用的SQL算子,因此我们又额外添加了5条查询语句,参考:github.com/risingwavela

为模拟真实场景,我们使用Kafka不断产生数据,并在下游分别接上Flink与RisingWave进行对比。我们专注于吞吐量,而非延迟。对于Flink与RisingWave,我们均要求保证exactly once语义。

由于具体测试环境,包括Flink的调优,相对复杂,我们并不在此详细列出。感兴趣的朋友可以微信添加risingwave_assistant进入RisingWave中文社区进行交流。

硬件配置

测试中使用到的机型均为AWS EC2 c5.2xLarge (8vCPUs 16GB memory)。

Risingwave一共有四个组件:1. Frontend Node; 2. Meta Node; 3. Compute Node; 4. Compactor Node. Compute Node和Compactor Node共享同一台机器。Frontend Node和Meta Node对性能无影响,他们共享另一台机器。

Flink则有两个组件:1. Job Manager; 2. Task Manager. 基于对应关系,Task Manager独占一台机器(RocksDB中的compaction threads对应了Compactor Node),而Job Manager则独占另一台机器。

性能测试结果

我们直接放出测试结果,如下图。

RisingWave与Flink的性能对比。

注意,在本图中我们对比了两个版本的Flink:Flink与Flink (better storage)。这原因是我们使用了EBS存储RocksDB状态。默认的EBS gp3性能参数为3000 IOPS与125 MB/s。由于在流处理中,内部状态管理很可能是性能的瓶颈,我们在使用默认EBS gp3的基础上,又将性能参数提升到12000 IOPS与500 MB/s,以此来提升Flink性能。

可以看到,在列出的27条query中,RisingWave在22条query中获得了性能优势。其中,在12条query中都跑出了相比于Flink至少高出50%的性能(即图中大于150%),10条query超过Flink性能两倍(即图中大于200%)。其中,q102获得了大于520倍的性能提升,q104获得了660倍的性能提升。

详细解释

为什么缺少了部分查询结果?

如果大家仔细观察,可以发现,我们并没有放出q6、q11、q13、q14这四条查询语句的结果。原因如下:

  • q6:该查询使用了窗口函数,当前版本的RisingWave暂时不支持该查询,但很快就会支持(本月底);

  • q11:该查询使用了session window,而我们认为该功能并非高优先级,因此目前没有实现;

  • q13:需要生成side_input,忽略;

  • q14:该查询需要UDF支持。尽管RisingWave支持UDF,但这要求部署单独的UDF服务,而我们主要是测试RisingWave与Flink的性能,因此忽略。

为什么无状态计算的性能看起来差不多?

在q0-q3以及q21、q22中,RisingWave相比于Flink的性能提升并不多。这点是反直觉的:RisingWave作为一个由Rust开发的项目,理论上应该轻易达到由Java开发的Flink的数倍性能。但为什么在测试中,并没有观察到这样的性能提升?这主要是因为在这些查询中,Flink/RisingWave与Kafka之间进行的信息传输所引入的网络IO成为了主要瓶颈。也就是说,大量时间被消耗在了网络传输上,而非CPU计算上。实际上,我们的确可以构造出复杂无状态计算(如对nested json进行解析等)来体现出Rust项目的性能优势,但Nexmark并不涵盖此类操作,为公平起见,我们忽略了该类测试。

如何解释q5与q16这两条RisingWave明显慢于Flink的查询?

在Flink的测试中,我们保留了Flink官方所使用的Nexmark源代码对于source的定义。与Risingwave的唯一区别在于:Flink在nexmark数据源上定义了watermark,即水位线。水位线的存在,截至目前,为Flink带来了额外的优化机会。比如一个窗口聚合函数可以在水位线到来时,判定某一个时间窗口可以关闭、并输出一次且仅有一次最终结果,而不是在某一行的更新之后实时输出最新的中间结果。 我们将前者的语义称为: Emit On Window Close (EOWC)。我们注意到,Flink不支持非EOWC语义的窗口聚合函数,于是我们也无法通过去除watermark的定义来强制Flink使用非EOWC语义。在Risingwave用户的生产环境使用中,他们向我们反馈对两种语义都有需求。

Risingwave马上会支持EOWC,但在上述的测试中还尚未支持。Flink的q5采用了这样的语义,而Risingwave则仍旧输出大量的实时中间结果。这个区别导致了Risingwave的下游join算子会被大量触发,导致性能低于Flink。我们将在下一次的测试中,为大家呈现支持EOWC后的结果。

对于q16,在优化执行计划时,Risingwave目前尚未提供如nightlies.apache.org/fl中所描述的Split Distinct Aggregation的优化。我们将在支持之后,在下一版的性能报告中,提供相同执行计划的性能数据。

RisingWave在哪类查询上显著优于Flink?

对内部状态复杂占用空间大的查询,RisingWave几乎肯定能够实现性能翻倍,甚至百倍的提升。一般来说,一个查询越复杂,所需维护的内部状态也就更复杂,状态占用空间也更大。例如在测试中,q4, q7, q9, q18, q20这些查询的内部状态都接近或者超过20GB,而q102与q105内部状态接近10GB。此时对于内部状态的存取往往成为计算过程的瓶颈,需要流计算引擎对状态进行缓存、索引等优化加速。从测试结果来看,RisingWave相比于Flink很显然能够更好的支持复杂的流处理任务。

RisingWave为什么能够达到如此高的性能?

RisingWave的性能与其设计实现密不可分。总结下来,我认为RisingWave的性能优势得益于三个关键点:

  1. RisingWave是由Rust从头开发,且几乎不依赖于任何第三方JVM组件。相比于由Java开发的Flink来说,从语言上就有巨大优势。当然,该优势主要存在于计算层,因为Flink所使用的RocksDB存储使用的是C++开发;

  2. 作为大数据项目,Flink拥有类似于MapReduce样式的Java API层,而Flink SQL实质上是对Flink Java API进行的封装。计算机基础理论告诉我们,封装越多,性能越差。相比之下,RisingWave并无中间表达层,因此可以直接针对SQL进行高度定制化优化,从而实现性能大幅提升;

  3. Flink直接使用RocksDB来存储计算中间状态,RocksDB对计算并无感知。相反,RisingWave内部自己实现了存储,存储能够感知计算,并且使用远端存储(例如S3、HDFS等)来大幅降低存储成本,从而实现计算性价比提升。

事实上,除了这三点之外,还有很多因素可能导致RisingWave相比于Flink的性能优势。例如,Flink目前的发展方向是成为大一统平台,其批处理、机器学习、数据湖等功能的引入会轻易提升系统复杂性,从而带来不必要的性能开销。总的来说,关于性能这一块,我们可以单独写新文章介绍,感兴趣的朋友也可以微信添加risingwave_assistant进入RisingWave中文社区进行交流。

没有被测量的部分

复杂无状态计算

正如上面提到的,当处理复杂无状态计算时,理论来说由Rust开发的系统性能应该远高于基于JVM语言编写的系统。考虑到如今不少应用都需要在流处理系统内部进行json解析、字符串处理等复杂操作,我们的确会考虑在今后添加测试该类查询。

多流join

多流join是流处理中的一个非常典型的场景。当用户有多个数据源时(例如多个MySQL实例或者多个Kafka topic),便会考虑使用流处理系统进行join来进行分析。在处理多流join的过程城中,往往都会需要面临内部状态过大的问题。根据Nexmark基准测试的结果,我们已经初步验证了RisingWave在内部状态较大情况下的出色性能,而多流join很显然是RisingWave所擅长的。事实上,我们已经开始了对多流join的实验,根据初步实验结果,RisingWave可以轻松处理十个以上数据流的join,而相比之下,Flink往往会直接因为状态管理问题而崩溃。我们会逐步将多流join的实验结果公布给大家。

UDF、水位线等高级功能

流处理系统的精湛之处远远不至于处理聚合、join、窗口等算子。事实上,用户经常需要UDF或者水位线等进阶功能来扩展表达能力,以及保证系统正确性。然而,限于Nexmark基准测试的局限性,我们并没有对这些功能进行测试。我们会考虑在今后的测试中涵盖这些功能。

如何对Flink进行性能调优?

Flink性能调优不仅是个技术活,更是个经验活。RisingWave团队在Flink性能调优方面积累了将近一年的经验。总结下来,我们可以通过三个方面对Flink进行性能优化:

  • 部署调优。Flink支持Kubernetes部署。然而,由于对于JVM生态的重度依赖,通过Kubernetes部署Flink并不能直接得到最佳性能。我们往往需要考虑Flink的具体部署方式(比如如何部署Zookeeper节点等等)。

  • SQL调优。Flink使用Calcite进行SQL解析与规划,但由于对数据缺少感知,Flink并不能很好的进行SQL优化。因此,在一些查询中,我们需要手动改写SQL实现更高性能。

  • RocksDB调优。由于Flink使用RocksDB进行内部状态管理,而RocksDB作为存储层并不感知计算,因此用户往往需要手工调节RocksDB参数来实现最佳性能。值得注意的是,RocksDB本身就拥有数百个可调参数,希望调好RocksDB还得对RocksDB的内部结构进行非常深入的研究。

如何对RisingWave进行性能调差?

最有可能降低RisingWave性能的方式在于调小计算节点的内存,并通过大量不规则访问来使RisingWave出现大量缓存未命中。其原理是:RisingWave使用远端存储来维护内部状态,并使用计算节点缓存最常访问的远端存储上的状态。当计算节点的容量较小,并访问不规则的情况下,就可能欺骗到缓存策略(RisingWave使用的是基于LRU的算法),从而让RisingWave频繁访问远端存储。远端存储访问往往代价较大,频繁访问注定会造成整体性能下降。

总结

在本文,我们描述了基于Nexmark基准测试进行的Flink和RisingWave性能对比。诚然,单一的基准测试并不能够覆盖流处理系统的方方面面,但是我们仍然可以大致了解到Flink与RisingWave在常用场景下的性能区别以及原因。除流处理能力以外,Flink有着诸多特性值得用户探索(包括批处理、机器学习、StateFun等等),而RisingWave则会更加专注于优化流处理方面的性能效率。

性能并不是评价系统优劣的唯一标准,但的确我们一直都在为实现极致性能而努力。

关于 RisingWave

RisingWave是一款分布式SQL流处理数据库,旨在帮助用户降低实时应用的的开发成本。作为专为云上分布式流处理而设计的系统,RisingWave为用户提供了与PostgreSQL类似的使用体验,并且具备比Flink高出10倍的性能以及更低的成本。




Apache Flink与RisingWave:流处理性能报告公开预览版的评论 (共 条)

分享到微博请遵守国家法律