如何提高文件阅读量

时间:2018-06-14 08:28:59

标签: scala apache-spark apache-spark-sql

我正在尝试改进spark-sql中的进程。我有两个批处理过程,一个输出是第二个输入,我需要它们分割。

我的第一个进程中有一个表,通过加载的密钥使用spark-sql进行分区,如果我将其保存在数据存储区中,则火花会松开跟踪用于此表的哈希值。后来我需要在其他进程中加载​​这些数据,并与其他数据进行一些连接,这个连接从其他进程加载的数据的密钥将与前一个进程相同。在这种情况下,火花加载数据,但由于缺乏用于持久化的散列的知识,它将重做洗牌以将数据放入预期的spark-sql分区。 由于sql分区的数量在两个进程中是相同的,因此密钥也是相同的,我认为最后一次洗牌是可以避免的,但我不知道如何。

在简历中,我想知道一种方法来保存hdfs数据存储区中的数据,以一种方式可以保存由键放置的spark-sql的HashPartition,以改善后续读取,避免第一次洗牌。或者用更少的话说。 我想读取一个分区表,关注表中分区键的跟踪,以避免混乱。

我想做的伪代码:

val path = "/home/data"
ds.repartition(col("key")).write.parquet(path)
//in other spark-sql process
sparkSession.read.parquet(path).repartition(col("key")) 
//i know i need this last repartition
//but how could i make it as much efficient as i could

1 个答案:

答案 0 :(得分:0)

基本上,您希望将分区数据集保留到HDFS。然后,如果您阅读它,spark将考虑它被分区以进行进一步处理的方式。 例如,假设您有以下数据框:

val df = sc.parallelize(
      Seq(1 -> 3, 1 -> 4, 2 -> 5, 
      2->7, 1->10, 2->7, 3->67, 
      3->89, 3->7)).toDF("A", "B")

然后让我们尝试一个小组:

df.groupBy("A").agg(count(lit(1)) as "C").explain
== Physical Plan ==
*HashAggregate(keys=[A#41], functions=[count(1)])
+- Exchange hashpartitioning(A#41, 200)
   +- *HashAggregate(keys=[A#41], functions=[partial_count(1)])
      +- *Project [_1#38 AS A#41]
         +- *SerializeFromObject [assertnotnull(input[0, scala.Tuple2, true])._1 AS _1#38, assertnotnull(input[0, scala.Tuple2, true])._2 AS _2#39]
            +- Scan ExternalRDDScan[obj#37]

Exchange hashpartitioning(A#41, 200)行告诉你将会有一些洗牌。

现在,如果您将数据保留在磁盘上:

df
    .write
    .partitionBy("key")
    .parquet("hdfs:///path/dataset")

然后,如果您阅读并尝试通过以下方式执行分组:

spark.read.parquet("data.parquet").agg(count(lit(1)) as "C").explain
== Physical Plan ==
*HashAggregate(keys=[], functions=[count(1)])
    +- Exchange SinglePartition
       +- *HashAggregate(keys=[], functions=[partial_count(1)])
          +- *Project
             +- *FileScan parquet [A#78] Batched: true, Format: Parquet, Location: InMemoryFileIndex[file:/home/olivier/data.parquet], PartitionCount: 3, PartitionFilters: [], PushedFilters: [], ReadSchema: struct<>

Exchange SinglePartition告诉您不会执行任何随机播放。

您也可以根据&#34; A&#34;如果你不需要所有数据,那么Spark就不必加载它不需要的数据。有关详细信息,请参阅Reading DataFrame from partitioned parquet file

相关问题