当我的spark程序运行更多数据时,我想我崩溃了,因为我正在选择默认的用于聚合的输出分区数-即200。我已经学会了如何控制它,但是在理想情况下,我将根据我正在写入的数据量来设置输出分区的数量。难题就在这里-我需要先在数据帧上调用count()
,然后再调用write
。这意味着我可以从S3重新准备两次。我可以先cache
,然后再count
,但是当我缓存这些数据时,我已经看到火花崩溃,缓存似乎使用了最多的资源,而如果我只写它,它可以做得更好。
所以我的问题是,如果您认为这是一种不错的方法-首先进行计数(该计数是磁盘大小的代理),还是应该对一些数字进行硬编码,在需要时进行更改?而且,如果我要先算数,他们是否有一些聪明的方法来优化事物,以便算数和写共享工作?除了缓存整个数据帧以外?
答案 0 :(得分:1)
是的,计数方法实际上是正确的方法。理想情况下,在写入之前,您希望rdd分区的大小相当大,例如50MB。否则,您将遇到“小文件问题”。
现在,如果您在内存中拥有大量数据缓存,可能会很难。您可以尝试MEMORY_AND_DISK
,但随后数据将溢出到磁盘上并导致速度降低。
我多次面对这种困境,每次我为分区数选择一个“魔术数”。数字已参数化,因此当我需要更改时,不需要更改代码,而只需传递其他参数即可。
如果您知道数据大小通常在特定范围内,则可以设置硬编码的分区号。这不是理想的,但是可以完成工作。
您还可以在s3中抽取指标,例如数据大小,如果超出某个阈值,则会发出警报,然后有人可以手动更改分区号。
通常,对于大约500GB的数据,如果将分区号保持在适中的高度(例如5000),则适用于较大的范围,即300GB至1.2TB的数据量。这意味着,如果您有适度的数据流入,您可能不需要太频繁地更改分区号。