场景
我们希望接收CSV文件(大约10 MB),这些文件存储在HDFS中。然后,该过程将向Kafka主题发送一条消息(该消息包含文件元数据,例如HDFS位置等)。
一个火花流作业会监听这个Kafka主题,在收到消息后,它应该从HDFS读取文件并处理该文件。
在上述情况下,从HDFS读取文件的最有效方法是什么?
从卡夫卡阅读
JavaInputStream<ConsumerRecord<String, FileMetaData>> messages = KafkaUtils.createDirectStream(...);
JavaDStream<FileMetaData> files = messages.map(record -> record.value());
选项1-使用平面地图功能
JavaDStream<String> allRecords = files.flatMap(file -> {
ArrayList<String> records = new ArrayList<>();
Path inFile = new Path(file.getHDFSLocation());
// code to read file from HDFS
return records;
});
选项2-使用foreachRDD
ArrayList<String> records = new ArrayList<>();
files.foreachRDD(rdd -> {
rdd.foreachPartition(part -> {
while(part.hasNext()) {
Path inFile = new Path(part.next().getHDFSLocation());
// code to read file from HDFS
records.add(...);
}
}
}
JavaRDD<String> rddRecords = javaSparkContext.sparkContext().parallize(records);
哪个选项更好? 另外,我应该使用spark上下文的内置方法从HDFS读取文件,而不是使用HDFS Path吗?
谢谢