Categories
程式開發

Spark 3.0重磅发布!开发近两年,流、Python、SQL重大更新全面解读


今天,开发历时近两年的Apache Spark 3.0.0正式发布了!3.0.0版本一共包含了3400多个补丁,是开源社区有史以来贡献力度最大的一次,新版本加入了Python和SQL的高级功能,提升了探索和生产应用方面的易用性。今年,Spark也迎来了开源10周年,这10年里Spark一直在不断发展,以便满足更多的应用场景和更广泛的受众需求。

Spark 3.0主要特性概览

  • 相比Spark 2.4,性能提升了2倍,主要体现在自适应查询执行、动态分区修剪等方面;

  • 兼容ANSI SQL;

  • Pandas API的重大改进,包括Python类型提示和增加额外的Pandas UDF;

  • 改进了Python错误处理,简化了PySpark异常;

  • 结构化流的新UI;

  • 调用R语言UDF速度提升最高达到了40倍;

  • 解决了3400个Jira问题,这些问题在 Spark 各个组件的分布情况如下:

image

Spark开源10周年

Spark诞生于加州大学伯克利分校的AMPLab实验室,该实验室致力于数据密集型计算的研究。AMPLab研究人员与大型互联网公司合作,研究如何解决数据和AI问题,然后发现那些拥有海量数据的公司也面临同样的问题。于是,他们开发了一个新引擎来处理这些新兴的工作负载,同时又能够让开发人员轻松地使用大数据处理API。

很快,社区开始参与贡献,对Spark进行了扩展,在流、Python和SQL方面带来了新功能,而这些模式现在已经是Spark的主要用例。持续的投入把Spark带到了今天的状态,成为数据处理、数据科学、机器学习和数据分析工作负载事实上的引擎。Apache Spark 3.0通过显著改善对SQL和Python(当今Spark使用的两种最广泛的语言)的支持和对性能、可操作性等方面的优化继续推进这种趋势。

改进的Spark SQL引擎

Spark SQL是支持大多数Spark应用程序的引擎。例如,在Databricks,超过90%的Spark API调用使用了DataFrame、Dataset和SQL API。这说明即使是Python和Scala开发人员,他们的大部分工作都通过Spark SQL引擎进行。Spark 3.0有46%的补丁与SQL有关,提升了性能和ANSI SQL兼容性。如下图所示,Spark 3.0的总体性能大约是Spark 2.4的2倍。接下来将介绍Spark SQL引擎的新功能。

image

新的自适应查询执行(AQE)框架通过在运行时生成更好的执行计划来提升性能,即使初始的计划不理想(由于缺少或使用了不正确的数据统计信息和错误地估算了成本)。由于Spark的数据存储和计算是分离的,因此数据的到达是无法预测的。基于这些原因,对于Spark来说,运行时自适应比传统系统来得更为重要。新版本引入了三个主要的自适应优化:

  • 动态聚结shuffle分区可简化甚至是避免调整shuffle分区的数量。用户可以在开始时设置相对较大的shuffle分区数量,AQE会在运行时将相邻的小分区合并为较大的分区。

  • 动态切换连接策略可以在一定程度上避免由于缺少统计信息或错误估计大小而导致执行次优计划的情况。这种自适应优化可以在运行时自动将排序合并连接(sort-merge join)转换成广播哈希连接(broadcast-hash join),从而进一步提高性能。

  • 动态优化倾斜(skew)连接是另一个关键的性能增强。倾斜连接可能会导致负载的极度失衡并严重降低性能。在AQE从shuffle文件统计信息中检测到倾斜连接之后,它可以将倾斜分区拆分为较小的分区,并将它们与另一边的相应分区合并。这个优化可以让倾斜处理并行化,获得更好的整体性能。

在一个3TB的TPC-DS基准测试中,与没有AQE的Spark相比,有AQE的Spark将两个查询的性能提升了1.5倍以上,另外37个查询的性能提升了1.1倍以上。

image

当优化器无法在编译时识别可跳过的分区,可以使用“动态分区修剪”,这在星型模型中很常见(星型模型由一个或多个事实表组成,这些事实表引用了任意数量的维度表)。在执行这种连接操作时,我们可以通过识别维度表过滤之后的分区来修剪从事实表读取的分区。在一个TPC-DS基准测试中,102个查询中有60个查询获得2到18倍的速度提升。

image

ANSI SQL兼容性对于将工作负载从其他SQL引擎迁移到Spark SQL来说至关重要。为了提升兼容性,新版本使用了Proleptic Gregorian日历,用户可以禁止使用ANSI SQL保留关键字作为标识符。此外,新版本针对数字类型的操作中引入了运行时溢出检查,并强制执行编译时类型检查。这些新的验证机制提高了数据质量。

连接提示:尽管Databricks一直在改进编译器,但还是不能保证编译器可以在任何时候做出最佳决策——连接算法的选择基于统计信息和启发式。当编译器无法做出最佳选择时,用户可以使用连接提示来影响优化器,让它选择更好的执行计划。新版本加入了新的提示:SHUFFLE_MERGE、SHUFFLE_HASH和SHUFFLE_REPLICATE_NL。

增强的Python API:PySpark和Koalas

Python现在是Spark中使用最为广泛的编程语言,所以也是Spark 3.0的重点关注领域。Databricks有68%的NoteBook命令是用Python写的。PySpark在PyPI上的月下载量超过500万。

image

很多Python开发人员在数据结构和数据分析方面使用了Pandas API,但仅限于单节点处理。Databricks会继续开发Koalas(一种基于Apache Spark的Pandas API实现),让数据科学家能够在分布式环境中更高效地处理大数据。借助Koalas,数据科学家们就不需要构建很多函数(例如绘图支持),在整个群集中获得更高的性能。

经过一年多的开发,Koalas实现了将近80%的Pandas API。Koalas在PyPI上的月下载量已迅速增长到85万,并以每两周发布一次的节奏快速演进。除了Koalas,很多人仍在使用PySpark API,该API也越来越受欢迎。

image

Spark 3.0对PySpark API做了一些增强:

  • 带有类型提示的新Pandas API:Spark 2.3最初引入了Pandas UDF,并将Pandas API集成到PySpark应用程序中。但是,随着UDF类型的增多,现有接口就变得难以理解。新版本引入了一个新的Pandas UDF接口,利用Python的类型提示来解决Pandas UDF类型泛滥的问题。新接口变得更具Python风格和自我描述性。

  • 新的Pandas UDF类型和Pandas函数API:新版本增加了两种新的Pandas UDF类型,即系列迭代器到系列迭代器和多个系列迭代器到系列迭代器。这对于数据预取和昂贵的初始化操作来说很有用。此外,新版本还添加了两个新的Pandas函数API,即map和co-grouped map。更多详细信息请参见这里

  • 更好的错误处理:PySpark的错误处理对于Python用户来说并不友好。新版本简化了PySpark异常,隐藏了不必要的JVM堆栈跟踪,并更具Python风格。

Hydrogen、流和可扩展性

Spark 3.0完成了Hydrogen项目的关键组件,并引入了新功能来改善流和可扩展性。

  • 加速器感知调度:Hydrogen项目是Spark的一项主要计划,旨在更好地统一基于Spark的深度学习和数据处理。GPU和其他加速器已经被广泛用于加速深度学习工作负载。为了使Spark能够利用目标平台上的硬件加速器,新版本增强了已有的调度程序,让集群管理器可以感知到加速器。用户可以通过配置来指定加速器,然后调用新的RDD API来利用这些加速器。

  • 结构化流的新UI:结构化流最初是在Spark 2.0中引入的。在Databricks,使用量同比增长4倍之后,每天使用结构化流处理的记录超过了5万亿条。新版本添加了专用的新Spark UI,用于查看流作业。新UI提供了两组统计信息:已完成的流查询作业的聚合信息和流查询的详细统计信息。

image

  • 可观察的指标:持续监控数据质量变化是管理数据管道的一种必备功能。新版本引入了监控批处理和流应用程序的功能。可观察的指标是一种可基于查询(DataFrame)定义的聚合函数。在DataFrame执行完成后会发出一个事件,事件包含了自上一个完成点以来处理的数据的度量信息。

  • 新的目录插件API:现有的数据源API缺乏访问和操作外部数据源元数据的能力。新版本增强了数据源V2 API,并引入了新的目录插件API。对于同时实现了目录插件API和数据源V2 API的外部数据源,用户可以通过标识符直接操作外部表的数据和元数据(在相应的外部目录注册了之后)。

Spark 3.0的其他更新

Spark 3.0解决了3400多个Jira问题,这是440多个贡献者共同努力的结果。这些贡献者包括个人贡献者和来自Databricks、谷歌、微软、英特尔、IBM、阿里巴巴、Facebook、英伟达、Netflix、Adobe等公司的员工。除了本文介绍的在SQL、Python和流技术方面的关键改进,Spark 3.0还有很多其他改进功能,详情可以查阅版本发行说明。发行文档中提供了更多信息,包括数据源、生态系统、监控等。

image

原文链接:

https://databricks.com/blog/2020/06/18/introducing-apache-spark-3-0-now-available-in-databricks-runtime-7-0.html