我正在运行一个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时,我注意到在dataframes
到fastutil collection objects
的初始转换完成后没有任何活动(这在作业启动后仅需几分钟)。我看到代码中使用的count
和collect
语句生成新作业,直到转换完成。之后,比较运行时不会启动任何新作业。
这意味着什么?这是否意味着分布式处理 根本不发生?
我知道集合对象不被视为RDD,可以 这就是原因吗?
如何在不使用资源的情况下执行我的程序 分配
任何帮助将不胜感激,谢谢!
答案 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;改变。