浅谈 Spark 的多语言支持

作者:郑锴,花名铁杰,阿里巴巴高级技术专家,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,欢迎了解。


原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/519146.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里云POLARDB如何助力轻松筹打造5亿用户信赖的大病筹款平台?

轻松筹首创了“大病救助”模式,帮助了众多病患在第一时间解決了医疗资金等问题,为了从源头解决了医疗资金问题。而在轻松筹这样全球5.5亿用户信赖的大病筹款平台的背后,是日益增长的各种数据。面对这样数据量所造成的巨大挑战,阿里…

彻彻底底给你讲明白啥是SpringMvc异步处理

来源 | 编程新说责编 | Carol出品 | CSDN云计算(ID:CSDNcloud)生活在这个世界上,我们必须承认任何事物都是运动变化着的,没有什么东西是一成不变的。不仅因为这句话是出自马克思主义哲学的唯物辩证法,而且事…

linux环境安装LFTP_02

安装: yum -y install lftp验证: sftp 用户名sftpIP地址 输入密码即可

选择阿里云数据库HBase版十大理由

根据Gartner的预计,全球非关系型数据库(NoSQL)在2020~2022预计保持在30%左右高速增长,远高于数据库整体市场。 阿里云数据库HBase版也是踏着技术发展的节奏,伴随着NoSQL和大数据技术的兴起和发展,从2010年…

酷睿i7cpu适合的linux,CPU性能篇 - Core i7-4770K Linux之旅:有喜有忧_Linux新闻_Linux公社-Linux系统门户网站...

CPU性能篇——Rodinia是学术界经常使用的科学测试工具。OpenMP LavaMD负载中,4770K相比3770K快了12%,8350表现也可以。OpenMP Leukocyte负载里,4770K对比3770K的优势依然有10%,但是8350大亮了,竟…

GitOps:Kubernetes多集群环境下的高效CICD实践

为了解决传统应用升级缓慢、架构臃肿、不能快速迭代、故障不能快速定位、问题无法快速解决等问题,云原生这一概念横空出世。云原生可以改进应用开发的效率,改变企业的组织结构,甚至会在文化层面上直接影响一个公司的决策,可以说&a…

远程办公是一阵“过渡风”还是会“继续燃烧”?

受中国新型冠状病毒肺炎感疫情的影响,2月伊始,「远程办公」成为所有人关心与讨论的热门话题之一。在现实驱动之下,企业如何协同与高效办公成为重点问题中的焦点。在中国企业与「远程办公」正面相遇满月之际,2月29日,CS…

SpringBoot+Shiro+ehcache实现登录失败超次数锁定帐号

文章目录二、Controller层接收登录请求三、自定义的Realm四、密码验证器增加登录次数校验功能五、ShiroConfig的配置类六、EhCache 的配置七、全局异常的配置####### 一、 Shiro的执行流程1、核心介绍1)Application Code用户编写代码2)Subject就是shiro管…

linux putty 字体,putty修改字体配色

先看效果步骤:1. 打开Windows注册表编辑器开始 -> regedit2. 找到putty默认session所在位置HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\Sessions\Default%20Settings3. 右键导出修改# 字体(monaco字体不错,如效果图)"Font""Consol…

90后ACE成长记——从偏居一隅小城里走出的核心技术人

《ACE成长记》栏目说明 名词解释: 阿里云工程师,简称 ACE (Alibaba Cloud Engineer),代表云计算的爱好者,是最“王牌”(ACE)的一群开发者,也是未来的MVP。 ACE 是遍布在…

阿里开发者招聘节 | 面试题01:如何实现一个高效的单向链表逆序输出?

面试,如同玩一场饥饿游戏:既要对环境了然于胸,又要对自身心知肚明。发现一个好工作不容易,但成功应聘又会面临一系列的挑战。 为帮助开发者们提升面试技能、有机会入职阿里,云栖社区特别制作了这个专辑——阿里巴巴资…

从Kubernetes安全地访问AWS服务,告诉你多云场景下如何管理云凭据!

作者| Alexey Ledenev翻译 | 天道酬勤,责编 | Carol出品 | CSDN云计算(ID:CSDNcloud)随着企业与各种云提供商合作,多云场景已经变得十分常见。在谷歌Kubernetes引擎(GKE)上运行的应用程序需要访…

linux未知设备驱动程序,未知Android设备 - linux mint

我仍然是一个新手到linux和android开发,但我终于得到了我的设备的认可。关键(我认为)是将SUBSYSTEM更改为SUBSYSTEMS,将ATTR更改为ATTRS。按照udev(7) page,这种“向上搜索DEVPATH查找匹配的设备......”所以,这就是我最后做一个令…

MSSQL-最佳实践-Always Encrypted

摘要 在SQL Server安全系列专题月报分享中,往期我们已经陆续分享了:如何使用对称密钥实现SQL Server列加密技术、使用非对称密钥实现SQL Server列加密、使用混合密钥实现SQL Server列加密技术、列加密技术带来的查询性能问题以及相应解决方案、行级别安…

java实现对文件加解密操作

源文件: 加密后的文件: 解密后的文件: package com.gblfy.test;import java.io.*;/*** java 实现对文件加解密的方法** author gblfy* date 2020-12-08*/ public class IOSercet {//获取系统类型private static String OS System.getPro…

如何在工作中快速成长?致工程师的10个简单技巧

阿里妹导读:阿里有句非常经典的土话,“今天的最好表现,是明天的最低要求。”如何挖掘潜能、发现更好的自己?今天,阿里巴巴高级无线开发专家江建明将认知升级的方法总结出来,帮助你获得快速成长的秘诀&#…

1 手写第一个Win32窗口程序

1 基础概念 什么是窗口? 答:窗口就是屏幕上的一片区域,接受用户的输入,显示程序的输出。可以包含标题栏、菜单栏、工具栏以及控件等。什么是句柄? 答: 作为一种管理和操作系统资源的机制,提供了…

解析云原生与云计算本质区别,别再傻傻分不清楚了!

来源| comparethecloud翻译 | 天道酬勤,责编 | Carol出品 | CSDN云计算(ID:CSDNcloud)云应用程序是热门话题。很多时候,我们会遇到像云原生应用程序和云计算应用程序这样的术语。首先,很少有人同时使用这两…

Java 使用 zip4j 进行基本的压缩、解压、设置密码操作(version zip4j-2.6.4)

先看工具类 package space.util;import java.io.File; import java.util.List;import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.model.enums.AesKeyStrength; import net.lingala.zip4j.model.enums.EncryptionMe…

linux显示mem进行排序,Linux查看系统负载(CPU和MEM考虑)

查看占用CPU最高的10个进程[tidb:vg_adn_tidbCkhsTest:172.31.30.62 ~/tidb-ansible]$ps aux | grep -v PID | sort -rn -k | headmysql 6.6 60.4 ? Sl Nov22 : /usr/local/mysql/bin/mysqld --basedir/usr/local/mysql/ --datadir/data/data_mysql --plugin-dir/usr/local/my…