本人刚开始入门学习Spark,打算先将Spark文档看一遍,顺便做点笔记,就进行一些翻译和记录。由于本人只会python,所以翻译都是以python部分代码进行。以下并非完全100%官网翻译,更多是个人理解+笔记+部分个人认为重要的内容的翻译,新手作品,请各位大神多多指正。
官网原文链接:http://spark.apache.org/docs/latest/rdd-programming-guide.html
Overview(综述)
从高层面来看,每一个spark应用包含了一个运行用户main函数的驱动程序以及在集群中的各种并行操作。
RDD,resilient distributed dataset,弹性分布式数据集,spark的主要抽象,能够在集群中被分区进行并行运算的元素集合。可以通过hadoop文件系统(或者hadoop支持的文件系统)或者是scala集合转换而来。用户能够让RDD保留在内存中,以便让其在并行操作中多次重复使用。最后RDD还支持故障恢复。
第二个抽象,shared variables,共享变量,其能够在不同任务和程序间共享。类型一:广播变量,broadcast variables,能够在集群所有节点内存中缓存。类型二:累加器,accumulators,用于累加和计数。
Linking with Spark(连接到spark)
可以通过pip安装pyspark或直接在shell中运行Pyspark(需要配置$SPARKHOME),也可以通过spark-submit直接提交py应用。
如果需要在Python中直接引用,首先需要通过pip安装pyspark(python3.x则用pip3安装),同时配置好PYSPARK_PYTHON路径。例如我的MacOs的python3路径配置为
export PYSPARK_PYTHON=/usr/local/bin/python3
上述配置好以后,就可以导入SparkContext, SparkConf了
from pyspark import SparkContext, SparkConf
Initializing Spark(初始化)
首先需要创建一个SparkContext对象,告知spark如何访问集群。在创建SparkContext之前,首先需要创建SparkConf对象
conf = SparkConf().setAppName(appName).setMaster(master)
sc = SparkContext(conf=conf)
其中appName为在clusterUI显示的应用名字,例如为’myapp’,master可以为spark,Mesos,YARN集群的URL,本地测试最简单的可以为’local’。
Using the Shell(使用shell)
如果想在PySpark交互式 shell中进行应用开发,就需要先配置好SPARK_HOME。
PySpark已经默认创建好sc,不需要重新创建。
可以通过下面命令启动pyspark
./bin/pyspark --master local[4]
Resilient Distributed Datasets (RDDs)
有两种方式获取RDD:并行化处理已有的collection,或者引用外部数据源创建,例如共享文件系统,HDFS, HBase,或者任何能够提供hadoop输入格式的数据源。
Parallelized Collections(支持并行的数据集)
通过在collection调用SparkContext’s parallelize方法,将collection的元素拷贝到分布式数据集中
data = [1, 2, 3, 4, 5]
distData = sc.parallelize(data)
distDate就是一个RDD,可以进行RDD的转换操作和处理动作
默认情况下,spark对于一个partition会运行一个任务,每个CPU承担2-4个分区任务。一般情况下,spark可以自动设置partition数量。
External Datasets(外部数据集)
hadoop支持的外部数据源,spark都支持,例如本地文件,HDFS, Cassandra, HBase, Amazon S3等。也支持text文件,序列文件等。
textfile可以通过SparkContext’s textFile方法创建RDD。方法接受一个URL,可以是本地文件路径,也可以是hdfs://,s3a://等
>>> distFile = sc.textFile("data.txt")
读取文件注意事项:
- 如果采用本地文件路径,需要确保worker通过相同的文件路径能够访问该文件,你需要将文件都拷贝到各个worker相同路径下。或者采用NFS的方式确保能够共同访问。
- spark基于文件的输入方法,能够运用在目录,压缩文件,以及使用通配符。
- textfile方法也支持设置第二个参数,控制partition的数量。默认情况下,spark为一个block(hadoop hdfs默认的128M)配置一个partition,也可以配置更多的partititon数量。但partition数量不能少于block数量。
另外,spark api还支持其他几种数据格式:
- SparkContext.wholeTextFiles ,能够读取包含多个小文件的文件夹,返回(文件名,内容)的键值对。对于textfile来说,则返回文件中的每行,对应一对记录
- RDD.saveAsPickleFile and SparkContext.pickleFile,将包含着python对象的RDD存储起来,通过批处理程序处理pickle序列化
- 序列文件以及hadoop输入输出格式(实验功能,后续可能会在spark sql实现)
Writable Support
pyspark序列化文件支持将RDD的java的K-V对,转换为可读写的java类型,并用Pyrolite来对java对象进行pickle(pickle为Python的序列化叫法)。逆过程为,unpickle python对象为java类型,在转换为writable。但arrays对象需要进行自行转换。
Saving and Loading SequenceFiles
序列化文件能够被保存和读取,key和value 类都可以指定,但对于标准writable来说就没有必要
>>> rdd = sc.parallelize(range(1, 4)).map(lambda x: (x, "a" * x))
>>> rdd.saveAsSequenceFile("path/to/file")
>>> sorted(sc.sequenceFile("path/to/file").collect())
[(1, u'a'), (2, u'aa'), (3, u'aaa')]
Saving and Loading Other Hadoop Input/Output Formats
pyspark支持读取hadoop 输入格式或者写入hadoop输出格式,hadoop配置可以传递至python字典。
$ ./bin/pyspark --jars /path/to/elasticsearch-hadoop.jar
>>> conf = {"es.resource" : "index/type"} # assume Elasticsearch is running on localhost defaults
>>> rdd = sc.newAPIHadoopRDD("org.elasticsearch.hadoop.mr.EsInputFormat",
"org.apache.hadoop.io.NullWritable",
"org.elasticsearch.hadoop.mr.LinkedMapWritable",
conf=conf)
>>> rdd.first() # the result is a MapWritable that is converted to a Python dict
(u'Elasticsearch ID',
{u'field1': True,
u'field2': u'Some Text',
u'field3': 12345})
对于某些二进制序列化数据(例如Cassandra / HBase),就必须先通过java/scale转换为pyrolite的picker可以处理的对象。
个人原创,欢迎转载