如何比较两个数据集?

时间:2018-03-07 02:44:25

标签: scala apache-spark fastutil

我正在运行一个spark应用程序,它从几个hive表(IP地址)中读取数据,并将数据集中的每个元素(IP地址)与来自其他数据集的所有其他元素(IP地址)进行比较。最终结果将是:

+---------------+--------+---------------+---------------+---------+----------+--------+----------+
|     ip_address|dataset1|dataset2       |dataset3       |dataset4 |dataset5  |dataset6|      date|
+---------------+--------+---------------+---------------+---------+----------+--------+----------+
| xx.xx.xx.xx.xx|     1  |              1|              0|        0|         0|      0 |2017-11-06|
| xx.xx.xx.xx.xx|     0  |              0|              1|        0|         0|      1 |2017-11-06|
| xx.xx.xx.xx.xx|     1  |              0|              0|        0|         0|      1 |2017-11-06|
| xx.xx.xx.xx.xx|     0  |              0|              1|        0|         0|      1 |2017-11-06|
| xx.xx.xx.xx.xx|     1  |              1|              0|        1|         0|      0 |2017-11-06|
---------------------------------------------------------------------------------------------------

为了进行比较,我将dataframes语句生成的hiveContext.sql("query")转换为Fastutil个对象。像这样:

val df= hiveContext.sql("query")
val dfBuffer = new it.unimi.dsi.fastutil.objects.ObjectArrayList[String](df.map(r => r(0).toString).collect())

然后,我使用iterator迭代每个集合,并使用FileWriter将行写入文件。

val dfIterator = dfBuffer.iterator()
while (dfIterator.hasNext){
     val p = dfIterator.next().toString
     //logic
}

我正在使用--num-executors 20 --executor-memory 16g --executor-cores 5 --driver-memory 20g

运行该应用程序

该过程总共持续约18-19小时,约有4-5百万条记录,每天进行一对一比较。

但是,当我检查Application Master UI时,我注意到在dataframesfastutil collection objects的初始转换完成后没有任何活动(这在作业启动后仅需几分钟)。我看到代码中使用的countcollect语句生成新作业,直到转换完成。之后,比较运行时不会启动任何新作业。

  • 这意味着什么?这是否意味着分布式处理 根本不发生?

  • 我知道集合对象不被视为RDD,可以 这就是原因吗?

  • 如何在不使用资源的情况下执行我的程序 分配

任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:8)

行后:

val dfBuffer = new it.unimi.dsi.fastutil.objects.ObjectArrayList[String](df.map(r => r(0).toString).collect())

电除尘器。上述部分内容:

df.map(r => r(0).toString).collect()

collect是最重要的事情,dfBuffer(这是一个常规的本地JVM数据结构)不会执行任何Spark作业。

  

这是否意味着分布式处理根本没有发生?

正确。 collect将所有数据放在驱动程序运行的单个JVM上(这正是您不应该这样做的原因,除非......您知道自己在做什么以及它可能导致什么问题)。

我认为以上回答了所有其他问题。

比较两个数据集(以Spark和分布式方式)比较问题的一种可能解决方案是join一个带参考数据集和count的数据集,以比较记录数是否为&# 39;改变。