[英]Spark 2.3 Dataframe partition-want to partition data on key in n number of partition
根據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.