窄宽依赖转换
窄依赖转换不需要与driver节点通信,窄依赖不需要数据跨分区迁移,在一个stage中执行计算,宽依赖的转换需要跨机器,数据需要跨分区迁移,尾端的计算需要等shuffle执行完成才能开始。举个例子对于尾端计算需要等shuffle完成,如sortByKey由于需要全部的数据有序,不是单个分区的有序,所以需要宽依赖转换,因为分区的数据会改变,所以排序后面的窄依赖转换计算需要等宽依赖转换完成。除了join的操作,多个RDD进行计算时,stage可以并行,stage一般是串行执行,串行计算必然是影响性能的,shuffle影响性能的原因不仅是因为宽依赖转换涉及到数据迁移和磁盘IO,还有stage的划分导致并行计算被限制。宽依赖转换对性能的影响是很大的,而且对容错的影响也很大,由于spark的容错是,分区数据出错了,可以重新计算,但是shuffle导致涉及的分区很多,当某个分区出错时可能所有的分区需要重新计算(比如一个排序好的RDD丢失了一个分区,就需要重新计算所有的分区),这样代价太大(所以存在checkpoint RDD),窄依赖就不需要全部重新计算,只需要将相关的分区重新计算。
iterator-to-iterator transformations
这种转换有时间和空间的优势,可以不用将整个分区的数据加载进内存,当内存不足时可以将不合适的数据spill到磁盘。
共享变量
包含两类:广播变量和累加器,广播变量在driver写一次,在各个执行器读;累加器在各个执行器写,在driver读。广播变量可以用来广播一个小表,用来join.
RDD复用
spark复用的RDD提供的api,包含persist、cache、checkpoint。spark不自动使用这些功能,需要用户手动使用,因为这些api的使用的损耗性能的,大数据集的persist或者checkpoint成本是比重计算更高。需要复用的场景:
- RDD需要被多次使用
- 在同一个RDD执行多次action
- transformation的链路很长