Apache Spark并不属于最轻量级的解决方案,所以有一大批托管解决方案是很自然的。AWS EMR、SageMaker、Glue、Databricks等。虽然这些服务抽象出了很多移动的部分,但它们引入了一个相当笨重的工作流程,反馈循环很慢。简而言之,这与本地开发不太一样,所以我想谈谈如何实现这一点。
现在,只要你安装了Java和Python,你就几乎一切就绪了。在这一点上,你可以python3 -m pip install pyspark ,不管是在虚拟环境中还是在全局中(通常首选前者,但这取决于你的设置)。Spark被整齐地打包在Python包中的所有JARs中,所以没有其他东西需要安装。
在Spark中工作时,你会得到一个全局变量spark ,使你能够读入数据,创建数据帧等。这个变量在托管解决方案中通常是凭空变出来的,所以我们必须自己创建它。
让我们创建一个pipeline.py ,内容如下
from pyspark.sql import SparkSession
spark = SparkSession.builder.getOrCreate()
print(spark.sql('select 1').collect())
单独的会话就足够了,但SQL语句只是为了测试一下。运行python3 pipeline.py 应该会启动一个Spark会话,运行简单的查询并退出(你同样可以运行spark-submit ,但这里没有必要)。如果你想进一步研究环境,你可以运行python3 -i pipeline.py ,这是Python的说法:"运行这个文件,把我放到Python解释器中,让我知道这个运行结果的状态"。这对调试非常有帮助。
进一步开展工作
由于我们有Spark会话,我们可以做典型的df = spark.read.csv('our_data') ,但数据本身可能是一个问题。在这一点上,我们与我们的共享基础设施中的许多数据互动,无论是HDFS还是像S3这样的对象存储。
如果我们把我们的Spark实例指向这些来源,我们将面临一些问题。
- 我们需要库来访问这些文件系统,这使得我们的精简操作不那么精简。
- 将会有巨大的延迟,以及网络外传输的高成本(又称出口费)。
- 源数据对于本地实验来说可能太大了,所以任何快速开发都会受到缓慢处理的阻碍。
我们可以通过一个简单的采样来解决所有这些问题--只需复制一些源文件到你的本地磁盘(最好是与你的CPU一样多的文件,以实现I/O并行)。这将导致快速的本地测试,不涉及网络(所以你甚至可以离线开发,如果这是你的事),而且数据刚好够你的笔记本电脑轻松处理。
这里有一个更完整的例子。
from pyspark.sql import SparkSession
import pyspark.sql.functions as f
if __name__ == '__main__':
spark = SparkSession.builder.getOrCreate()
df = spark.read.csv('sales_raw')
df.filter(f.col('price') > 1000).groupby('region').count().show()
df.write.partitionBy('region', 'brand').parquet('sales_processed')
PySpark的最小Docker镜像看起来是这样的。这只是一个普通的例子,请确保将基本镜像和你的依赖项都固定下来。
FROM python:3.8-slim
# the mkdir call is there because of an issue in python's slim base images
# see https://github.com/debuerreotype/docker-debian-artifacts/issues/24
RUN mkdir -p /usr/share/man/man1 && apt-get -y update && apt-get -y --no-install-recommends install default-jre
# you'll likely use requirements.txt or some other dependency management
RUN python3 -m pip install pyspark
在建立了这个镜像之后(docker build -t imgname .),你就可以进行测试了,只是要确保覆盖入口--从基础镜像中继承的是一个Python解释器。因此,通过docker run --rm -it imgname bash 进入shell,然后就可以了。
你现在已经准备好运行一个本地的、可重复的、快速迭代的、涉及分布式处理系统的工作流程。这不是很好吗?
快乐的Sparking!