1.什么是RDD-弹性分布式数据集?
RDD(弹性分布式数据集)是PySpark的基本构建块,它是容错的,不可变的对象分布式集合。不变的含义一旦创建了RDD,就无法更改。 RDD中的每个记录都分为逻辑分区,可以在群集的不同节点上进行计算。
换句话说,RDD是类似于Python中列表的对象的集合,区别在于RDD是在分散在多个物理服务器(也称为集群中的节点)上的多个进程上计算的,而Python集合仅在一个进程中存在和处理。此外,RDD提供数据的分区和分布的数据抽象,这些数据旨在在多个节点上并行运行计算,而在RDD上进行转换时,我们不必担心默认情况下PySpark提供的并行性。
2.PySpark RDD的优点
与传统的python编程相比,PySpark具有很多优势,因此在机器学习和数据科学领域得到了广泛的应用。
- 内存中处理:PySpark将来自磁盘的数据和进程加载到内存中,并将数据保留在内存中,这是PySpark和Mapreduce(I / O密集型)之间的主要区别。在转换之间,我们还可以将RDD缓存/持久化在内存中以重用先前的计算。
- 不变性:PySpark RDD本质上是不可变的,一旦创建了RDD,就无法修改。当我们在RDD上应用转换时,PySpark将创建一个新的RDD并维护RDD沿袭。
- 容错能力:PySpark在HDFS,S3 e.t.c上的容错数据存储上运行,因此任何RDD操作都会失败,它会自动从其他分区重新加载数据。此外,当PySpark应用程序在群集上运行时,PySpark任务故障会自动恢复一定次数(根据配置),然后无缝完成应用程序。
- 懒惰进化:PySpark不会评估RDD转换(由驱动程序出现/遇到),而是会保留遇到的所有转换(DAG),并在看到第一个RDD动作时评估所有转换。
- 分区:从数据创建RDD时,默认情况下,它将在RDD中对元素进行分区。默认情况下,它分区为可用的内核数。
3.PySpark RDD的缺点
PySpark RDD不太适合对状态存储进行更新的应用程序,例如Web应用程序的存储系统。 对于这些应用程序,使用执行传统更新日志记录和数据检查点的系统(例如数据库)更为有效。 RDD的目标是为批处理分析提供有效的编程模型,并保留这些异步应用程序。
4.创建RDD
1.using sparkContext.parallelize()
PySpark parallelize() 是SparkContext中的一个函数,用于根据列表集合创建RDD。
rdd = sc.parallelize([1,2,3,4,5,6,7,8,9,10])
可以使用parallelize()方法创建一个空的RDD对象。
emptyRDD2 = rdd=sparkContext.parallelize([])
有时我们可能需要按分区向文件写入一个空的RDD,在这种情况下,您应该使用分区创建一个空的RDD。
rdd2 = spark.sparkContext.parallelize([],10)
2. using sparkContext.textFile()
rdd2 = spark.sparkContext.textFile("/path/textFile.txt")
3.using sparkContext.wholeTextFiles()
wholeTextFiles() 函数返回PairRDD,其键为文件路径,值为文件内容。
rdd3 = spark.sparkContext.wholeTextFiles("/path/textFile.txt")
4.using sparkContext.emptyRDD
rdd = spark.sparkContext.emptyRDD()
print("initial partition count:"+str(rdd.getNumPartitions()))
5.重新分区
有时我们可能需要对RDD进行重新分区,PySpark提供了两种重新分区的方法: 首先使用repartition()方法对所有节点的数据进行混洗,也称为完全混洗,其次使用coalesce()方法对最小节点的数据进行混洗,例如,如果您有4个分区中的数据,并且执行conesce(2)仅将数据从2个节点中移动 。
这两个函数都将要分割的分区数rdd如下所示。 请注意,repartition()方法是一项非常昂贵的操作,因为它会重新整理集群中所有节点的数据。
reparRdd = rdd.repartition(4)
print("re-partition count:"+str(reparRdd.get