簡體   English   中英

Spark 2.3 Dataframe 分區-想要在n個分區的key上對數據進行分區

[英]Spark 2.3 Dataframe partition-want to partition data on key in n number of partition

我需要 spark(scala) 數據幀分區方面的幫助。 我需要通過一個鍵列分區成 n 個分區,與同一鍵相關的所有行都應該在同一個分區中(即鍵不應跨分區分布)

注意:我的密鑰可能有數百萬個

例如:假設我有以下數據框

在此處輸入圖片說明

等等

如您所見,許多值共享相同的鍵。 我想將此數據集划分為“n”個分區,其中相同的鍵應位於同一分區中,並且鍵不應跨分區分布。 多個鍵位於同一個分區中,並且鍵不可排序。

提前致謝

根據Spark - The Definitive Guide一書, Spark - The Definitive Guide有兩個內置分區器,一個用於離散值的HashPartitioner和一個RangePartitioner 兩者都適用於離散值和連續值。

示例 HashPartitioner:

import org.apache.spark.HashPartitioner

val rdd = df.rdd // convert DataFrame to low-level RDD
val keyedRDD = rdd.keyBy(...) // define your custom key
keyedRDD.partitionBy(new HashPartitioner(n))

示例分區器:

import org.apache.spark.Partitioner

class DomainParitioner extends Partitioner {
  def numPartitions = n
  def getPartition(key: Any): Int = {
    // your custome partition logic
  }
}

keyedRDD.partitionBy(new DomainPartitioner).map(_._1).glom().map(_.toSet.toSeq.length)

書中還提到你應該注意key skew ,這意味着某些鍵可能比其他鍵有很多很多的值。 您希望盡可能地打破這些鍵以提高並行性並防止在執行過程中出現OutOfMemoryErrors

您可以在將 DataFrame 寫入基於文件的輸出時對其進行分區。 就像是:

df.write.partitionBy("colName").format("parquet").save(path-to-file)

這將創建與您的目錄結構相同的目錄結構

path
└── to
    └── file
         ├── colName=value1
                       └── data.parquet
         ├── colName=value2
                       └── data.parquet

當您加載數據和過濾器時,謂詞將被下推到源文件,您可以獲得分區的性能優勢

這不是您要找的嗎?

嘗試

def repartition(partitionExprs: org.apache.spark.sql.Column*): org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] 

val df = Seq(("aa","vv"),("aa","v1v1"),("a1","v2")).toDF("Key","Value")
 val partionedDf = df.repartition(col("Key"))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM