总 结
1 PySpark简介
Spark是基于Scala语言开发的,专为大规模数据处理而设计的快速通用的计算引擎
Python中Apache Spark的接口
2 PySpark功能
2.1 Spark Core
Spark底层通用执行引擎,提供RDD(弹性分布式数据集)和内存计算功能
2.2 DataFrame
二维数据结构, 类似于pandas的dataframe
2.3 Pandas API
支持pandas API
2.4 Spark SQL
分布式查询引擎, 用于结构化数据处理
2.5 MLlib
机器学习库,sklearn
2.6 Streaming
kafka+Spark Streaming,高吞吐高容错的实时流数据处理
3 RDD
3.1 概念:弹性分布式数据集, 不可变, 可分区
3.2 部署模式:
3.2.1 Local本地模式:(学习环境)
3.2.2 Standalone独立模式:
运行在自带的资源调度管理框架之上, 可以独立部署到集群, 而无需依赖其他系统
3.2.3 Mesos模式:
运行在Mesos资源调度管理框架之上, 官方推荐这种模式, 大部分企业也是采用这种模式
3.3.4 YARN:
运行在YARN资源调度管理框架上, 与hadoop进行统一部署, 分布式存储则依赖hdfs(分布式文件系 统)
3.3 创建RDD
3.3.1 textFile方法
本地文件系统加载数据
# 第2个参数,指定分区数量 file = "./data/hello.txt" rdd = sc.textFile(file, 3) # 展示所有元素 rdd.collect()
3.3.2 parallelize方法
# 第2个参数,指定分区数量 rdd = sc.parallelize(range(1, 11), 2) rdd.collect()
4 RDD算子(函数)
4.1 Actions
动作算子的特点是立刻执行
4.2 常用动作算子
4.2.1 collect
# 查看所有的元素 rdd.collect() # 查看所有的元素 rdd.collect() [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4.2.2 take
# 查看指定数量的元素 rdd.take(4)
4.2.3 first
# 获取第1个元素 rdd.first()
4.2.4 top
# 获取top n的元素 rdd.top(3)
4.2.5 takeOrdered
# 按指定规则排序后,再抽取指定数量的元素 # 升序后抽取 rdd.takeOrdered(num=5) # 降序后抽取 rdd.takeOrdered(num=5, key=lambda x: -x)
4.2.6 takeSample
# 随机抽取指定数量的元素 # 第1个参数,是否重复抽样 # 第2个参数,抽样数量 # 第3个参数,随机种子 rdd.takeSample(False, 5, 0)
4.2.7 count
# 查看元素数量 rdd.count()
4.2.8 sum
rdd.sum() # 求和 rdd.max() # 最大值 rdd.min() # 最小值 rdd.mean() # 平均值 rdd.stdev() # 总体标准差 rdd.variance() # 总体方差 rdd.sampleStdev() # 样本标准差 rdd.sampleVariance() # 样本方差 rdd.stats() # 描述统计
4.2.9 histogram
# 按指定箱数,分组统计频数 rdd.histogram(2) # ([0, 25, 50], [25, 26]) # 第1组[0, 25): 25 # 第2组[25, 50]: 26
4.2.10 fold
# 按指定函数(add加法)对元素折叠 from operator import add rdd.fold(0, add)
4.2.11 reduce
# 二元归并操作,如累加 # 逐步对两个元素进⾏操作 rdd.reduce(lambda x, y: x + y) from operator import add rdd.reduce(add)
4.2.12 foreach
# 对每个元素执行一个函数操作 # accumulator累加器 acc = sc.accumulator(value=0) rdd.foreach(lambda x: acc.add(x)) acc.value
4.2 Transformations变换算子
变换算子的特点是惰性执行(不会立刻执行), 而是需要等到有动作算子操作的时候才会真正去执行
4.2.1 map
# 对每个元素映射一个函数操作,如求平方 rdd.map(lambda x: x**2).collect()
4.2.2 filter
# 筛选数据,如筛选大于5的元素 rdd.filter(lambda x: x > 5).collect()
4.2.3 flatMap
rdd = sc.parallelize(["hello world", "hello python"]) rdd.collect() # flat展平 ['hello world', 'hello python'] # 先以空格拆分为二维结构 rdd.map(lambda x: x.split(" ")).collect() [['hello', 'world'], ['hello', 'python']] # 对每个元素映射一个函数操作 # 并将结果数据进行扁平化(展平) rdd.flatMap(lambda x: x.split(" ")).collect() ['hello', 'world', 'hello', 'python']
4.2.4 sample
# 每个分区按比例抽样 # 第1个参数,是否重复抽样 # 第2个参数,抽样概率 # 第3个参数,随机种子 rdd.sample(False, 0.5, 666).collect()
4.2.5 distinct
# 去重 rdd.distinct().collect()
4.2.6 subtract差集/union并集/intersection交集
4.2.7 sortBy
# 按第3列排序,默认升序 rdd.sortBy( keyfunc=lambda x: x[2], ascending=True ).collect()
5 PairRDD变换算子
-
包含key和value的RDD,类似python的字典
5.1 KeyBy
创建一个键值对RDD rdd = sc.parallelize(["a", "b", "c"]) # 以函数返回值作为key,原有元素作为value rdd.keyBy(lambda x: 1).collect() [(1, 'a'), (1, 'b'), (1, 'c')]
5.2 lookup
# 通过key访问value,动作算子 rdd.lookup("python")
5.3 reduceByKey
# 以key分组对value执行二元归并操作,比如求和 rdd.reduceByKey(lambda x, y: x+y).collect()
6 RDD分区算子
6.1 glom
rdd = sc.parallelize(range(10), 2) rdd = sc.parallelize(range(10), 2) rdd.collect() [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 将每个分区的元素转换为列表 rdd.glom().collect() [[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]
6.2 coalesce
# 重置分区数量 # shuffle=True,增加至指定分区数量 # shuffle=False,减少至指定分区数量 rdd_new = rdd.coalesce(2, shuffle=False) rdd_new.glom().collect()
6.3 repartition
# 单元素RDD重置分区数量 rdd1 = sc.parallelize(range(10), 3) # 键值对RDD重置分区数量 rdd2 = sc.parallelize( [("a", 1), ("a", 2), ("a", 3), ("c", 4)])
6.4 partitionBy
# 键值对RDD重置分区数量 rdd2 = sc.parallelize( [("a", 1), ("a", 2), ("a", 3), ("c", 4)])
7 RDD缓存
-
什么缓存: 缓存是一种可以实现内存与CPU之间高速交换数据的存储器
-
工作原理: 当CPU要读取一个数据, 优先从缓存中查找, 找到就立即读取并发给CPU处理
-
如果一个RDD被多个任务调用, 那么可以缓存到内存中, 提高计算效率
-
如果一个RDD后续不再被调用, 那么可以立即释放缓存, 避免资源浪费
rdd.getStorageLevel() # 常见的两种存储级别 # 第1种: 缓存到内存 # 第2种: 缓存到内存和磁盘 # StorageLevel(False, True, False, False, 1) # 是否使用磁盘, False # 是否使用内存, True # 是否使用堆外内存, False # - java虚拟机概念(jvm) # - 堆外内存受操作系统管理 # - 堆内内存受jvm管理 # 是否以java反序列化格式存储, False # - 序列化: 将对象转换为可传输的字节序列的过程 # - 反序列化: 将字节序列还原为对象的过程 # 备份数量, 1