使用spark和scala进行连接计数时获得性能的最佳方法

使用spark和scala进行连接计数时获得性能的最佳方法,scala,join,apache-spark,spark-dataframe,query-performance,Scala,Join,Apache Spark,Spark Dataframe,Query Performance,我需要验证摄取操作,基本上,我在HDFS中有两个大文件,一个是avro格式的(摄取文件),另一个是拼花格式的(合并文件) Avro文件具有以下架构: 文件名、日期、计数、afield1、afield2、afield3、afield4、afield5、afield6、…afieldN 拼花地板文件具有以下架构: 文件名,另一个字段1,另一个字段1,另一个字段2,另一个字段3,另一个字段14,…,另一个字段n 如果我尝试在一个数据帧中加载这两个文件,然后尝试在其中使用一个简单的连接,那么本地机器中的

我需要验证摄取操作,基本上,我在HDFS中有两个大文件,一个是avro格式的(摄取文件),另一个是拼花格式的(合并文件)

Avro文件具有以下架构:

文件名、日期、计数、afield1、afield2、afield3、afield4、afield5、afield6、…afieldN

拼花地板文件具有以下架构:

文件名,另一个字段1,另一个字段1,另一个字段2,另一个字段3,另一个字段14,…,另一个字段n

如果我尝试在一个数据帧中加载这两个文件,然后尝试在其中使用一个简单的连接,那么本地机器中的作业将花费超过24小时!,这是无法接受的

ingestedDF.join(consolidatedDF).where($"filename" === $"fileName").count()
?实现这一目标的最佳方式是什么??在进行连接计算之前从数据帧中删除列??计算每个数据帧的计数,然后求和

PD

我正在阅读有关地图侧关节技术的文章,但是如果有一个小文件可以放入RAM,那么这项技术对我来说是可行的,但是我不能保证,因此,我想知道社区更喜欢哪种方法来实现这一点


我将通过将数据剥离到我感兴趣的字段(
filename
)来解决这个问题,从而生成一组具有源文件名的唯一文件名(原始数据集)。 此时,两个中间数据集具有相同的模式,因此我们可以合并它们并进行计数。这应该比在完整数据上使用
join
快几个数量级

// prepare some random dataset
val data1 = (1 to 100000).filter(_ => scala.util.Random.nextDouble<0.8).map(i => (s"file$i", i, "rubbish"))
val data2 = (1 to 100000).filter(_ => scala.util.Random.nextDouble<0.7).map(i => (s"file$i", i, "crap"))

val df1 = sparkSession.createDataFrame(data1).toDF("filename", "index", "data")
val df2 = sparkSession.createDataFrame(data2).toDF("filename", "index", "data")

// select only the column we are interested in and tag it with the source.
// Lets make it distinct as we are only interested in the unique file count
val df1Filenames = df1.select("filename").withColumn("df", lit("df1")).distinct
val df2Filenames = df2.select("filename").withColumn("df", lit("df2")).distinct

// union both dataframes
val union = df1Filenames.union(df2Filenames).toDF("filename","source")

// let's count the occurrences of filename, by using a groupby operation
val occurrenceCount = union.groupBy("filename").count

// we're interested in the count of those files that appear in both datasets (with a count of 2)
occurrenceCount.filter($"count"===2).count
//准备一些随机数据集
val data1=(1到100000).filter(=>scala.util.Random.nextDouble(s“file$i”,i,“垃圾”))
val data2=(1到100000).filter(=>scala.util.Random.nextDouble(s“file$i”,i,“crap”))
val df1=sparkSession.createDataFrame(data1.toDF(“文件名”、“索引”、“数据”)
val df2=sparkSession.createDataFrame(data2.toDF(“文件名”、“索引”、“数据”)
//只选择我们感兴趣的列,并用源标记它。
//让我们把它区分开来,因为我们只对唯一的文件计数感兴趣
val df1Filenames=df1.select(“filename”).withColumn(“df”,lit(“df1”)).distinct
val df2Filenames=df2.select(“filename”).withColumn(“df”,lit(“df2”)).distinct
//联合两个数据帧
val union=df1Filenames.union(df2Filenames.toDF(“文件名”,“源”)
//让我们使用groupby操作来计算filename的出现次数
val occurrenceCount=union.groupBy(“文件名”).count
//我们对两个数据集中出现的文件的数量感兴趣(数量为2)
occurrenceCount.filter($“count”==2).count

难道你不能计算每个数据帧的计数,然后求和吗?我想我可以,@mtoto,但是,首先,我想知道实现这一点的最佳方法是什么。实际上,为了知道数字,我已经运行了以下语句ingestedDF.join(consolidatedDF).where($“filename”==$“filename”).count()。工作完成后,我会试试你的建议。?您应该如何编写代码?不确定问题是什么:您是否只想知道两个数据集中通用文件名的计数?或者区别?两个数据集中的公共文件名的计数,以一种有效的方式。两个数据集中的文件名是唯一的吗?我必须证明这一点。我将发布我的原始解决方案(尚未完成)中与您的解决方案相对应的数字。@aironman也可以在笔记本中看到它:拜托,这不是信任与否的问题,而是用我的数据进行测试的问题。谢谢你的帮助,我会在工作完成后发布数据。hi@maasg。早上好,在我的本地机器(i7 2.5 GHZ 16GB RAM osx 10,12.2)中执行此查询:ingestedDF.join(consolidatedDF).where($“filename”====$“filename”).count()需要两天时间!结束。在你的帮助下,103秒…:)令人惊讶和印象深刻。谢谢你,伙计!我跟你学了很多,太好了!我是黛比·拉塞维扎:-)