SparkRDD基础概念
RDD基础概念
一个适用与分布式计算的数据抽象,一个弹性分布式的数据集
RDD数据的概念来自与一篇论文
RDD(弹性分布式数据集,Resilient Distributed Dataset)是 Apache Spark 的基本数据结构。RDD 是一个分布式的、不可变的数据集合,允许用户在集群的多个节点上并行操作数据。这种设计使得 RDD 特别适合于大规模数据处理的并行计算任务。以下是关于 RDD 的一些基础概念和特点:
1. 弹性性质
- 容错性:RDD 的“弹性”主要体现在其容错机制上。如果RDD的任何分区遭受故障,它可以通过原始创建操作的行动记录(称为血统 lineage)自动重建。
- 可恢复:通过利用其血统信息,RDD 可以对失败的节点中的数据进行重新计算,而不是通过数据复制来提供容错能力。
2. 分布式特性
- 分区数据:RDD 数据被分割成多个分区,这些分区可以在集群的不同节点上并行处理。
- 位置透明:用户不需要知道数据具体存储在哪里,Spark 负责数据的分布和处理的调度。
3. 不可变性
- 只读:一旦创建,RDD 的数据就不可更改。所有对数据的操作都会生成一个新的 RDD,原始 RDD 保持不变。
- 操作结果的确定性:同一个 RDD 上执行相同的操作,无论执行多少次,结果都是相同的。
4. 类型安全
- 泛型支持:RDD 是一个泛型类型,支持存储任何类型的对象,包括用户定义的类。
5. 创建和转换
- 并行集合:通过在 SparkContext 上调用
parallelize
方法,可以将现有集合(如数组或列表)转换为 RDD。 - 外部数据集:通过 SparkContext 上的方法,如
textFile
,可以从外部存储(如 HDFS、S3 等)读取数据并创建 RDD。 - 转换操作:例如
map
、filter
、reduceByKey
等,用于生成新的 RDD。
6. 惰性求值
- 转换的惰性执行:在 RDD 上定义的转换操作不会立即执行。只有在触发行动(如
count
、collect
)时,所有之前定义的转换才会被计算。
7. 行动操作
- 触发计算:行动操作(如
collect
、count
、saveAsTextFile
)用于触发实际计算,并在需要时从 RDD 中提取结果或将结果存储到外部系统。
8. 存储特性
- 内存:RDD 默认存储在内存中,这有助于快速访问和处理。将数据保留在内存中,可以显著提高迭代算法和交互式查询的性能。通过 cache() 或 persist() 方法,可以将 RDD 持久化到内存中。这是在进行多次操作时避免重新读取数据的有效方法。
- 外存:磁盘存储:当内存资源有限或处理非常大的数据集时,可以选择将 RDD 持久化到磁盘。
RDD五大特性
1. 分区性
RDD的分区是RDD数据存储的最小单位,一份RDD的数据,本质是分隔成了多个分区
RDD是逻辑上的抽象对象,而[[1, 2, 3], [4, 5, 6], [7, 8, 9]]是物理分区
示例:
>>> rdd = sc.parallelize([1,2,3,4,5,6,7,8,9],3) >>> rdd.glom().collect() [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> >>> rdd = sc.parallelize([1,2,3,4,5,6,7,8,9],6) >>> rdd.glom().collect() [[1], [2, 3], [4], [5, 6], [7], [8, 9]] >>>
2. RDD方法会作用在其所有的分区上
>>> rdd = sc.parallelize([1,2,3,4,5,6,7,8,9],3)
>>> rdd.map(lambda x:x*10).glom().collect()
[[10, 20, 30], [40, 50, 60], [70, 80, 90]]
RDD方法大致原理
3. RDD血缘性
- RDD之间是有依赖关系(RDD有血缘关系)
- 可以叫做RDD的迭代计算关系
from pyspark import SparkConf, SparkContext
if __name__ == '__main__':
conf = SparkConf().setAppName("WordCountHelloWorld")
sc = SparkContext(conf=conf)
# 读取 HDFS 上的文件
rdd1 = sc.textFile('hdfs://mycluster/sparkdata/words.txt')
# 将每一行按空格拆分成单词
rdd2 = rdd1.flatMap(lambda line: line.split())
# 每个单词计数为 1
rdd3 = rdd2.map(lambda word: (word, 1))
# 对相同的单词进行计数
rdd4 = rdd3.reduceByKey(lambda x, y: x + y)
# 输出结果
print(rdd4.collect())
RDD血缘性
4. Key-Value型的RDD可以有分区器
key-Value型指的是RDD的最基本的数据构成为一个二元元组 例如('key','value')
分区规则:
- 默认分区器:Hash分区规则,可以手动设置一个分区器(rdd.partitionBy的方法设置)
特性的可选型:
- 这个特性是可选的,不是所有的RDD都是Key-Value型
5. RDD的分区规划,会尽量靠近所在的服务器
计算向数据靠拢
在初始RDD(读取数据的时候)规划的时候,分区会尽量规划到存储数据所在节点的上。
- 优点:
- 避免网络读取而带来的延迟
Spark是尽量将计算靠拢数据,并不是100%的,原因是因为如果只有3台节点有数据,但是需要4个Executor来进行计算
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 David
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果