1.初识Spark
1.1 Spark(基础原理知识)
Spark是一个开源的,强大的分布式查询和处理引擎,他提供MapReduce的灵活性和扩展性(不以Mapreduce的数据处理框架),当数据存储在内存中时,他比Apache Hadoop快100倍,访问磁盘时高达10倍
他支持高级API有:
1.Scala
2.Java
3.Ptyhon
4.R
而今天我们就要了解Pyspark的运用
Apache Spark提供了几个已经实现并调优过的算法、统计模型和框架:为机器学习提供的MLlib和ML,为图形处理提供的GrapxX和GraphFrames以及Spark Streaming(DStream和Structured)。Spark允许用户在同一个应用程序中随意的组合使用这些库。
1.2 如何作业和API
任何Spark应用程序都会分离主节点上的单个驱动进程(可以包含多个作业),然后将执行进程(包含多个任务)分配给多个任务节点。
Spark作业与一系列对象依赖关系相连这些依赖关系是以有向无环图(DAG)的方式组织的(图片我就不放了,如果大家对这方面的知识点感兴趣,大家可以网上百度一下)
1.3 弹性分布式数据集(RDD)
简称RDD,是不可变虚拟机(JVM)对象的分布式集合,Spark就是围绕着RDD而构建的。我们使用python时,尤为重要的是注意python是存储在JVM对象中的。因此RDD的计算是在缓存和内存中运行的,和其他传统分布式框架相比,该模式计算速度得到了一个质的飞跃。
此外,RDD还有数据扩展(例如map(…)、reduce(…)、filter(…)),这些粗粒度的数据转换保持平台的高度扩展和活用性
RDD的操作是惰性的,他只有在计算出结果并要返回结果到程序的时候才会进行计算转换。该延迟行会产生更多精细查询:针对性能进行优化的查询
RDD的两个动作:
1.转换
map,filter,groupBy,join等
2.操作
count、collect等,接受RDD后返回非RDD,
即输出一个值或一个结果
1.4 DataFrame(介绍)
DataFrame像RDD一样,是分布在集群节点中的不可变的数据集合,然而与RDD不同的是,在DataFrame中,数据是以命名列的方式组织的
他的存在是为了开发人员对大型数据集的处理更加容易,他们允许开发人员对数据结构进行形式化,允许更高级的抽象。也就是说他提供了一种特定领域的语言API来操作分布式数据,使Spark可以被更广泛的使用。
他的还有一个主要优点:因为Spark引擎一开始就构建了一个逻辑执行计划,而且执行生成的代码是基于成本优化程序确定的物理计划。与java和scala相比,python的rdd是很慢的,而DataFrame的引入则使性能在各种语言中都保持稳定。
1.5 SparkSession(介绍)
在过去你可能会使用SparkConf、SparkContext、SQLContext、和HiveContext来执行配置、Spark环境、SQL环境和Hive环境的各种Spark查询
现在我们可用现在的版本来写(简化处理):
df=spark.read.format('json').load('py/test/sql/a.json')
df=spark.read.json('py/test/sql/a.json')
所以SparkSession是读取数据、处理元数据、配置会话
和管理集群资源的入口。
2. RDD (具体操作)
2.1 创建RDD
一般有两种方法来创建RDD
1.用parallelize集合(元素list或array)
data= sc.parallelize(
[(1,'jobs'),(2,'amy'),(3,'alice')]
)
2.用本地或者外地文件
data_file= sc.\
textFile
(‘/tmp/jobs/a.txt’,2)
tips:
sc.textFile(....,n)方法中的最后一个
参数代表该数据集被划分的分区个数,经验
方法是把每一个集群中的数据集分成2到4个
分区。
2.2 Schema
RDD是没有Schema数据结构的,所以它能创建多种不同类型的数据格式比如
data=sc.parallelize([
{'a',1}
{'as','ff'}
['jobs','amy','aa']
]).collect()
collect()指把该数据集送回驱动程序的操作
可以访问对象中的数据,和在python中做的
一样
2.3 全局作用域和局部作用域
作为一个潜在的pyspark用户,你需要习惯的一件事就是spark的内在并行性。
spark在两种模式下运行:本地和集群的
本地运行时和使用python没有什么不同
但是你不小心将代码部署到集群中的时候,你就需要注意了解Spark是在集群中如何执行任务的。
在集群模式中,提交任务时,任务发送到了给驱动程序节点(或者主节点)该驱动程序节点为任务创建DAG,并且决定哪一个执行者(工作者)节点将要允许的任务,然后,该驱动程序指示工作者执行他们的任务,并且在执行结束时将结果返回给驱动程序,然而在这之前,驱动程序为每一个任务的终止做准备,驱动程序中有一组变量和方法,以便工作者在RDD上执行任务。而这些变量在上下文中是静态的
2.4 准换操作()
2.4.1 map (返回一个新的分布式数据集)
data=[1,2,3,4]
new_data=sc.parallize(data).map(lambda x:x+1).collect()
lambda(python中匿名函数关键字)
2.4.2 filter (返回一个被筛选过的数据集)
承接上文
new_filter=sc.parallelize(data).filter(lambda x:x==4).collect()
2.4.3 flatMap (类似于map,但是返回的数据不一定和原数据相同)
test=sc.parallelize([1,2,3,4])
sorted(rdd.flatMap(lambda x:range(1,x)).collect())
2.4.4 leftOuterJoin()
a=sc.parallelize([('a',1),('b',2)])
b=sc.parallelize([('a',2),('b',3)])
c=a.leftOuterJoin(b)
2.5 行动操作
2.5.1 take(等于collect,但是他能限制返回的行数)
test=a.take(2)
返回前2行,(n)是指返回前n行。
2.5.2 reduce(讲rdd元素两两传入给输入函数,同时产生一个新的值,直到最后只有一个为止)
data.map(lambda row:row[1]).reduce(lambda x,y:x+y)
2.5.3 count (返回RDD中元素的个数)
test.sc.parallelize(data).count()