在我的R脚本中,我有两列(时间,值)SparkDataFrame
,其中包含四个不同月份的数据。由于我需要将我的函数分别应用于每个月,我想我会repartition
将它分成四个分区,每个分区中的每个分区都会保存一个月的数据。
我创建了一个名为partition的附加列,其整数值为0 - 3,之后通过此特定列调用repartition
方法。
可悲的是,正如本主题中所描述的那样:
Spark SQL - Difference between df.repartition and DataFrameWriter partitionBy?,使用repartition
方法,我们只能确保具有相同密钥的所有数据都将在同一个分区中结束,但具有不同密钥的数据也可能最终位于同一分区中。 / p>
在我的情况下,执行下面显示的代码会导致创建4个分区,但只填充其中2个分区。
我想我应该使用partitionBy
方法,但是在SparkR的情况下,我不知道如何做到这一点。
官方文档指出此方法适用于名为WindowSpec
而非DataFrame
的内容。
我真的很感激这方面的帮助,因为我不知道如何将这种方法融入我的代码中。
sparkR.session(
master="local[*]", sparkConfig = list(spark.sql.shuffle.partitions="4"))
df <- as.DataFrame(inputDat) # this is a dataframe with added partition column
repartitionedDf <- repartition(df, col = df$partition)
schema <- structType(
structField("time", "timestamp"),
structField("value", "double"),
structField("partition", "string"))
processedDf <- dapply(repartitionedDf,
function(x) { data.frame(produceHourlyResults(x), stringsAsFactors = FALSE) },
schema)
答案 0 :(得分:3)
你使用的是错误的方法。如果你
需要将我的功能分别应用于每个月
你应该使用gapply
那个
使用指定的列对SparkDataFrame进行分组,并将R函数应用于每个组。
df %>% group_by("month") %>% gapply(fun, schema)
或
df %>% gapply("month", fun, schema)
在我的情况下,执行下面显示的代码会导致创建4个分区,但只填充其中2个分区。
这表明哈希冲突。合理地增加唯一键数量以上的分区数应该可以解决问题:
spark.sql.shuffle.partitions 17
我想我应该使用partitionBy方法,但是
没有。 partitionBy
与window functions(SparkR window function)一起使用。
解决your comment:
我决定使用dapply与单独的分区,以便能够轻松地将每个月保存到单独的CSV文件中
哈希分区程序不像How does HashPartitioner work?
那样工作您可以在编写器中尝试使用partitionBy
,但我不确定它是否在SparkR中直接支持。它在结构化流中受支持,对于批处理,您可能必须调用Java方法或使用带有Metastore的表:
createDataFrame(iris) %>% createOrReplaceTempView("iris_view")
sql(
"CREATE TABLE iris
USING csv PARTITIONED BY(species)
LOCATION '/tmp/iris' AS SELECT * FROM iris_view"
)