浅谈 Spark 的多语言支持(修订版)

简介: Spark 设计上的优秀无容置疑,甫一出道便抢了 Hadoop 的 C 位,在开源大数据的黄金十年里一时风头无两,在人工智能时代的当下仍然能够与时俱进,不可谓不牛逼。架构和设计上的卓越,不遑多言,美中不足之处自然也有不少,比如调度模型跟 MapReduce 这种计算范式过于耦合,Spark 最近引入 Barrier 调度模式就是为了支持深度学习这种新的计算类型,所幸在于对框架的改动不会伤经动骨。

作者:郑锴,花名铁杰,阿里巴巴高级技术专家,Apache Hadoop PMC,Apache Kerby 创立者。深耕分布式系统开发和开源大数据多年,先后专注在安全,存储和计算领域。之前在 Intel,目前转战阿里云上,致力于提供更好用更有弹性的 Hadoop/Spark 大数据平台。


Spark 设计上的优秀无容置疑,甫一出道便抢了 Hadoop 的 C 位,在开源大数据的黄金十年里一时风头无两,在人工智能时代的当下仍然能够与时俱进,不可谓不牛逼。架构和设计上的卓越,不遑多言,美中不足之处自然也有不少,比如调度模型跟 MapReduce 这种计算范式过于耦合,Spark 最近引入 Barrier 调度模式就是为了支持深度学习这种新的计算类型,所幸在于对框架的改动不会伤经动骨。有些缺陷则不然,影响全局,调整起来绝非易事。这儿我主要想谈下 Spark 的框架语言实现和多语言支持,谈它的得与失,不过主要还是谈问题谈缺陷。

Spark 核心和框架构建在 Scala 上,对应用开发者也是言必称 Scala,上来就秀代码极简的漂亮肌肉。在用户接口上,从企业级应用的首选 Java,到数据科学家的 Python 和 R,再到商业智能 BI 的 SQL,官方都一一支持,按说已经很全面很完整了,各方神圣也都伺候到了,还有什么抱怨的,言何缺陷?我们来看下目前存在的问题,希望不会变成鸡蛋里挑骨头。首先,对 Python 的支持也就是 PySpark 复杂且效率低下,有点像 hack,十分像早期 Spark 攻城略地的产出。其实对 R 的支持 SparkR 也如出一辙,我们讨论清楚了 PySpark 也就明白了对其他语言的支持其实是类似的。从使用者的角度来看用 PySpark 写程序的体验还是很不错的,跟 Scala 有点类似,简洁而优雅,就跟写个单机程序一样,不需要考虑分布式处理的复杂性。然而在这件漂亮的外衣下,用 PySpark 写的 Spark 程序就是比 Scala 版本慢,还动不动 OOM 掉。为什么?我们来探一下究竟。一般 Spark 程序首先给定输入也就是要处理的数据集,然后表达好针对这个数据集的每行记录要处理的逻辑和转换规则,再将结果打印出来或者保存到文件。背后 Spark 框架进行翻译转换,产出一个个 RDD 和这些 RDD 之间的关系,每个 RDD 表示对应的数据集和在该数据集上要执行的变换处理逻辑。这些 RDD 根据它们之间的依赖关系组成 DAG,对 DAG 翻译转换成 stages 和 tasks,这个过程在 driver 端由框架 Scala 代码完成,包括对 stages 和 tasks 的调度执行;RDD 的处理逻辑对应用户的 Scala 或 Python 代码,因为要分布式并发处理,主要在 executor 上执行。因此,对于 Python 版本的 Spark 程序,在 driver 上和 executor 上都有要执行的 Python 代码,必然需要对应的 Python 解释器来执行;然而 Spark 计算框架是 Scala/Java 代码实现的,driver 和 executor 整体上得跑在 JVM 进程里面。那么如何在 driver 端和 executor 上同时执行代表用户逻辑的 Python 代码和核心引擎的 JVM 代码,并在两者之间进行交互和协调呢?PySpark 的做法是在 driver 端和 executor 上伴随必需的 JVM 进程,再 launch 起来单独的 Python 解释执行进程,然后通过 socket,文件和 pipeline 进行交互和协作。这不能不说是个非常低效的做法,因为 Spark 程序通常而言并非一个普通的应用,要处理非常大的数据集。对于成千上万行记录的处理,都要在 executor 上通过跨进程管道到 Python 进程上来回一趟,末了在 driver 上为了传递计算结果可能还要写个磁盘文件才能转给 Python 进程,为此涉及到大量记录数据在 Python 和 Java 之间要序列化和反序列化,效率可想而知。开启新的 Python 进程直接执行用户的代码省事倒是省事,除了效率问题,考虑到进程管理,内存控制,容器环境和数据安全,这样做的代价还是很大的,然而 Spark 却不得不这样做,主要是因为受限于它在语言支持上面缺乏长远的考虑和整体的设计,这就是我想讲的最重要的问题。

在语言支持上,从一开始 Spark 的关注点就是“糖衣”而非“炮弹”,在用户体验上追求数据处理逻辑表达的简洁有力,因此完胜当时的各种计算框架而后一骑绝尘。记得在 Hadoop 如日中天的时候,笔者所在的 Intel 大数据团队正在玩 Hadoop 不亦乐乎,Spark 的作者 Matei 先生在远程会议上向我们演示当时还十分稚嫩的 Spark,看到那个有名的 MapReduce Helloworld 例子 WordCount 程序只需要两三行 Scala 代码搞定,真是骇人。Spark 能够在短时间内抢了 Hadoop 的风头,除了性能更快,毫无疑问这也是个关键因素。然而这种简洁有力,在多大程度上要归功于 Scala,其实不太好讲。感觉最本质的还是在于函数式语言的支持, RDD 本身的抽象,丰富的算子支持和巧妙的关系推导,这部分可以归为引擎层面,大体上用其他语言,比如更擅长做系统框架的,C++,应该也能实现得出来。至于用户的程序是用 Scala 还是 Python,只要支持 closures,应该都能行,简洁程度上不会差别太大,也完全可以多支持一些语言,每个用户具体用哪一个要看个人的偏好,没有道理让大家都去学一个新的语言。可惜的是,Spark 引擎的实现应该是受到了主要用户接口语言 Scala 的影响,也采用了 Scala,部分采用 Java,但本质上都是 JVM 语言,这样做的好处是一锅煮,省事。考古学家可以列出一大堆使用 Scala 的好处,比如代码行数少,codegen 给力之类的,但是这些都是局部的,从整体上 Spark 作为一个统一的大数据处理平台,其实更需要长远的通盘考虑。这个考虑就是在用户接口上要能够更快更好地支持更多的用户语言,在计算引擎上能够支持硬件层面的极致性能优化,在计算场景上也能支持其他计算引擎的集成。

这个考虑简单来说就是缺乏对框架层面的 C/C++ 支持。当然这个支持很难在第一天就考虑进来,毕竟关注点不在这儿,那个时候估计 Matei 先生也想不到 Spark 会这么成功。然而框架层面缺乏对 C/C++ 的原生支持或者换句话说,框架核心没有采用 C/C++ 这种 native 语言来开发,其弊端和对 Spark 今后长远发展的影响毫无疑问显而易见。C/C++ 作为系统语言,下可以跟硬件直接打交道,上可以直接对接各种开发语言,因此也不难支持各种计算处理库和引擎。Spark 本身定位为一个大数据处理平台,如果核心公共逻辑和操作交给 C/C++ 来实现,那么首先支持 Python 这种用户接口语言,直接利用 FFI 机制调用就是了,简单且无损效率。主流的开发语言基本上都很好地支持 C/C++,Python 不说,像 Java,Go,Rust,Julia,都是。Spark 添加一个新的语言支持,就简化为添加一个新的 binding,还好维护,也不用担心这个功能被阉割,那个支持还不全。对新的硬件做优化也不成问题,比如从计算新贵 GPU 到 RDMA,再到可持久化大内存 AEP,根本不会受限于 JVM 的限制,各大硬件厂商都能自己撸起袖子开搞,Spark 坐享其成就是。现在对这些新硬件的支持为什么上不了,社区不接受?个人认为主要还是缺乏框架层面的支持,搞出来的都像是 hack,进去也是麻烦。看看人家 Tensorflow 就知道了,CPU,TPU,GPU 都能玩得转。核心框架采用 Scala/Java 来实现,还有一个重要的影响是数据集的内存表示,早期 Spark 直接用 Java 对象来表示数据记录,需要持久化或者网络传输要序列化和反序列化,当然在这一点上 Spark 后来很快意识到了问题,通过 offheap 和 Tunsten 项目马上把问题解了,所幸还有招数。如果是 C/C++ 实现的,数据的内存布局必然会采取类似 Arrow 的这种中性表示,方便各种用户接口语言来访问和操作,就像深度学习框架里面常见的 tensor,必须考虑高效传递。最后一点,采用 Scala/Java 来实现的 Spark 框架,虽然整合开源大数据领域和企业级应用里面很常见的各种数据源得心应手,但要整合集成更多的计算框架则就力不从心了。类似于对新硬件的支持,看一下 Yahoo 对 Caffe 和 Tensorflow 的支持就明白了,只能 hack 一下自己玩,不可能融入到 Spark 里面流行起来,要原生支持 deep learning,像 machine learning,可以,但要自己撸。Spark 自己花了很大力气搞 mllib,Intel 搞 BigDL,都是没办法,因为缺乏核心框架的给力支持,不能直接把这些领域里面现成的库实现和计算引擎集成进来。如果核心框架是是 C/C++ 实现的,集成 PyTorch 和 Tensorflow 能有多大的问题?无非是多挂一个动态模块或搞一个扩展插件的事情。

好吧,啰嗦到这儿,问题有解吗?肯定有。Spark 搞定了用户生态,只要保持接口兼容不变,核心框架来个天翻地覆,改弦更张换个语言来实现,未尝不可,就看有没有人愿意这么干。有没有更取巧的办法呢,不用听起来这么吓人?答案也是肯定的,笔者所在的团队就在干这样的事情,不过我们可以下次再行文讨论,有兴趣的同学可以联系我们,也欢迎加入,一起做出来,拥抱这个人工智能时代。对了,我们是阿里巴巴计算平台,开源大数据部门 EMR,致力于在云上打造极致的弹性 Spark 计算体验,做会在云上玩的 Spark,欢迎了解。技术方案和细节,我们可以下次再行文讨论,有兴趣的同学可以联系我,本人邮箱zhengkai.zkATalibaba-inc.com,也欢迎加入钉钉群 Apache Spark 中国技术交流群,群号 23109202;阿里云 E-MapReduce 技术交流群,群号21784001。或者扫码加入:
lADPDgQ9qonEd_3NBc3NBGU_1125_1485
lADPDgQ9qonLjW7NBc3NBGU_1125_1485

相关实践学习
数据湖构建DLF快速入门
本教程通过使⽤数据湖构建DLF产品对于淘宝用户行为样例数据的分析,介绍数据湖构建DLF产品的数据发现和数据探索功能。
快速掌握阿里云 E-MapReduce
E-MapReduce 是构建于阿里云 ECS 弹性虚拟机之上,利用开源大数据生态系统,包括 Hadoop、Spark、HBase,为用户提供集群、作业、数据等管理的一站式大数据处理分析服务。 本课程主要介绍阿里云 E-MapReduce 的使用方法。
相关文章
|
机器学习/深度学习 分布式计算 Java
浅谈 Spark 的多语言支持
Spark架构和设计上的优秀毋庸置疑,从一出道便抢了 Hadoop 的 C 位。在开源大数据的黄金十年一时风头无两,在当下人工智能时代仍然能够与时俱进,通天之处不遑多言,美中不足之处也有不少。小的方面,比如调度模型跟 MapReduce 这种计算范式过于耦合,Spark 最近引入 Barrier 调度模式就是为了支持深度学习这种新的计算类型,所幸在于对框架的改动不会伤筋动骨;有些缺陷则不然,影响全局,调整起来绝非易事。
|
分布式计算 自然语言处理 搜索推荐
协同过滤算法 R/mapreduce/spark mllib多语言实现
用户电影评分数据集下载 http://grouplens.org/datasets/movielens/ 1) Item-Based,非个性化的,每个人看到的都一样2) User-Based,个性化的,每个人看到的不一样对用户的行为分析得到用户的喜好后,可以根据用户的喜好计算相似用户和物品,然后可以基于相似用户或物品进行推荐。这就是协同过滤中的两个分支了,基于用户的和基于物品的协同过滤。
4191 0
|
分布式计算 自然语言处理 Java
Spark入门到精通视频学习资料--第七章:Spark多语言编程(1讲)
Spark目前支持scala、python、JAVA编程。 作为Spark的原生语言,scala是开发Spark应用程序的首选,其优雅简洁的代码,令开发过mapreduce代码的码农感觉象是上了天堂。
1063 0
|
3月前
|
机器学习/深度学习 SQL 分布式计算
Apache Spark 的基本概念和在大数据分析中的应用
介绍 Apache Spark 的基本概念和在大数据分析中的应用
157 0
|
7天前
|
分布式计算 Hadoop 大数据
大数据技术与Python:结合Spark和Hadoop进行分布式计算
【4月更文挑战第12天】本文介绍了大数据技术及其4V特性,阐述了Hadoop和Spark在大数据处理中的作用。Hadoop提供分布式文件系统和MapReduce,Spark则为内存计算提供快速处理能力。通过Python结合Spark和Hadoop,可在分布式环境中进行数据处理和分析。文章详细讲解了如何配置Python环境、安装Spark和Hadoop,以及使用Python编写和提交代码到集群进行计算。掌握这些技能有助于应对大数据挑战。
|
3月前
|
机器学习/深度学习 SQL 分布式计算
介绍 Apache Spark 的基本概念和在大数据分析中的应用。
介绍 Apache Spark 的基本概念和在大数据分析中的应用。
|
2月前
|
分布式计算 大数据 Java
Spark 大数据实战:基于 RDD 的大数据处理分析
Spark 大数据实战:基于 RDD 的大数据处理分析
120 0
|
3月前
|
分布式计算 监控 大数据
Spark RDD分区和数据分布:优化大数据处理
Spark RDD分区和数据分布:优化大数据处理
|
4月前
|
分布式计算 大数据 Linux
Python大数据之PySpark(三)使用Python语言开发Spark程序代码
Python大数据之PySpark(三)使用Python语言开发Spark程序代码
100 0
|
4月前
|
SQL 分布式计算 大数据
Hudi数据湖技术引领大数据新风口(三)解决spark模块依赖冲突
Hudi数据湖技术引领大数据新风口(三)解决spark模块依赖冲突
100 0