按字段將數據分區爲預定義分區計數的最佳方式是什麼?什麼是按列分區但保持固定分區數的有效方式?
我目前通過指定partionCount = 600來分區數據。發現計數600可爲我的數據集/羣集設置提供最佳查詢性能。
val rawJson = sqlContext.read.json(filename).coalesce(600)
rawJson.write.parquet(filenameParquet)
現在我想通過列「eventName的」分區此數據,但仍然保持計數600的數據,目前約有2000獨特eventNames,加上各eventName的行數不統一。大約10個eventNames有超過50%的數據導致數據傾斜。因此,如果我像下面那樣進行分區,那麼它不是很高效。寫入時間比沒有寫入多5倍。
val rawJson = sqlContext.read.json(filename)
rawJson.write.partitionBy("eventName").parquet(filenameParquet)
什麼是這些方案的數據分區的好方法?有沒有辦法通過eventName進行分區,但將其分散到600個分區中?
我的模式是這樣的:
{
"eventName": "name1",
"time": "2016-06-20T11:57:19.4941368-04:00",
"data": {
"type": "EventData",
"dataDetails": {
"name": "detailed1",
"id": "1234",
...
...
}
}
}
謝謝!
感謝Sim的細節。 – vijay
如果重新分區是通過計算列(eventName的映射)完成的,那麼通過eventName(即WHERE eventName ==「foo」)篩選的查詢仍然只能讀取相關分區而不執行全表掃描,因爲它現在不再是eventName分區了? – vijay
只有在完全過濾分區列時,纔會發生最有效的加載。如果您的偏差在一段時間內保持穩定,則使用靜態映射(無論它可能是什麼;不一定是列表桶),並在查詢過程中應用相同的功能。如果您的偏差隨時間推移不穩定,則需要隨時間分別維護事件到分區映射的數據結構,在您正在查詢的時間段內進行聯合,並通過分區列對兩者進行過濾(以有效減少分區)和事件名稱(專注於分區)。 – Sim