scala - 有没有办法将 parquet 分区下的所有文件读取到单个 spark 分区上?
问题描述
数据以镶木地板格式存储。parquet 文件根据分区键列(用户 id 列的哈希值)进行分区
userData/
partitionKey=1/
part-00044-cf737804-90ea-4c37-94f8-9aa016f6953a.c000.snappy.parquet
part-00044-cf737804-90ea-4c37-94f8-9aa016f6953b.c000.snappy.parquet
partitionKey=2/
part-00059-cf737804-90ea-4c37-94f8-9aa016f6953a.c000.snappy.parquet
partitionKey=3/
part-00002-cf737804-90ea-4c37-94f8-9aa016f6953a.c000.snappy.parquet
给定分区方案,我们知道:
- 给定用户的所有数据都将属于同一分区
- 一个分区可以有多个用户的数据
在读取数据时,我希望 1 个用户的所有数据都落入同一个 spark 分区。一个 spark 分区可以有多个用户,但它应该包含所有这些用户的所有行。
目前,我使用的是: SparkSession.read.parquet("../userData").repartition(200, col("UserId"))
(也尝试了使用自定义分区器的 partitionBy;操作顺序:DataFrame -> RDD -> KeyedRDD -> partitionBy -> RDD -> DataFrame;在 partitionBy 之前,有一个反序列化到对象的步骤,这会爆炸 shuffle 写入)
有没有办法避免重新分区并利用输入文件夹结构将用户的数据放在单个分区上?
解决方案
SparkSession.read.parquet
应该根据您的文件路径自动推断分区信息。你可以在这里找到更多信息
如果您的文件路径是:
userData/
UserId=1/
part-00044-cf737804-90ea-4c37-94f8-9aa016f6953a.c000.snappy.parquet
part-00044-cf737804-90ea-4c37-94f8-9aa016f6953b.c000.snappy.parquet
UserId=2/
part-00059-cf737804-90ea-4c37-94f8-9aa016f6953a.c000.snappy.parquet
UserId=3/
part-00002-cf737804-90ea-4c37-94f8-9aa016f6953a.c000.snappy.parquet
当您调用SparkSession.read.parquet("/path/to/userData")
时,它将按UserId
.
推荐阅读
- javascript - 如何阻止 Apify 保存已处理的请求?
- r - 如何创建堆积条形图
- mysql - 此查询中我的 MySQL 语法有什么问题?
- boolean-algebra - 为什么在这张卡诺图中没有考虑 D 为常数的突出显示区域?
- shell - zsh shell 问题,特别是当我试图获取输出时
- flutter - 当我显示重叠元素时如何使我的页面可滚动,其中有太多的项目在颤动?
- node.js - DynamoDB BatchGet 总是给出“提供的关键元素与架构不匹配”
- python-3.x - 如何通过传入 True 或 False 变量来停止无限循环中的线程?
- excel - 在 For 循环中使用 MonthName 函数时出现运行时错误
- java - 如何在包含的 JSP 上访问请求属性