什么是RDD
- RDD是弹性分布式数据集,Spark最基本的数据集,它不可变、可分区、可并行计算。
- 弹性表示:可以将数据存储在内存或者磁盘,RDD的分区是可以改变的,task如果失败会进行特定次数的重试,stage如果失败会自动进行特定次数的重试且只会计算失败的分片,基于lineage的高效容错
RDD有什么特性
- A list of partitions
- A function for computing each split
- A list of dependencies on other RDDs
- Optionally,a Partitioner for key-value RDDs(eg:to say that the RDD is hash-partitioned)
- 可选项,数据本地性,数据位置最优
map、flatMap与mapPartition的区别
- map 函数会对每一条输入进行指定的操作,然后为每一条输入返回一个对象
- flatMap函数则是两个操作的集合——正是“先映射后扁平化”
-
- 对每一条输入进行指定的操作,然后为每一条输入返回一个对象
-
- 将所有对象合并为一个对象
- mapPartition每次处理一个分区的数据,但是可能导致OOM
repartition和coalesce异同
- 前者会产生shuffle,后者不会
- repartition只是coalesce接口中shuffle为true的简易实现
transformation与action的区别
- transformation:不触发提交作业,属于延迟计算
- action:会触发SparkContext提交Job作业
reducebykey与groupbykey的区别
- 前者的效率高于后者
- reducebykey:spark会在每个分区移动数据之前将输出数据与一个共用的key结合
- groupbykey:所有的键值对(key-value pair) 都会被移动,在网络上传输这些数据非常没必要,因此避免使用 GroupByKey
宽依赖与窄依赖
- 窄依赖:一个父RDD的分区去到了子RDD的一个分区,没有shuffle产生,如:filter、map、flatMap、distinct
- 宽依赖:一个父RDD的分区去到子RDD的多个分区,会产生shuffle,如:reduce、groupByKey、join
Spark中如何划分Stage
- 从后往前,遇到宽依赖就划分stage
pipeline管道
- pipeline管道会来一条数据计算一条数据,会把所有的逻辑走完,然后shuffle write,进行数据的持久化
RDD缓存
- cache与persist
- cache只能基于内存的缓存
- persist可以选择不同的StorageLevel
- cache不一定会提升速率,当数据量很大时,会造成缓存溢出
RDD共享变量
- 广播变量
-
- 缓存到各节点的内存
-
- 能被集群中的任何变量调用
-
- 变量是只读的,不能修改
- 累加器
-
- 支持加法操作,实现计数器与变量求和
spark-submit的时候如何引入外部jar包
- 配置 -driver-class-path 外部jar包
- 配置 -jars 外部jar包
Spark防止内存溢出
- driver端的内存溢出
-
- 可以增大driver的内存参数spark.driver.memory (default 1g)
- map过程产生大量对象导致内存溢出
-
- 在会产生大量对象的map操作之前调用repartition方法,分区成更小的块传入map
- 数据不平衡导致内存溢出
-
- 调用repartition重新分区
- shuffle后内存溢出
- 使用rdd.persist(StorageLevel.MEMORY_AND_DISK_SER)代替rdd.cache()
shuffle数据块有多少种不同的存储方式
- RDD数据块:用来存储所缓存的RDD数据
- shuffle数据块:用来存储持久化的shuffle数据
- 广播数据块:存储广播变量的数据
- 任务返回数据块:
- 流式数据块:spark streaming中,存储接收到的流式数据块
数据倾斜
- 多数task执行速度较快,少数task执行时间非常长,或者等待很长时间后提示你内存不足,执行失败
数据倾斜原因
- 数据问题:key分布不均衡,key的设置不合理
- spark问题:shuffle时并发度不高
数据倾斜的后果
- spark中的stage的执行时间受限于最后那个执行完成的task,因此运行缓慢的任务会拖垮整个程序的运行速度
- 过多的数据在同一个task中运行,将会把executor撑爆
如何实现sparkStreaming读取kafka中的数据
- receiver:是采用了kafka高级api,利用receiver接收器来接受kafka topic中的数据,从kafka接收来的数据会存储在spark的executor中,之后spark streaming提交的job会处理这些数据,kafka中topic的偏移量是保存在zk中的。
- direct:在spark1.3之后,引入了Direct方式。不同于Receiver的方式,Direct方式没有receiver这一层,其会周期性的获取Kafka中每个topic的每个partition中的最新offsets,之后根据设定的maxRatePerPartition来处理每个batch。
什么是粗粒度,什么是细粒度
- 每个应用程序的运行环境由一个Dirver和若干个Executor组成,其中,每个Executor占用若干资源,内部可运行多个Task(对应多少个“slot”)
- 粗粒度:启动时就分配好资源
- 细粒度:用资源的时候再分配,用完了就立即回收
driver的功能
- 每个spark作业运行时包含一个driver进程
- 创建SparkContext程序,连接到给定的SparkMaster
- 划分stage,并生成DAGScheduler
- 通过taskScheduler生成并发送task到executor
Spark技术栈有哪些
- spark core
- spark streaming
- spark sql
- MLBase:MLlib、MLl、MLOptimizer、MLRuntime
- GraphX
- BlinkDB
Spark有哪些组件
- master
- worker
- driver
- spark context
- client
Spark作业执行流程
- 客户端提交作业
- driver启动流程
- driver申请资源并启动其余executor
- executor启动流程
- 作业调度,生成stages与tasks
- task调度到executor上,executor启动线程执行task逻辑
- driver管理task状态
- task完成,stage完成,作业完成
来源:oschina
链接:https://my.oschina.net/u/577399/blog/4306238