这是我参与更文挑战的第29天,活动详情查看:更文挑战
一 Kryo序列化
Kryo序列化比Java序列化更快更紧凑,但Spark默认的序列化是Java序列化并不是Spark序列化,因为Spark并不支持所有序列化类型,而且每次使用都必须进行注册。注册只针对于RDD。在DataFrames和DataSet当中自动实现了Kryo序列化。
二 Spark中的血缘(笔试重点)
宽依赖和窄依赖。有Shuffle的是宽依赖。
三 Spark任务的划分
- Application:初始化一个SparkContext即生成一个Application;
- Job:一个Action算子就会生成一个Job;
- Stage:Stage等于宽依赖的个数加1;
- Task:一个Stage阶段中,最后一个RDD的分区个数就是Task的个数。
四 cache缓存级别
DataFrame的cache默认采用 MEMORY_AND_DISK
RDD 的cache默认方式采用MEMORY_ONLY
五 释放缓存和缓存
-
缓存:
- dataFrame.cache
- sparkSession.catalog.cacheTable(“tableName”)
-
释放缓存:
- dataFrame.unpersist
- sparkSession.catalog.uncacheTable(“tableName”)
六 缓存和检查点区别
-
Cache缓存只是将数据保存起来,不切断血缘依赖。Checkpoint检查点切断血缘依赖。
-
Cache缓存的数据通常存储在磁盘、内存等地方,可靠性低。Checkpoint的数据通常存储在HDFS等容错、高可用的文件系统,可靠性高。
-
建议对checkpoint()的RDD使用Cache缓存,这样checkpoint的job只需从Cache缓存中读取数据即可,否则需要再从头计算一次RDD。
七 Spark分区
-
默认采用Hash分区
缺点:可能导致每个分区中数据量的不均匀,极端情况下会导致某些分区拥有RDD的全部数据。 -
Ranger分区
要求RDD中的KEY类型必须可以排序。 -
自定义分区
根据需求,自定义分区。
请列举会引起Shuffle过程的Spark算子,并简述功能。 reduceBykey: groupByKey: …ByKey:
八 当Spark涉及到数据库的操作时,如何减少Spark运行中的数据库连接数?
使用foreachPartition代替foreach,在foreachPartition内获取数据库的连接。
九 如何使用Spark实现TopN的获取(描述思路或使用伪代码)(重点)
方法1:
1. 按照key对数据进行聚合(groupByKey)
2. 将value转换为数组,利用scala的sortBy或者sortWith进行排序(mapValues)数据量太大,会OOM。
方法2:
1. 取出所有的key
2. 对key进行迭代,每次取出一个key利用spark的排序算子进行排序
方法3:
1. 自定义分区器,按照key进行分区,使不同的key进到不同的分区
2. 对每个分区运用spark的排序算子进行排序
十 京东:调优之前与调优之后性能的详细对比(例如调整map个数,map个数之前多少、之后多少,有什么提升)
这里举个例子。比如我们有几百个文件,会有几百个map出现,读取之后进行join操作,会非常的慢。这个时候我们可以进行coalesce操作,比如240个map,我们合成60个map,也就是窄依赖。这样再shuffle,过程产生的文件数会大大减少。提高join的时间性能。
十一 Spark Shuffle默认并行度
参数spark.sql.shuffle.partitions 决定 默认并行度200