按字段将数据分区为预定义分区计数的最佳方式是什么?什么是按列分区但保持固定分区数的有效方式?
我目前通过指定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