Scala 在按列分区将数据帧写入CSV时,如何保持数据帧的顺序?
我对Scala 在按列分区将数据帧写入CSV时,如何保持数据帧的顺序?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我对数据帧的行进行排序,并将其写入磁盘,如下所示: df. orderBy("foo"). write. partitionBy("bar", "moo"). option("compression", "gzip"). csv(outDir) 当我查看生成的.csv.gz文件时,它们的顺序没有保留。Spark就是这样做的吗?在使用分区将DF写入磁盘时,有没有办法保持顺序 编辑:更准确地说:不是CSV的顺序是关闭的,而是它们内部的顺序。假设我在df.orderBy之后有如下
数据帧的行进行排序,并将其写入磁盘,如下所示:
df.
orderBy("foo").
write.
partitionBy("bar", "moo").
option("compression", "gzip").
csv(outDir)
当我查看生成的.csv.gz文件时,它们的顺序没有保留。Spark就是这样做的吗?在使用分区将DF写入磁盘时,有没有办法保持顺序
编辑:更准确地说:不是CSV的顺序是关闭的,而是它们内部的顺序。假设我在df.orderBy
之后有如下内容(为简单起见,我现在只按一列进行分区):
我希望是这样的,例如,对于文件夹bar=1
中的文件:
第00000部分-NNN.csv.gz:
1,1
1,3
2,5
3,8
4,10
1,1
2,5
1,3
4,10
3,8
第00001部分-NNN.csv.gz:
1,1
1,3
2,5
3,8
4,10
1,1
2,5
1,3
4,10
3,8
但它是什么样的:
第00000部分-NNN.csv.gz:
1,1
1,3
2,5
3,8
4,10
1,1
2,5
1,3
4,10
3,8
第00001部分-NNN.csv.gz:
1,1
1,3
2,5
3,8
4,10
1,1
2,5
1,3
4,10
3,8
已经有一段时间了,但我再次目睹了这一切。我终于找到了解决办法
假设您的模式如下所示:
- 时间:bigint
- 频道:字符串
- 价值:双倍
如果您这样做:
df.sortBy("time").write.partitionBy("channel").csv("hdfs:///foo")
df.sortBy("channel", "time").write.partitionBy("channel").csv("hdfs:///foo")
单个部分-*
文件中的时间戳会被丢弃
如果您这样做:
df.sortBy("time").write.partitionBy("channel").csv("hdfs:///foo")
df.sortBy("channel", "time").write.partitionBy("channel").csv("hdfs:///foo")
顺序是正确的
我认为这与洗牌有关。因此,作为一种解决方法,我现在先按我希望数据分区的列进行排序,然后按我希望在各个文件中对数据进行排序的列进行排序。您使用的是哪一个spark版本?我正在使用2.3.1。这个周末我也将尝试使用。这里有“扣球”。但通常情况下,一旦阅读,您将得到一个拆分,并需要始终重新分区以确保。哈希与RangeBy?有趣的东西会引起混乱,然后在过去与配置单元兼容。该任务的结果用于.net应用程序,该应用程序将数据读回并使用FILESTREAM列将其放入MSSQL数据库(这是第三方的要求)。由于每个文件夹都是一个接一个地读取的,而且所有CSV组合中的条目都不会超过600000个,因此我目前将所有内容读取到内存中并重新排序。对于这种特殊情况,这是可以容忍的,但如果能更多地了解正在发生的事情,那就太好了。