我有一个运行阶段计算的火花应用程序 - 即,
1.使用AWS S3(ds: data-original
)上的大型数据集输入进行计算,生成过滤结果(ds1: data-intermediate
),并将ds1
保存到AWS S3。
2.在同一个应用程序中,继续处理(过滤)ds1: data-intermediate
并生成最终结果ds2: data-final
。
3.对ds2
执行某些操作,然后将ds2
保存到AWS S3。
所以处理就像:
ds -> ds1
//ds1.persist()
ds1.write.save(...)
ds1 -> ds2
ds2.cache()
ds2.count
ds2.distinct
ds2.write.save(...)
ds / ds1 / ds2的数据大小分别为100GB,10GB,1GB 我想使用RDD缓存来避免冗余计算,但也希望避免不必要的SerDes和磁盘IO。
我的问题是,如果我没有按ds1
行显示//ds1.persist()
,那么当应用ds1
时,会激活app重新计算ds1 -> ds2
}?
谢谢!
答案 0 :(得分:0)
你有几个选择,从快速和昂贵到慢和便宜:
df.persist(MEMORY_ONLY)
将数据帧缓存到群集的RAM中。如果你有足够的记忆,速度会很快。在AWS定价模型更改为每秒后,成为一个很好的选择。缺点:如果你有一个复杂的管道,你在现场实例上运行,一个实例的失败会导致整个计算失败。df.persist(MEMORY_AND_DISK)
速度较慢,但仍然是一个很好的选择,因为数据缓存到Spark执行程序的本地存储。它与选项1具有相同的缺点。注意,在选项3中,您必须保存然后加载新的数据帧以剪切计算图。
答案 1 :(得分:0)
如果我正确理解了问题,除d2(the final result)
之上的操作外,其他任何操作都没有。由于火花变换是懒惰的,除非遇到动作,否则先前的RDD将不会实现。回答你的问题:
如果我没有按照行所示持续使用ds1 //ds1.persist(),会激活app在计算时重新计算ds1 ds1 - > DS2?
即使您正在缓存/持久ds1
,在ds2
计算/区分之前,它也不会计算。所以ds1
不是"重新计算",因为它是第一次计算。
您的处理可以是:
1)ds -> ds1
2)ds1 -> ds2
3)ds2.cache()
4)ds2.count //your first action. at this point ds1 & ds2 will be computed & cached
5)ds2.distinct // will not compute ds1 & ds2 again as its cached previously.
6)ds2.write.save(...) // assuming you are not storing d2 directly but after some transformation/action on top of d2. if you just want to save d2, then do write.save(..) on line 3 instead.