使用Spark Streaming + Kafka在HDFS中清空文件夹

时间:2016-03-08 23:55:03

标签: scala apache-spark hdfs spark-streaming

我正在使用Spark Streaming + Kafka将数据提取到HDFS中。

val ssc = new StreamingContext(sparkContext, Seconds(30))
val messageRecBased = KafkaUtils.createStream(ssc, zkQuorum, group, topic)
  .map(_._2)

每30秒,Kafka队列中的所有数据都将存储在HDFS的单独文件夹中。某些文件夹包含一个名为part-00000的空文件,因为相应的批处理间隔(30秒)内没有数据。 我使用以下行来过滤这些文件夹:

messageRecBased.filter { x => x.size == 0 }
messageRecBased.repartition(1).saveAsTextFiles("PATH")

但它不起作用,它仍然会生成带有空文件的文件夹。

3 个答案:

答案 0 :(得分:1)

如果您查看DStream.saveAsTextFiles()方法定义,它只会向RDD.saveAsObjectFile中的每个RDD生成DirectKafkaInputDStream

  def saveAsObjectFiles(prefix: String, suffix: String = ""): Unit = ssc.withScope {
    val saveFunc = (rdd: RDD[T], time: Time) => {
      val file = rddToFileName(prefix, suffix, time)
      rdd.saveAsObjectFile(file)
    }
    this.foreachRDD(saveFunc)
  }

因此,您可以选择编写自己喜欢的内容,而不是使用DStream.saveAsTextFiles()

messageRecBased.foreachRDD{ rdd =>
    rdd.repartition(1)
    if(!rdd.isEmpty)
        rdd.saveAsObjectFile("FILE_PATH")
}

答案 1 :(得分:0)

您可以检查分区是否为空,如果不是,则只保存RDD,如下所示。此代码应防止空RDD保存。

messageRecBased.partitions.isEmpty

答案 2 :(得分:0)

这就是我创建新目录并避免空批处理的方式。

import java.time.format.DateTimeFormatter
import java.time.LocalDateTime

   messageRecBased.foreachRDD{ rdd =>
        rdd.repartition(1)
        val eachRdd = rdd.map(record => record.value)
        if(!eachRdd.isEmpty)
          eachRdd.saveAsTextFile("hdfs/location/"+DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now)+"/")
      }