简单介绍
谈到spark大家都可以想到RDD,它是spark必不可少的一部分,在我看来他是spark数据处理的基础之一给大家简单介绍一下吧。
RDD
RDD又叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合。RDD具有数据流模型的特点:自动容错、位置感知性调度和可伸缩性。RDD允许用户在执行多个查询时显式地将工作集缓存在内存中,后续的查询能够重用工作集,这极大地提升了查询速度。
(1)一组分片(Partition),即数据集的基本组成单位。对于RDD来说,每个分片都会被一个计算任务处理,并决定并行计算的粒度。用户可以在创建RDD时指定RDD的分片个数,如果没有指定,那么就会采用默认值。默认值就是程序所分配到的CPU Core的数目。
(2)一个计算每个分区的函数。Spark中RDD的计算是以分片为单位的,每个RDD都会实现compute函数以达到这个目的。compute函数会对迭代器进行复合,不需要保存每次计算的结果。
(3)RDD之间的依赖关系。RDD的每次转换都会生成一个新的RDD,所以RDD之间就会形成类似于流水线一样的前后依赖关系。在部分分区数据丢失时,Spark可以通过这个依赖关系重新计算丢失的分区数据,而不是对RDD的所有分区进行重新计算。
(4)一个Partitioner,即RDD的分片函数。当前Spark中实现了两种类型的分片函数,一个是基于哈希的HashPartitioner,另外一个是基于范围的RangePartitioner。只有对于于key-value的RDD,才会有Partitioner,非key-value的RDD的Parititioner的值是None。Partitioner函数不但决定了RDD本身的分片数量,也决定了parent RDD Shuffle输出时的分片数量。
(5)一个列表,存储存取每个Partition的优先位置(preferred location)。对于一个HDFS文件来说,这个列表保存的就是每个Partition所在的块的位置。按照“移动数据不如移动计算”的理念,Spark在进行任务调度的时候,会尽可能地将计算任务分配到其所要处理数据块的存储位置。
基本使用
#pyspark.SparkContext()是spark应用的入口,也可以称为驱动
from pyspark import SparkConf, SparkContext
conf = SparkConf().setAppName("sparkApp").setMaster("local")
sc = SparkContext.getOrCreate(conf)
#parallelize(c,numSlices=None)分发本地Python集合以形成RDD。如果输入表示性能范围,则建议使用xrange。
#glom()通过将每个分区内的所有元素合并到一个列表中返回一个RDD。
rdd1 = sc.parallelize([0,2,3,4,6], 5)
rdd2 = sc.parallelize(range(0, 6, 2), 5)
print(rdd1.collect())
print(rdd1.glom().collect())
print(rdd2.collect())
print(rdd2.glom().collect())
# histogram(buckets)
# 对rdd中的元素进行频数统计,统计区间有两种,一种是给出段数,一种是直接给出区间。返回为元组
rdd = sc.parallelize(range(51))
print(rdd.histogram(2))
print(rdd.histogram([0, 5, 25, 50]))
print(rdd.histogram([0, 15, 30, 45, 60]))
rdd = sc.parallelize(["ab", "ac", "b", "bd", "ef"])
print(rdd.histogram(("a", "b", "c")))
# pipe(command, env=None, checkCode=False)
# 通过管道向后面环节输出command处理过的结果,具体功能就体现在command,command为linux命令。
# pipe函数中的'cat'为linux命令,表示打印内容。
sc.parallelize(['1', '2', '', '3']).pipe('cat').collect()
# sorted(sc.parallelize([1, 1, 2, 3]).distinct().collect())
# 返回此RDD的采样子集
# withReplacement:是否重复采样
# fraction:样本预期占RDD的大小,每一个元素被取到的概率一样,是一个【0,1】的数
# seed 随机模式的种子
rdd = sc.parallelize(range(100), 4)
print(rdd.sample(False, 0.1, 81).count())
print(rdd.sample(False, 0.2, 81).count())
以上都是一些简单的数据处理的操作,在使用中发现和pandas有点类似,不过个人认为pandas加numpy还是比较如意的,当然spark主要还是基于java开发的,python在spark上感觉更多还是用在一些机器学习上面。