1、collect的功能是什么,其底层是怎么实现的?
driver通过collect把集群中各个节点的数据收集过来汇总成总结果,collect返回结果是array类型的,collect把各个节点的数据抓过来,抓过来的数据是array类型,collect对array抓过来的结果进行合并,合并后array中只有一个元素,是tople类型(kv类型的)
2、spark为什么要进行持久化,一般在什么场景下进行persist操作?
为什么要进行持久化?
spark所有复杂一点的算法都会有persist身影,spark默认数据放在内存中,spark很多内容都是放在内存中,非常适合高速迭代。只有第一个输入数据中间不产生临时数据,但分布式系统风险很高,所以容易出错,就需要容错,rdd出错或者分片可以根据血统算出来,如果没有对rdd进行persist或者cache的话,就需要重头做。
以下场景
(1)、某个步骤计算非常耗时,需要用到persist持久化
(2)、计算链条非常长,重新恢复要很多步骤,
(3)、checkpoint 所在的rdd要持久化persist
lazy级别,框架发现有checnkpoint,checkpoint(相当于快照)_时单独触发一个job,需要重算一遍,checkpoint前
要持久化,写个rdd.cache或者rdd.persist,将结果保存起来,再写checkpoint操作,这样执行起来会非常快,不需要重新计算rdd链条了。checkpoint之前一定会进行persist。
(4)、shuffle之后为什么要进行persist,shuffle要进行网络传输,风险很大,数据丢失重来,恢复代价很大
.介绍一下join操作优化经验?
答:join其实常见的就分为两类: map-side join 和 reduce-side join。当大表和小表join时,用map-side join能显著提高效率。将多份数据进行关联是数据处理过程中非常普遍的用法,不过在分布式计算系统中,这个问题往往会变的非常麻烦,因为框架提供的 join 操作一般会将所有数据根据 key 发送到所有的 reduce 分区中去,也就是 shuffle 的过程。造成大量的网络以及磁盘IO消耗,运行效率极其低下,这个过程一般被称为 reduce-side-join。如果其中有张表较小的话,我们则可以自己实现在 map 端实现数据关联,跳过大量数据进行 shuffle 的过程,运行时间得到大量缩短,根据不同数据可能会有几倍到数十倍的性能提升
广播变量:task的数量由rdd的分区决定。算子中使用driver端的变量,也会被封装到task中发送到Excutor中(每个task中都会有一个变量副本)如果task的数量很多,产生的变量副本也会很多,会导致网络上传输的数据量变多。整体性能降低。
广播变量中的数据,并不会封装到task中
1、task在运行的时候会向excutor查找广播变量的数据
2、如果Excutor中有这个广播变量的数据,可以直接使用
3、如果excutor中没有这个广播变量,Excutor会到driver拉取这个广播变量
优点:每一个Excutor中只有一个变量副本