用null替换空字符串会导致数据帧大小增加?

时间:2017-11-20 10:47:39

标签: apache-spark spark-dataframe

我无法理解以下现象:在Spark 2.2中,在Scala上,我看到用lit(null)替换文字空字符串值后持久化DataFrame大小的显着增加。

这是我用来替换空字符串值的函数:

def nullifyEmptyStrings(df:DataFrame): DataFrame = {
    var in = df
    for (e <- df.columns) {
         in = in.withColumn(e, when(length(col(e))===0, lit(null:String)).otherwise(col(e)))
     }
    in
  }

我观察到在运行此函数之前我的初始数据帧的持久(DISK_ONLY)大小是1480MB,之后是1610MB。分区数保持不变。

有什么想法?顺便说一下,归零工作正常,但我引入这个的主要原因是减少了随机播放的大小,似乎我只是这样增加它。

2 个答案:

答案 0 :(得分:2)

我自己会回答这个问题,因为我们现在已经做了一些可能有用的调查。

测试具有完全String列的大型(数百万行)DataFrames,我们观察到将空字符串替换为空值会导致在S3(1.1-1.5%)上序列化为镶木地板时整体磁盘占用空间略有减少。

但是,MEMORY_ONLY或DISK_ONLY缓存的数据帧分别增加了6%和8%。我只能推测当Column是StringType时,Spark是如何在内部表示NULL值的......但无论它是什么,它都比空字符串大。如果有任何方法可以检查,我会很高兴听到它。

这种现象在PySpark和Scala中是相同的。

我们使用null的目的是减少复杂连接操作中的shuffle大小。总的来说,我们经历了相反的情但是我们将继续使用空值,因为isNotNull过滤器的自动下推使得在Spark SQL中编写连接更加清晰。

答案 1 :(得分:-2)

这里的结果相同。也许还应检查分区数,因为具有许多不同值的大分区可能将列存储为行字符串而不是字典。