第一,RDD重构与优化
尽量去复用RDD,差不多的RDD,可以抽取成为一个共同的RDD,供后面的RDD计算时,反复使用。
第二,公共RDD一定要实现持久化
持久化,也就是说,将RDD中的数据缓存到内存中,或者缓存到磁盘中,(BlockManager),以后无论对这个RDD做多少次计算,那么都是直接取RDD的持久化的数据,比如从内存中或者磁盘中,直接提取一份数据
第三:持久化,是可以进行序列化的
如果正常将数据持久化到内存中,那么可能会导致内存的占用过大,这样的话,也许,会导致OOM内存溢出,当纯内存无法支撑公共的RDD数据完全存放的时候,就优先考虑,使用序列化的方式在纯内存中存储,将RDD的每个partition数据,序列化成一个大的字节数组,就一个对象,序列化后,大大减少内存的空间占用。
序列化的方式,唯一的缺点就是在获取数据的时候需要反序列化
如果序列化纯内存方式,还是导致OOM,内存溢出,就只能考虑磁盘的方式,内存+磁盘的普通方式(别序列化)
最不好的是内存+磁盘+序列化
第四,为了数据的高可靠性,而且内存充足,可以使用双副本机制,进行持久化。
持久化的双副本机制(内存超多的情况)
持久化怎么做?
就是对RDD调用persist()方法,并传入一个持久化级别
action.persist(StorageLevel.MEMORY_ONLY());
只要一个spark作业中的RDD被使用了俩次以上,那么就可以对它进行persist