在Spark中执行group by on RDD并将每个组写为单独的Parquet文件

时间:2016-02-16 23:21:18

标签: java apache-spark apache-spark-sql parquet

我的内存中有一个RDD。我想使用一些任意函数对RDD进行分组,然后将每个单独的组写为单独的Parquet文件。

例如,如果我的RDD由以下形式的JSON字符串组成:

{"type":"finish","resolution":"success","csr_id": 214}
{"type":"create","resolution":"failure","csr_id": 321}
{"type":"action","resolution":"success","csr_id": 262}

我想按"类型"对JSON字符串进行分组。属性,并用相同的"类型"写每组字符串;到同一个Parquet文件。

我可以看到DataFrame API允许按如下方式写出Parquet文件(例如,如果RDD由JSON字符串组成):

final JavaRDD<String> rdd = ...
final SQLContext sqlContext = SQLContext.getOrCreate(rdd.context());
final DataFrame dataFrame = sqlContext.read().json(rdd);
dataFrame.write().parquet(location);

这意味着将整个DataFrame写入Parquet文件,因此Parquet文件将包含具有不同值的记录,用于&#34;类型&#34;属性。

Dataframe API还提供了groupBy函数:

final GroupedData groupedData = dataFrame.groupBy(this::myFunction);

但GroupedData API似乎不提供将每个组写出到单个文件的任何功能。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

您无法编写GroupedData,但可以在write:

上对数据进行分区
dataFrame.write.partitionBy("type").format("parquet").save("/tmp/foo")

每种类型都将以${column}=${value}格式写入其自己的目录。这些可以单独加载:

sqlContext.read.parquet("/tmp/foo/type=action").show
// +------+----------+
// |csr_id|resolution|
// +------+----------+
// |   262|   success|
// +------+----------+