一、没有缓存的情况:
#coding:utf8
import time
from pyspark import SparkConf,SparkContext
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
conf.set("spark.ui.port", "4041") # 显式设置 Spark UI 端口
sc=SparkContext(conf=conf)
rdd1=sc.textFile("./data/input_data/words.txt")
rdd2=rdd1.flatMap(lambda x:x.split(' '))
rdd3=rdd2.map(lambda x:(x,1))
rdd4=rdd3.reduceByKey(lambda a,b:a+b)
print(rdd4.collect())
rdd5=rdd3.groupByKey()
rdd6=rdd5.mapValues(lambda x:sum(x))
print(rdd6.collect())
time.sleep(1000000)
在以上的代码中血缘关系为:rdd1 --> rdd2 --> rdd3 --> rdd4,在执行rdd4.collect()后,rdd1、rdd2、rdd3、rdd4的计算结果不会保留,但他们的血缘关系还在。但是后面rdd5又有使用到rdd3,这时就要重新执行rdd1 --> rdd2 --> rdd3,以便生成rdd3的数据.
打开sparkUI,DAG显示在没有缓存的情况下,可以看到job1会重新前面的操作,重新生成rdd3.
二、加上缓存的情况:
以下代码加上了缓存机制。rdd3.persist(StorageLevel.DISK_ONLY_2),别忘了在最后释放缓存 rdd3.unpersist()。
#coding:utf8
import time
from pyspark import SparkConf,SparkContext
from pyspark import StorageLevel
if __name__ == "__main__":
conf = SparkConf().setAppName("test").setMaster("local[*]")
conf.set("spark.ui.port", "4041") # 显式设置 Spark UI 端口
sc=SparkContext(conf=conf)
rdd1=sc.textFile("./data/input_data/words.txt")
rdd2=rdd1.flatMap(lambda x:x.split(' '))
rdd3=rdd2.map(lambda x:(x,1))
rdd3.persist(StorageLevel.MEMORY_AND_DISK)
rdd4=rdd3.reduceByKey(lambda a,b:a+b)
print(rdd4.collect())
rdd5=rdd3.groupByKey()
rdd6=rdd5.mapValues(lambda x:sum(x))
print(rdd6.collect())
rdd3.unpersist()
time.sleep(1000000)
在以上代码中就不会重新计算rdd3,后面需要rdd3的时候可以直接从缓存读取数据,从而加快了处理速度。打开spark UI,显示如下。可以看到以下小绿点,rdd3已经被缓存了,前面的就不用重新执行了。
RDD.persist()方法可以指定不同的存储级别,即StorageLevel。一般建议使用rdd.persist(StorageLevel.MEMORY_AND_DISK)。缓存会保留被缓存RDD的血缘关系,以便在缓存数据丢失的情况下可以重新计算这些数据。
1、rdd.cache():缓存到内存中,rdd.cache() 等价于rdd.persist(StorageLevel.MEMORY_ONLY)
2、rdd.persist(StorageLevel.MEMORY_ONLY) :仅内存缓存,内存不足则丢弃部分分区,必要时重新计算丢失的分区。
3、rdd.persist(StorageLevel.MEMORY_ONLY_2) :仅内存缓存,2个副本
4、rdd.persist(StorageLevel.DISK_ONLY):仅缓存硬盘上
5、rdd.persist(StorageLevel.DISK_ONLY_2):仅缓存硬盘上,2个副本
6、rdd.persist(StorageLevel.DISK_ONLY_3):仅缓存硬盘上,3个副本
7、rdd.persist(StorageLevel.MEMORY_AND_DISK):先放内存,不够放硬盘
8、rdd.persist(StorageLevel.MEMORY_AND_DISK_2):先放内存,不够放硬盘,2个副本
9、rdd.persist(StorageLevel.OFF_HEAP):堆外内存(系统内存)
10、rdd.persist(StorageLevel.NONE):不缓存