RDD的引入
由于分布式计算通常需要以下功能:
- 分区控制;
- shuffle控制
- 数据存储\序列化\发送
- 数据计算api
这些功能已经不能通过简单的python内置集合完成,除非你再自己写一套框架,需要一个统一的数据抽象来实现以上功能,因此有了RDD,它就是在集群中可以实现高度容错的一个计算对象。
RDD定义
RDD是resilient distributed dataset 弹性分布式数据集合,是spark中最基本的数据抽象,代表一个不可变、可分区、里面的数据可并行计算的集合。
RDD的五大特性
- RDD是有分区的,一个RDD如果有多个分区,在逻辑层面,我们可能会认为它是一个整体,物理存储上实际在3个不同的分区中(内存/磁盘空间)
# 定义一个三分区的rdd数据集合,这里的sc是sparkcontext
rdd = sc.parallelize([1, 2, 3, 4, 5, 6], 3)
# 将RDD的分区排布展现出来
rdd.glom().collect()
- 计算方法都会作用到每一个分区上
# 会对每一个分区上的数据都执行*10
rdd = sc.parallesize([1, 2, 3, 4, 5, 6], 3).map(lambda x : x * 10.glom().collect())
- RDD之间是有相互依赖关系的,通常都会由一个rdd衍生出其他rdd,并依次迭代下去
sc = SparkContext(conf = conf)
rdd1 = sc.textFile("../text")
rdd2 = rdd1.flatMap(lambda x : x.split(","))
rdd3 = rdd2.map(lambda x : (x, 1))
- kv型RDD可以有分区器,所谓kv型RDD,就是RDD内部存储的数据类型为二元元组,如:
("hadoop", 1)
("python", 2)
("spark", 3)
("hadoop", 5)
("spark", 7)
这类RDD默认是hash分区规则,key相同的会被分到同一个区,如上面的hadoop和spark分别有两个数据,但我们可以通过人为指定分区器,让hadoop和python一个分区(用rdd.partitionBy()方法),这个特性是只对k-v型rdd生效,单值的rdd没必要用
- RDD分区数据读取会尽量靠近分区所在地(移动数据不如移动计算),尽量规划到存储数据所在的服务器上,这样能减少网络读取,使用本地读取效率更高