1.基础概念
1.在spark中,最重要的概念就是RDD,是一个不可改变的分布式数据集
2.三要素:
a) 分布式数据集:也就是数据集dataset分布在集群中各个block上
b) 可以直接得到上一级RDD指针
c) 上一级的RDD可以重复使用,方便恢复数据
3.与hadoop差异在哪?
hadoop流程:hdfs-->map-->reduce-->hdfs ,这个过程可以理解为单独的过程,如reduce的结果你想在利用,你得从hdfs拉取新数据
spark流程:RDD-->map-->reduce-->RDD 这个过程是可以不断循环,每次计算返回的都是一个RDD对象
4.名词解释
1.action:RDD直接返回一个运算结果,如count
2.transformation:RDD生成另一个RDD,如flatmap,map,distinct
3.Job:用户通过spark-submit提交的一次作业
4.Partition:数据分区,一个RDD可以有多个分区在不同机器上
5.sparkContext:我们自己函数与spark交互的交互层
总结:RDD是Spark中的抽象数据结构类型,任何数据在Spark中都被表示为RDD。从Scala编程的角度看,可以将其简单看成是一个数组。与我们理解数组的区别是,RDD中的数据分区存储,不同分区的数据就分布在不同的机器上,可被并行处理。因此,Spark应用程序所做的无非是把需要处理的数据转换为RDD,然后对RDD进行一系列的变换和操作从而得到结果
2.python操作spark实例
先用Python简单测试下spark
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import os
from pyspark import *
s = "[result]------------->> " # 由于运行spark是信息就多,这个用于区分数据的输出
def word(line):
"""切词,将句子按空格分开,返回一个列表"""
return line.split()
def map_fun(line):
"""map处理函数,主要实现将输入的一个单词,变为元组,其中1表示词频"""
return (line,1)
def reducebykey_fun(a,b):
"""reduceByKey处理函数,接受相邻两个元素,并做加法运算"""
return a+b
def reduce_fun(a, b):
"""reduce处理函数,接受相邻两个元素,并做比较大小运算,最终返回最大值"""
if a[0] > b[0]:
return a
else:
return b
def test():
conf = SparkConf().setAppName("worldCount").setMaster("local")
# 定义spark参数
sc = SparkContext(conf=conf)
# 初始化SparkContent对象,可以理解为这是与spark交互的接口
datas1 = sc.textFile("file:///home/hadoop_test/hadoop_test/input.txt")
# 加载数据集datas1,返回RDD类型,RDD可从普通数组创建,也可由系统目录或HDFS中的文件创建
print s + str(datas1.count()) # 输出数据集中个数
print s + str(datas1.first()) # 输出数据集中第一个元素
datas2 = datas1.flatMap(word)
# flatmap接口接受一个函数,函数的返回值是一个可迭代对象,最后返回一个RDD数据集
# 这一步已经得到切好词的单词数据集,不在是句子了
print s + str(datas2.collect())
datas3 = datas2.map(map_fun)
# map接口同上,也是接受一个函数,函数的返回值可以是任意类型,这里返回一个元素为元组结构
print s + str(datas3.collect())
datas4 = datas3.reduceByKey(reducebykey_fun)
# reduceByKey接口接受一个函数,合并具有相同键的值,返回值可以可以任意定,但是函数的传入值是键的值
print s + str(datas4.collect())
datas5 = datas3.reduce(reduce_fun)
# reduce接口接受一个函数,该函数的参数传入值是整个元素,例如我这里元素结构为元组,返回值可以可以任意定
print s + str(datas5)
# datas = datas.filter()
sc.stop()
test()
附上以上程序执行结果
[hadoop_test@hserver1 spark_test]# ~/spark-2.4.0-bin-hadoop2.7/bin/spark-submit test.py
2019-03-21 10:56:32 INFO BlockManager:54 - Using org.apache.spark.storage.RandomBlockReplicationPolicy for block replication policy
2019-03-21 10:56:32 INFO BlockManagerMaster:54 - Registering BlockManager BlockManagerId(driver, cq02-bda-advsvr06-02.cq02.baidu.com, 57792, None)
...
[result]------------->> 11
[result]------------->> sdsa
[result]------------->> [u'sdsa', u'asdasdas', u'as', u'asa', u'as', u'asdsadsa', u'asdas', u'asdas', u'asdasd', u'asdas', u'asdasdadadas', u'dasdasdadashuda', u'sdas', u'dias', u'da', u'duiasd', u'asjid']
[result]------------->> [(u'sdsa', 1), (u'asdasdas', 1), (u'as', 1), (u'asa', 1), (u'as', 1), (u'asdsadsa', 1), (u'asdas', 1), (u'asdas', 1), (u'asdasd', 1), (u'asdas', 1), (u'asdasdadadas', 1), (u'dasdasdadashuda', 1), (u'sdas', 1), (u'dias', 1), (u'da', 1), (u'duiasd', 1), (u'asjid', 1)]
[result]------------->> [(u'asdas', 3), (u'asdasdas', 1), (u'asdasdadadas', 1), (u'sdsa', 1), (u'as', 2), (u'asdasd', 1), (u'asdsadsa', 1), (u'duiasd', 1), (u'asa', 1), (u'asjid', 1), (u'sdas', 1), (u'da', 1), (u'dasdasdadashuda', 1), (u'dias', 1)]
[result]------------->> (u'sdsa', 1)
....
3.spark相关API接口
变换操作:
map():参数是函数,函数应用于RDD每一个元素,返回值是新的RDD
flatMap():参数是函数,函数应用于RDD每一个元素,将元素数据进行拆分,变成迭代器,返回值是新的RDD
filter():参数是函数,函数会过滤掉不符合条件的元素,返回值是新的RDD
zip():把两个列表的元素合成一个由元素对组成的列表里
partition():根据函数的返回值对列表进行拆分
find():返回集合里第一个匹配结果的元素
flatten:用于把嵌套的结构展开
distinct():没有参数,将RDD里的元素进行去重操作
union():参数是RDD,生成包含两个RDD所有元素的新RDD
intersection():参数是RDD,求出两个RDD的共同元素
subtract():参数是RDD,将原RDD里和参数RDD里相同的元素去掉
cartesian():参数是RDD,求两个RDD的笛卡儿积
行动操作:
collect():返回RDD所有元素
count():RDD里元素个数
countByValue():各元素在RDD中出现次数
reduce():并行整合所有RDD数据,例如求和操作
fold(0)(func):和reduce功能一样,不过fold带有初始值
foreach(func):对RDD和map一样对每个元素都使用特定函数,无返回值。
take(n):返回结果的前n个元素
first():返回据集的第一个元素(类似于take(1))
saveAsTextFile(path):据集的元素,以textfile的形式,保存到本地文件系统,hdfs或者任何其它hadoop支持的文件系统
二元组RDD常用API
注意:这种一般是K-V这种类型
reduceByKey:合并具有相同键的值
groupByKey:对具有相同键的值进行分组
keys:返回一个仅包含键值的RDD
values:返回一个仅包含值的RDD
sortByKey:返回一个根据键值排序的RDD
flatMapValues:针对Pair RDD中的每个值应用一个返回迭代器的函数,然后对返回的每个元素都生成一个对应原键的键值对记录
mapValues:对Pair RDD里每一个值应用一个函数,但是不会对键值进行操作
combineByKey:使用不同的返回类型合并具有相同键的值
subtractByKey:操作的RDD我们命名为RDD1,参数RDD命名为参数RDD,剔除掉RDD1里和参数RDD中键相同的元素
join:对两个RDD进行内连接,在类型(K,V)和(K,W)类型的据集上用,返回一个(K,(V,W)),每个key中的所有元素都在一起的据集
rightOuterJoin:对两个RDD进行连接操作,第一个RDD的键必须存在,第二个RDD的键不再第一个RDD里面有那么就会被剔除掉,相同键的值会被合并
leftOuterJoin:对两个RDD进行连接操作,第二个RDD的键必须存在,第一个RDD的键不再第二个RDD里面有那么就会被剔除掉,相同键的值会被合并
cogroup:将两个RDD里相同键的数据分组在一起
countByKey:对每个键的元素进行分别计数
collectAsMap:将结果变成一个map
lookup:在RDD里使用键值查找数据
sample:对RDD采样
take(num):返回RDD里num个元素,随机的
top(num):返回RDD里最前面的num个元素,这个方法实用性还比较高
takeSample:从RDD里返回任意一些元素
sample:对RDD里的数据采样
takeOrdered:从RDD里按照提供的顺序返回最前面的num个元素