Scala Spark不允许我计算加入的数据帧

Scala Spark不允许我计算加入的数据帧,scala,apache-spark,spark-dataframe,Scala,Apache Spark,Spark Dataframe,我是Spark Jobs的新手,我有以下问题 当我对任何新加入的数据帧进行计数时,作业会运行很长时间并将内存溢出到磁盘。这里有逻辑错误吗 // pass spark configuration val conf = new SparkConf() .setMaster(threadMaster) .setAppName(appName) // Create a new spark context val sc = new SparkCon

我是Spark Jobs的新手,我有以下问题

当我对任何新加入的数据帧进行计数时,作业会运行很长时间并将内存溢出到磁盘。这里有逻辑错误吗

    // pass spark configuration
    val conf = new SparkConf()
      .setMaster(threadMaster)
      .setAppName(appName)

    // Create a new spark context
    val sc = new SparkContext(conf)

    // Specify a SQL context and pass in the spark context we created
    val sqlContext = new org.apache.spark.sql.SQLContext(sc)


    // Create three dataframes for sent and clicked files. Mark them as raw, since they will be renamed
    val dfSentRaw = sqlContext.read.parquet(inputPathSent)
    val dfClickedRaw = sqlContext.read.parquet(inputPathClicked)
    val dfFailedRaw  = sqlContext.read.parquet(inputPathFailed)



    // Rename the columns to avoid ambiguity when accessing the fields later
    val dfSent = dfSentRaw.withColumnRenamed("customer_id", "sent__customer_id")
      .withColumnRenamed("campaign_id", "sent__campaign_id")
      .withColumnRenamed("ced_email", "sent__ced_email")
      .withColumnRenamed("event_captured_dt", "sent__event_captured_dt")
      .withColumnRenamed("riid", "sent__riid")


    val dfClicked = dfClickedRaw.withColumnRenamed("customer_id", "clicked__customer_id")
      .withColumnRenamed("event_captured_dt", "clicked__event_captured_dt")
    val dfFailed = dfFailedRaw.withColumnRenamed("customer_id", "failed__customer_id")


    // LEFT Join with CLICKED on two fields, customer_id and campaign_id
    val dfSentClicked = dfSent.join(dfClicked, dfSent("sent__customer_id") === dfClicked("clicked__customer_id")
      && dfSent("sent__campaign_id") === dfClicked("campaign_id"), "left")
     dfSentClicked.count() //THIS WILL NOT WORK

val dfJoined = dfSentClicked.join(dfFailed, dfSentClicked("sent__customer_id") === dfFailed("failed__customer_id")
      && dfSentClicked("sent__campaign_id") === dfFailed("campaign_id"), "left")
为什么不能再计算这两个/三个数据帧?我是不是因为重命名而搞砸了索引

谢谢大家!


调用
count
是您的Spark作业在这里的唯一实际实现,因此这不是一个真正的
count
问题,而是在它之前对
连接所做的洗牌。您没有足够的内存来执行连接而不会溢出到磁盘。在一次洗牌中溢出到磁盘是一种非常简单的方法,可以让您的Spark作业永远持续下去=)

真正有助于防止洗牌溢出的一件事是拥有更多的分区。然后,在任何给定时间,通过洗牌移动的数据都会减少。您可以设置
spark.sql.shuffle.partitions
,它控制spark-sql在连接或聚合中使用的分区数。它默认为200,因此您可以尝试更高的设置

通过增加
Spark.shuffle.memoryFraction
(默认值为0.4)和减少
Spark.storage.memoryFraction
(默认值为0.6),您可以增加本地Spark分配的堆大小和/或增加可用于洗牌的内存部分。例如,当您进行
.cache
调用时,会使用存储分数,您可能对此并不在意


如果您倾向于完全避免溢出,可以通过将
spark.shuffle.spill
设置为
false
来关闭溢出。我相信,如果您的内存不足,需要溢出而不是一直默默等待,这将引发异常,并可以帮助您更快地配置内存分配。

几个问题:您看到的错误是什么?您是否尝试过对预联接数据帧进行计数?您是否尝试过跨不同数据帧合并列名并调用此联接(
join(right:DataFrame,usingColumns:Seq[String],joinType:String)
)?1。这并不是真正的错误,我只是觉得这个作业会永远运行并溢出(“UnsafeeExternalSorter将内存溢出到磁盘”)2。是的,计数工作-预加入3。我不明白这一点,我做了什么不同?非常感谢你的帮助!数据的大小是多少?您的集群内存配置是什么?我在32 GB机器上本地运行intelliJ和xmx2048m(应该提到这一点)。数据是集群上的数据的子集。大约1GB。