Spark的RDD Persistence,是一个重要的能力,可以将中间结果保存,提供复用能力,加速基于中间结果的后续计算,经常可以提高10x以上的性能。在PySpark的DataFrame中同样适用。
主要方法是persist()
和cache()
。官方说明请看RDD Persistence。
需要注意的是,Spark Python API中,默认存储级别是MEMORY_AND_DISK
。
本文记录一下实际开发中使用Spark这个能力的一些心得,主要是PySpark。
persist()
和cache()
该使用哪个?
建议总是使用persist()
。
原因:persist()
功能更加强大,由于其支持设置存储级别,所以用起来更加灵活方便。cache()
虽然是使用默认存储级别,但是在网上看到,使用cache()
出现内存溢出的问题,换成persist()
就没问题。我一般使用persist()
,所以没遇到过这个问题。
什么时候使用persist()
?
1、当一个中间数据集,后面被多个计算重复使用,你应该对这个数据集使用persist()
。
2、如果资源允许,你应该尽可能多的使用persist()
,因为这可以极大的减少重复计算,提高程序性能。
关于第2点,至少我写这篇随笔时,是这样认为的。为什么这么说,是因为我在实际开发中做过一个对比测试。
我开发了一个PySpark程序,只对最大的几个需要重复使用的数据集使用了persist()
,程序运行时间10分钟左右。这个程序中,有不少中间结果会被重复使用,当我对一部分中间结果数据集也使用了persist()
之后,程序运行时间降低为8.7分钟左右。当我对大部分会被重复使用的中间结果数据集使用了persist()
之后,程序运行时间进一步降低为8分钟左右。
我对比了三种程序的stage情况,发现使用persist()
多的程序,stage数量有一定的减少,另外相同的stage,可以达到几秒的差距,当然也许和机器配置有关。不过这个性能提升确实非常明显!!也许存在偶然性,不过理论上来说,这个应该可以提升性能。
什么时候使用unpersist()
?
unpersist()
是用来释放资源的,是persist()
的反向操作。
你应该在第一时间使用unpersist()
,也就是说,当这个数据集不再被使用,应该立刻释放其占用的资源。
该如何选择存储级别?
如果条件允许,建议使用默认存储级别。
在PySpark中,persist()
的默认存储级别是MEMORY_AND_DISK
,个人觉得这个存储级别是一个非常好的策略。
至于其他存储级别,可以在程序调试中对比测试其性能,来决定使用哪个存储级别。