理清 Spark 2.2 的概念-RDD、Dataset、MLlib
根据实验室的要求,现在在啃《Spark 机器学习》。这本书和市面上大多数 Spark 书籍一样,全都基于 Spark 1.x。在 Spark 版本已经升到 2.2 的今天,敲这本书上的代码可以说是遍地是坑了,很多东西都已经变更,而且很难找到正确的解决方案,弄的我很是烦躁。
没办法,问题要一点一点解决。我决定先从理清《Spark 机器学习》提到的某些 Spark 2.2 提供的概念、模块和配合工具下手,主要关心一下几点:
- RDD 是什么?在升级到 Spark2.2+ 后有什么改动?
- Dataset 是什么?DataFrame 又是什么?
- MLlib 是什么?在升级到 Spark2.2+ 后有没有变动?如何使用?
- IPython 是什么?如何配合 Spark2.2+ 使用?
Spark
Apache Spark 是一个快速的, 多用途的集群计算系统。 它提供了 Java, Scala, Python 和 R 的高级 API,以及一个支持通用的执行图计算的优化过的引擎. 它还支持一组丰富的高级工具, 包括使用 SQL 处理结构化数据处理的 Spark SQL, 用于机器学习的 MLlib, 用于图形处理的 GraphX, 以及 Spark Streaming。
RDD
概念
RDD(Resilien Distributed Dataset,弹性分布式数据集)是 Spark 的核心概念之一。一个 RDD 代表一系列的“记录”(严格来说是某种类型的对象)。这些记录被分配或分区到一个集群的多个节点上(在本地模式下,可以类似地理解为单个进程里的多个线程上)。
Spark 中的 RDD 具备容错性,即当某个节点或任务失败时(非用户代码错误引起,如硬件故障、网络连接失败等),RDD 会在余下的节点上自动重建,以便任务最终能够完成。
功能
RDD 可以从一个驱动程序中已存在的 Scala 集合创建,也可以基于 Hadoop 的输入源(任何其他 Hadoop 支持的文件系统)创建,以及通过转换(transforming)来创建。
RDD 支持两种类型的操作:转换(transformation)和执行(action)。一般来说,转换操作是对一个数据集里的所有记录执行某种函数,从而使记录发生改变;而执行通常是运行某些计算或聚合操作,并将结果返回给驱动程序。
值得注意的是,Spark 中的转换操作是懒加载的(lazy),即在 RDD 上调用一个转换操作不会立即触发相应的计算,而是会将转换操作链接起来,并在执行操作被调用时才被高效计算。
调用一个 RDD 的cache
(或persist
)函数将会告诉 Spark 将这个 RDD 缓存在集群的内存中,以加快下一次访问数据集的速度。
更多 RDD 功能及实际编程方法可见 Spark 编程指南 - Spark 2.2.0 中文文档 - ApacheCN里的相关部分。
升级变动
在 Spark 2.0 之前,Spark 的主要编程接口是 RDD。而在 Spark 2.0 之后,RDD 被 Dataset(数据集)替换。
Dataset 很像 RDD,也是强类型的,并能够使用强大的 lambda 函数。但 Dataset 在引擎盖(hood)有更好的优化,因此性能要更优于 RDD。RDD 接口仍然受支持,但是建议切换使用 Dataset。
Dataset 和 DataFrame
Dataset
Dataset 是一个分布式的数据集合。一个 Dataset 可以从 JVM 对象来构造并使用转换功能。Dataset API 在 Scala 和 Java 是可用的,遗憾的是,Python 暂不支持 Dataset API。但是由于 Python 的动态特性, 许多 Dataset API 的优点已经可用了。
DataFrame
一个 DataFrame 是一个 Dataset 组成的指定列。它的概念与一个关系型数据库中的表或者在 R/Python 中的数据帧(data frame)是相等的,但优化得更好。
DataFrames 可以从结构化的文本文件、Hive中的表、外部数据库,或者已经存在的 RDD 构造而来。DataFrame API 可以在 Scala、Java、Python 和 R 中实现。在 Scala 和 Java 中,一个 DataFrame 所代表的是一个多行的 Dataset。
更多相关信息可见 Spark SQL and DataFrames - Spark 2.2.0 中文文档 - ApacheCN。
MLlib
概念
MLlib 是 Spark 的机器学习库。其目标是使实用的机器学习具有可扩展性并且变得容易。在较高的水平上,它提供了以下工具:
- ML Algorithms(ML 算法):常用的学习算法,如分类,回归,聚类和协同过滤;
- Featurization(特征):特征提取,变换,降维和选择;
- Pipelines(管道):用于构建,评估和调整 ML Pipelines 的工具;
- Persistence(持久性):保存和加载算法,模型和 Pipelines;
- Utilities(实用):线性代数,统计学,数据处理等。
升级变动
MLlib 包括基于 RDD 的 API 和基于 DataFrame 的 API。从 Spark 2.0 开始,基于 RDD 的 API 处于维护模式,这意味着这些 API 仍然被支持且会修复 bug,但不会再添加新功能。在基于 DataFrame 的 API 能够开发到相同功能时,基于 RDD 的 API 将被弃用,并预计在 Spark 3.0 中删除。
更多相关信息可见 MLlib: 主要指南 - Spark 2.2.0 中文文档 - ApacheCN。
IPython
书中的 3.2 节开始也涉及到 IPython 的使用,并且在实际使用中也有一些坑。因此也需要了解一下。
概念
IPython 是一个 Python 的高级交互式 shell,基于 BSD 开源,比默认的 Python shell 好用得多,支持变量自动补全,自动缩进,支持 bash shell 命令,并且内置了许多很有用的功能和函数。IPython 内置的 pylab 包括用于数值计算的 NumPy 和 SciPy,以及用于交互式绘图和可视化的 matplotlib。
升级变动
书中想在启动 PySpark 终端时使用 IPython 而非标准的 Python shell。启动时也可以向 IPython 传入其他参数,包括让它启动时也启动 pylab 功能。
但是实际操作时,在 Spark 主目录下输入如下命令:
1 | IPYTHON=1 IPYTHON_OPTS="--pylab" ./bin/pyspark |
会报错,提示信息如下:
1 | Error in pyspark startup: |
解决方法:
把输入命令变成:
1 | PYSPARK_DRIVER_PYTHON=ipython PYSPARK_DRIVER_PYTHON_OPTS="--pylab" ./bin/pyspark |
如果要使用 IPython 提供的 Notebook 应用,
输入:
1 | PYSPARK_DRIVER_PYTHON=ipython PYSPARK_DRIVER_PYTHON_OPTS='notebook' ./bin/pyspark |
参考资料:Starting Ipython with Spark 2 - Stack Overflow
参考资料
- 《Spark 机器学习》
- 概述 - Spark 2.2.0 中文文档 - ApacheCN