1.job&stage&task如何划分?
job:应用程序中每遇到一个action算子就会划分为一个job。
stage:一个job任务中从后往前划分,分区间每产生了shuffle也就是宽依赖则划分为一个stage,stage这体现了spark的pipeline思想,即数据在内存中尽可能的往后多计算,最后落盘,减少磁盘IO。
task:RDD中一个分区对应一个task。
2.什么是宽依赖和窄依赖?
根据分区之间是否产生shuffle来确定。
宽依赖:上游一个分区的数据被打散到下游的多个分区,1:N
窄依赖:上游一个分区的数据全部进入到下游的一个分区,1:1 or N:1
3.Spark有哪几种部署模式,有什么区别?
1.Local:本地模式,运行在单个机器,一般用作测试环境。
2.Standalone:一个基于Master+Slaves的资源调度集群。spark任务提交给Master调度管理,是spark自带的一个调度系统。
3.Yarn:spark客户端直接连接yarn,不需要额外构建spark集群。有yarn-client和yarn-cluster两种模式,主要区别在于:driver程序的运行节点。yarn-client时driver运行在本地提交任务的客户端,yarn-cluster是driver运行在集群中随机的任一节点。
4.Mesos:比较少用,不了解。
5.K8s:spark后续高版本新增支持。
4.Spark中算子有哪些类型?分别举例。
一共有3种算子类型:转换算子(Transformation)、动作算子(Action)、控制算子(cache、persist、checkpoint)
转换算子:返回一个新的RDD。
动作算子:不返回RDD,返回RDD的值或将值持久化存储。
控制算子:持久化内存、磁盘或HDFS。返回原被持久化的RDD而非新RDD。
算子举例:
Transformation:
- 的
5.cache、persist、checkpoint的区别,及各自的使用场景?
6.广播变量与累加器
1)广播变量
简而言之,就是在每个集群节点中缓存一份driver端定义的公共变量,且该被广播的变量在executor中只读。
当不使用广播变量的时候,spark任务中需要用到的公共变量会copy到每个task中,这种方式弊端一是重复存储占用内存资源,二是增加了IO操作。而使用广播变量,driver端定义的公共变量只会往每个集群中的worker节点中copy一份,由executor中的所有task共享。且该方法的底层实现涉及到了序列化与反序列化以及高效的广播算法,所以效率较高。
详细参考官网:https://spark.apache.org/docs/3.1.2/rdd-programming-guide.html#shared-variables
广播变量 demo
from pyspark.sql import SparkSession
"""
需求:从rdd中过滤掉黑名单“blacklist”中的角色
"""
spark = SparkSession.builder \
.master("local[*]") \
.appName("broadcast_demo") \
.config("spark.executor.instances", "4") \
.config("spark.executor.cores", "2") \
.config("spark.executor.memory", "1g") \
.getOrCreate()
sc = spark.sparkContext
rdd = sc.parallelize([("101", "梁静茹"), ("102", "王菲"), ("103", "王诗安"), ("104", "李宗盛")], 2)
print(f"过滤前:{rdd.collect()}")
blacklist = ["101", "103"]
bc = sc.broadcast(blacklist)
rdd_filter = rdd.filter(lambda x: x[0] not in bc.value)
print(f"过滤后:{rdd_filter.collect()}")
sc.stop()
spark.stop()
2)累加器
累加器,简要的概括,是一种分布式共享只写变量。
7.reduceByKey与groupByKey的区别?
https://blog.csdn.net/atwdy/article/details/133155108