Spark:创建DataFrame所需的内存是否有点等于输入数据的大小?

Pro*_*707 3 apache-spark

我很难说我是否需要1TB的内存来加载基于1TB数据库表的Spark DataFrame.是这样的吗?

我被告知我在另一个问题中没有以非常火花的方式做事,因为我开始通过迭代创建DataFrames然后处理这些子集来分块数据.问题是这太慢了,因为没有足够的并行处理发生.然后根据反馈,我尝试加载一个整个表,然后使用Spark分区/分组/排序按我需要的顺序获取我需要的东西,但据我所知,它只是填满了尽可能多的内存因为我分配(在我的本地测试机器上),尽管有多达数千个分区(在我的情况下)是一个30GB的小型数据库表.

这让我很疯狂,因为我已经在过去的几周内完成了大量的搜索和阅读文章和文档,我很难找到使用Spark的实例访问我想做的事情的例子甚至称之为模糊的"大"数据集.特别是在涉及DataFrames并使用真实数据库作为输入时.另外得到反馈说我不应该手动分块任何数据让我觉得必须有一些神奇的事情发生,而不是所有数据实际上一次被选中.在这方面任何有用的资源将不胜感激.

Ind*_*ain 8

cache()在以下情况下,您绝对应该使用RDD和DataFrame:

  • 在迭代循环中重用它们
  • 在单个应用程序作业中多次重复使用RDD
  • 当再生RDD分区前期费用是昂贵的(即HDFS,一套复杂的后map(),filter()等)这有助于在恢复过程中如果工人节点死亡.

请记住,Spark将以LRU方式自动从Workers中驱逐RDD分区.LRU驱逐在每个Worker上独立发生,并取决于Worker中的可用内存.

在RDD的生命周期中,RDD分区可能存在于内存中或跨群集的磁盘上,具体取决于可用内存.

Spark UI上的"存储"选项卡显示在任何给定时间点跨群集存在的分区(内存或磁盘)的位置.

请注意,对于大于可用群集内存的数据集cache(),persist(StorageLevel.MEMORY_ONLY)这可能不是理想的别名.被驱逐出内存的每个RDD分区都需要从源(即HDFS,网络等)重建,这是昂贵的.

一个更好的解决方案是使用persist(StorageLevel.MEMORY_AND_DISK_ONLY)哪个将RDD分区溢出到Worker的本地磁盘,如果它们被从内存中逐出.在这种情况下,重建分区只需要从Worker的本地磁盘中提取相对较快的数据.

您还可以通过附加_SER来选择将数据保存为序列化字节数组,如下所示: MEMORY_SERMEMORY_AND_DISK_SER.这可以节省空间,但会产生额外的序列化/反序列化惩罚.而且因为我们将数据存储为序列化字节数组,所以创建的Java对象较少,因此GC压力降低.

Spark存储级别