spark性能调优之二:RDD重构和持久化
spark的RDD计算是lazy机制的,因此默认情况下,多次对同一个RDD执行算子,去获取不同的RDD,都会对这个RDD以及之前的父RDD,全部重新计算一次。因此:
1、RDD的架构需要优化和重构
尽量去复用RDD,差不多的RDD,可以重构为一个共同的RDD,以供后面RDD计算时,反复使用。
2、公共RDD一定要实现持久化
持久化,就是将RDD的数据缓存到内存/磁盘中,(BlockManager),以后对这个RDD计算时,直接从内存或磁盘中直接抽取持久化的数据。
3、持久化,是可以序列化的
当持久化过程中,内存占用过大,就会导致OOM内存溢出。这个时候就可以考虑使用序列化的方式在内存中存储。即将RDD的每个partition数据,序列化为一个大的字节数组,就一个对象,大大减少内存的空间占用。持久化的方式还有内存加磁盘,内存加磁盘再做序列化。
4、如果内存充足,为了数据的高可靠性,可以使用双副本机制
如果机器宕机了,副本丢了,就还得重新计算一次,若在其他节点还有副本,那么久不需要重新计算只需利用另一份副本即可。
附持久化级别:
级别 | 使用空间 | CPU时间 | 是否在内存中 | 是否在磁盘上 | 备注 |
MEMORY_ONLY | 高 | 低 | 是 | 否 | |
MEMORY_ONLY_2 | 高 | 低 | 是 | 否 | 数据存2份 |
MEMORY_ONLY_SER | 低 | 高 | 是 | 否 | 数据序列化 |
MEMORY_ONLY_SER_2 | 低 | 高 | 是 | 否 | 数据序列化,数据存2份 |
MEMORY_AND_DISK | 高 | 中等 | 部分 | 部分 | 如果数据在内存中放不下,则溢写到磁盘 |
MEMORY_AND_DISK_2 | 高 | 中等 | 部分 | 部分 | 数据存2份 |
MEMORY_AND_DISK_SER | 低 | 高 | 部分 | 部分 | |
MEMORY_AND_DISK_SER_2 | 低 | 高 | 部分 | 部分 | 数据存2份 |
DISK_ONLY | 低 | 高 | 否 | 是 | |
DISK_ONLY_2 | 低 | 高 | 否 | 是 | 数据存2份 |
NONE | |||||
OFF_HEAP |