spark的使用入门
- 使用notebook打开pyspark
PYSPARK_DRIVER_PYTHON=jupyter PYSPARK_DRIVER_PYTHON_OPTS=notebook ./bin/pyspark
- 用python写独立应用
初始化SparkContext
from pyspark import SparkConf, SparkContext
Master = yarn # 集群URL:可选local, yarn-client
conf = SparkConf().SetMaster(Master).setAppName("My app")
...
# deploy-mode: 可选client, cluster,指定yarn的模式
spark-submit --master yarn --deploy-mode client test.py
注意点:
在以上运行过程中出现错误:
Current usage: 80.2 MB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual memory used. Killing container.
解决方法:
在yarn-site.xml中添加以下代码即可,记得要重启hadoop和spark。
<property>
<name>yarn.nodemanager.pmem-check-enabled</name>
<value>false</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
驱动器节点
驱动器程序在Spark应用中有以下两种职责:
- 把用户程序转为任务
spark驱动器负责把用户程序转为多个物理执行的单元,这些单元也被称为任务。任务是Spark中最小的工作单元,用户程序通常要启动成百上千的独立任务。 - 为执行器节点调度任务
驱动器进程始终对应用中所有的执行节点有完整的记录。每个执行节点代表一个能够处理任务和存储RDD数据的进程。
Spark驱动器程序会更具当前的执行器节点集合,尝试把所有任务基于数据所在位置分配给合适的执行器进程。当任务执行时,执行器进程会把缓存数据存储起来,而驱动器进程同样会跟踪这些缓存数据的位置,并且利用这些位置来调度以后的任务,以尽量减少数据的网络传输。
执行器节点
Spark执行器节点是一种工作进程,负责在Spark作业中运行任务,任务间相互独立,执行器崩溃或异常,Spark应用也可正常运行。
执行器的两大作用:
- 它们负责组成Spark应用的任务,并将结果返回给驱动器进程
- 它们通过自身的块管理器为用户程序中要求缓存的RDD提供内存式存储。RDD式是直接缓存在执行器进程内的,因此任务可以在运行时充分利用缓存数据加速运算。
集群上运行Spark应用的过程总结:
(1) 用户通过spark-submit脚本提交应用。
(2)spark-submit脚本启动驱动器程序,调用用户定义的main()方法。
(3)驱动器程序与集群管理器通信,申请资源已启动执行器节点。
(4)集群管理器为驱动器程序启动执行器节点
(5)驱动器进程执行用户应用中的操作。根据程序中的所定义的对RDD的转化操作和行动操作,驱动器节点把工作以任务的形式发送到执行器进程
(6)任务在执行器程序中进行计算并保存结果。
(7)如果驱动器程序的main()方法退出,或者调用了SparkContext.stop(),驱动器程序会终止执行器操作,并且通过集群管理器释放资源。
pyspark快速入门:
一.RDD编程
RDD支持两种操作:转化操作和行动操作
- 转化操作
- 转化操作为惰性操作,只有在执行行动操作时,才开始执行转化操作。所以不应该将RDD看做放着特定数据的数据集,而是通过转化操作构建出来的、记录如何计算数据的指令列表。
- 若希望能多次使用同一个RDD,使用持久化存储:persist()
- 移除持久化的RDD:unpersist()
- 转化操作可以操作任意数量的输入RDD
基本的转化操作
函数名 | 目的 |
---|---|
map() | 将函数应用于RDD中的每个元素,将返回值构成新的RDD |
flatmap() | 将函数应用于RDD中的每个元素,将返回的迭代器的内容构成新的RDD,通常用来切分单词 |
filter() | 返回一个通过传给filter()的函数的元素组成RDD |
distinct() | 去重 |
sample(withReplacement, fraction, [seed] | 对RDD采样,以及是否替换 |
union() | 生成一个包含两个RDD中所有元素的RDD |
intersection() | 求两个RDD共同的元素的RDD |
subtract() | 移除一个RDD中的内容 |
cartesian() | 于另一个RDD的笛卡尔积 |
- 行动操作
基本的RDD行动操作
函数名 | 目的 |
---|---|
collect() | 返回RDD中的所有元素 |
count() | RDD中的元素个数 |
countByValue() | 各元素在RDD中出现的次数 |
take(num) | 从RDD中返回num个元素 |
top(num) | 从RDD中返回最前面的num个元素 |
takeOrdered(num) (ordering) | 从RDD中按照提供的顺序返回最前面的num个元素 |
takeSample(withRepalcement, num, [seed]) | 从RDD中返回任意一些元素 |
reduce(func) | 并行整合RDD中所有的整数 |
fold(zero)(func) | 和reduce()一样,但是需要提供初始值 |
aggreagte(zeroValue)(seqOp, comOp) | 和Reduce()相似,但是通常返回不同类型的函数 |
foreach(func) | 对RDD中的每个元素使用给定的函数 |
注意点:
- collect() 要求所有数据都必须能一同放入单台机器的内存中。
- take(n) 尝试只访问尽量少的分区,因此会得到一个不均衡的集合,返回元素的顺序与预期不一致。
- top() 可以通过提供自己的比较函数,来提取前几个元素
- foreach() 不将任何结果返回到驱动程序中,把数据发送到一个网络服务器中或数据库中。
二、键值对操作
- 例:使用第一个单词作为键创建出一个pairRDD
pairs = lines.map(lambda x: (x