我正在创建一个像这样的单个RDD 2.csv文件
val combineRDD = sc.textFile("D://release//CSVFilesParellel//*.csv")
然后我想在这个RDD上定义自定义分区,这样一个分区必须包含一个文件。 这样每个分区即一个csv文件在一个节点上处理,以便更快地进行数据处理
是否可以根据文件大小或一个文件中的行数或一个文件的文件末尾字符编写自定义分区程序?
我如何实现这一目标?
一个文件的结构如下所示:
00-00
时间(秒)测量1测量2测量3 .....测量
0
0.25
0.50
0.75
1
...
3600
1.第一行数据包含小时:分钟 每个文件包含1小时或3600secs的数据
2.第一列是第二列,分为4个部分,每部分250毫秒,数据记录250毫秒
对于我想要添加小时数的每个文件:分钟到秒,以便我的时间看起来像这个小时 - 分钟 - 秒。但问题是,我不希望这个过程顺序发生
我使用for-each函数获取每个文件名 - >然后在文件中创建数据的RDD并添加上面指定的时间。
但我想要的是每个文件应该转到一个节点进行处理和计算时间,而不是一个文件中的数据分布在节点之间计算时间。
谢谢。
此致
Vinay Joglekar
答案 0 :(得分:1)
让我们回到基础。
Gzip不可拆分会强制一个文件进入一个分区,但这绝不会有助于anyKind吞吐量增加
编写自定义输入格式从FileInputFormat扩展并提供splitlogic和recordReader逻辑。
要在spark中使用自定义输入格式,请按照
http://bytepadding.com/big-data/spark/combineparquetfileinputformat/
答案 1 :(得分:0)
简单的回答,而不会质疑你为什么要这样做。单独加载文件,以便知道正在加载的文件名
// create firstRDD containing a new attribute `filename=first.csv`
val firstRDD = sc.textFile("D://release//CSVFilesParellel//first.csv")
.map(line => new CsvRecord(line))
// create secondRDD containing a new attribute `filename=second.csv`
val secondRDD = sc.textFile("D://release//CSVFilesParellel//second.csv")
.map(line => new CsvRecord(line))
// now create a pair RDD and re-partition on the filename
val partitionRDD = firstRDD.union(secondRDD)
.map(csvRecord => (csvRecord.filename,csvRecord))
.partitionBy(customFilenamePartitioner)
的以下引用
要实现customFilenamePartitioner,您需要子类化 org.apache.spark.Partitioner类和实现三种类型 方法:
NumPartitions:Int,返回根据要求创建的分区数。
getPartition(key:Any):Int,返回分区ID范围 对于给定的键,从(0到numPartitions-1)。
equals(),:标准的Java编程相等方法。这是 很重要,因为Spark应用程序需要测试 您的Partitioner对象通过其自己的术语对其他实例 它决定你的两个RDD是否以与它相同的方式进行分区 是必需的。
请记住,重新分区很可能会触发昂贵的随机播放,因此,除非您要反复查询这个新分区的RDD,否则您最好以另一种方式解决问题。