Apache Spark页面在大型数据集上生成或查看结果

时间:2018-04-24 12:18:33

标签: apache-spark hive

我正在使用Hive with Spark 1.6.3

我有一个大型数据集(40000行,20列左右,每列包含500字节--3KB数据)

查询是3个数据集的连接

我希望能够分页最终的连接数据集,并且我发现我可以使用row_number() OVER (ORDER BY 1)为数据集中的每一行生成唯一的行号。

在此之后我可以做到

SELECT * FROM dataset WHERE row between 1 AND 100

但是,有些资源建议不要使用ORDER BY,因为它将所有数据放入1个分区(我可以看到在shuffle分配将数据移动到一个分区的日志中就是这种情况),当发生这种情况时,我会遇到内存异常。

我如何以更有效的方式浏览数据集?

我启用了persist - MEMORY_AND_DISK,这样如果分区太大,它就会溢出到磁盘上(对于某些转换,我可以看到至少有一些数据溢出到磁盘上,当我不使用row_number()

2 个答案:

答案 0 :(得分:0)

好吧,您可以在最终的联接数据框中应用this method

您还应该将数据帧保留为文件以保证排序,因为重新评估可能会创建different order

答案 1 :(得分:0)

一种策略可以是首先仅选择数据集的unique_key,并仅对该数据集应用row_number函数。由于您从大型数据集中选择单个列,因此它很可能适合单个分区。

val dfKey = df.select("uniqueKey")
dfKey.createOrUpdateTempTable("dfKey")
val dfWithRowNum = spark.sql(select dfKey*, row_number() as row_number OVER (ORDER BY 1))
// save dfWithRowNum

完成uniqueKey上的row_number操作后;保存该数据帧。现在在下一阶段将此数据帧与更大的数据帧连接,并将row_number列附加到该数据帧。

dfOriginal.createOrUpdateTempTable("dfOriginal")
dfWithRowNum.createOrUpdateTempTable("dfWithRowNum")
val joined = spark.sql("select dfOriginal.* from dfOriginal join dfWithRowNum on dfOriginal.uniqueKey = dfWithRowNum.uniqueKey")
// save joined

现在您可以查询

SELECT * FROM joineddataset WHERE row between 1 AND 100

对于MEMORY_DISK的持久性,我发现偶尔因内存不足而失败。我宁愿使用DISK_ONLY,虽然执行得到保证,但性能会受到惩罚。