一、spark的内存分布
sql
复制代码
堆内内存:
在这使用堆内内存的时候,如果我们设置了堆内内存2个g的话,读取的数据也是两个g,此时又来两个g的数据,这样就会产生OOM溢出,因为处理完两个g的数据,并不会马上进行GC。
堆外内存:
这样我们就可以使用堆外内存,也就是物理内存,堆外内存可以精准的申请和释放空间,不需要Gc,性能比较高,提升了任务的效率。
二、Spark的宽窄依赖
sql
复制代码
宽依赖:
一个父RDD分区中的数据划分到多个子RDD分区的过程,也就说明有shuffle的过程。如GroupByKey,reduceByKey,join,sortByKey等。
窄依赖:
一个父RDD分区中的数据被一个子RDD分区所使用,map,filter。
三、Spark中reduceByKey和groupByKey的区别
sql
复制代码
reduceByKey:按照key进行聚合,在shuffle之前有个combine预聚合的操作,返回的结果是RDD(K,V)
groupByKEy:直接按照key进行进行分组,直接进行shuffle
建议使用reduceByKey 但注意是否会影响最终的业务逻辑
四、Spark的缓存
sql
复制代码
将频繁使用的RDD进行缓存到内存中,后面RDD用到的时候去内存中区就不需要重复了,提高任务的执行效率
cache时间数据保存在内存中
程序结束后会被清除或手动调用unpersist方法清除
会记录RDD的血缘关系
五、什么是RDD
sql
复制代码
一个弹性分布式的数据集
数据可以保存在内存中也可以保存在磁盘中
他是一个分布式的计算的集合
RDD有3个特征分区、不可变、并行操作
RDD是有好多分区组成的,操作RDD的时候,对RDD里的每个分区进行操作
RDD使用算子进行操作
算子分为转换算子与行动算子
六、Spark落盘场景
sql
复制代码
在shuffle中会进行落盘的操作
shuffle分为shuffle write和shuffle read
在这期间会进行一次落盘操作
七、Spark的shffle
sql
复制代码
Spark使用涉及到一些shuffle算子的时候就会进行shuffle
shuffle的过程:
八、Spark内存OOM的情况
sql
复制代码
1. map过程中产生大量对象导致内存溢出
2. 数据不平衡导致内存溢出
3. coalesce调用导致内存溢出
4. shuffle后内存溢出
5. standalone模式下资源分配不均匀导致内存溢出
6. 在RDD中,公用对象能减少OOM的情况
九、怎样避免SparkOOM
sql
复制代码
1. 使用mapPartition代替部分map操作,或者连续使用map的操作
2. broadcast join和普通join
3. 先filter在join
4. partitionBy优化
5. combineDyKey的使用
6. 参数优化
十、Spark shuffle的默认并行度
sql
复制代码
由spark.sql.shuffle.partitions决定默认并行度为200,数据量比较的是并且集群性能可以的时候也已适当的加大
十一、Coalesce和Repartition的区别
sql
复制代码
Coalesce和Repartition两个都是用来改变分区的,Coalesce用来缩减分区但不会进行shuffle,Repartition用来增加分区会进行shuffle的操作,在spark中减少文件个数会使用coalesce来减少分区,但如果分区量过大,分区数过少就会出现OOM,所以coalesce缩小分区个数也需合理。
十二、如何使用spark实现TopN的操作
sql
复制代码
方法一:
(1)按照key对数据进行聚合(reduceByKey)
(2)将value转换为数组,利用scala中sortBy或者sortWith进行排序(mapValues)数据量太大,会OOM。
方法二:
(1)自定义分区器,按照key进行分区,使不同的key进到不同的分区中
(2)对每个分区运用spark的排序算子进行排序
十三、spark中的共享变量
sql
复制代码
累加器是spark中提供的一种分布式变量机制,其原理类似与mapreduce先分后合,累加器的一个常用用途在对作业执行中的事件进行计数。而广播变量用来搞笑分发较大的对象。
十四、Coalesce和Repartition的关系与区别
sql
复制代码
关系:都是用来修改RDD的partition数量的,repartiotion底层调用的就是coalesce()方法coalesce(numPaitition,shuffle=true)
区别:repartiotion一定会发生shuffle,coalesce根据传入的参数来判断是否会发生shuffle
一般情况下增大rdd的partition的数量使用repartition,减少partition数量使用coalesce
十五、Spark的调优
sql
复制代码
遵循几个原则
原则一:避免重复使用的RDD
原则二:尽可能复用一个RDD
原则三:对多次使用的RDD进行持久化
原则四:尽量避免使用shuffle类的算子
原则五:使用map-side预聚合的shuffle操作
原则六:使用高性能的算子
原则七:广播大变量
原则八:使用Kryo优化序列化性能
原则九;优化数据结构
十六、Spark中RDD与DataFream及DataSet之间的关系
sql
复制代码
宏观:
RDD:弹性分布式数据集
Datafream在RDD上多了一层schema
Dataset在datafream之上多了一个数据结构
微观:
RDD:
优点 编译时:
编译时可以检查类型是否安全
面向对象的风格:
可以通过直接点方法对数据进行操作
缺点 序列化与反序列化消耗资源太大,反序列化时会将数据结构与数据内容都序列化
GC操作频繁,RDD要频繁的创建和销毁,务必会产生很多的GC操作
Datafream:在RDD之上引入一层schema与off-head
多个RDD每行的数据结构都一致,spark就可以通过schema来识别数据结构在反序列化的时候可以只反序列化数据而结构就可以省略掉了
Dataset:综合了RDD与Datafream的优点,并引入encoding数据再进行序列化时ancoding出来的字节码和off-head互通,这样就可以按需读取数据
三者之间的转换:
rdd - df = toDF
rdd - ds = toDS
df - ds = as[]
ds - df = toDF
ds - rdd = RDD
df - rdd = RDD
十七、简述介绍sparkStreaming窗口函数的原理
sql
复制代码
窗口函数就是在原来定义的sparkStreaming计算批次大小的基础上在进行封转,每次计算多个批次的数据,同时还需要传递一个滑动步长的参数,用来设置当前任务完成之后下次从什么地方开始计算。
十八、SparkStreaming精准一次消费
sql
复制代码
1. 手动维护偏移量
2. 处理完业务数据后,在进行提交偏移量的操作
极端条件下,如果在提交偏移量断网或停电会造成spark程序第二次启动时重复消费问题,所以在涉及到金额或精确度非常高的场景会使用事务保持精准一次消费。