Spark Streaming 的saveAsTextFiles遇到的坑

使用sparkStreaming消费数据,并使用Dstream的 saveAsTextFile保存数据到hdfs中,通过使用这个方法,生成的文件夹存在问题,

代码例子如下:

    resultRdd.map(x=>x).saveAsTextFiles("hdfs:ip//data/storage/20181010/"+(new Date()))  //new Date()自行转化

    ssc.start()

    ssc.awaitermination()


而hsfs中目录显示为

   /data/storage/20181010/201810100708223-1547016648000

   /data/storage/20181010/201810100708223-1547016652000

   /data/storage/20181010/201810100708223-1547016658000

   .........................................


从中发现最后面多了一条横杠 -和时间戳1547016648000,是根据间隔时间自动生成的,但是我不想要他后面的-1547016648000,

并且201810100708223日期固定住了

查看saveAsTextFiles源码


def saveAsTextFiles(prefix: String, suffix: String = ""): Unit = ssc.withScope {

  val saveFunc = (rdd: RDD[T], time: Time) => {

    val file = rddToFileName(prefix, suffix,time)

    rdd.saveAsTextFile(file)

  }

  this.foreachRDD(saveFunc)

}

saveAsTextFiles方法中也是调用了saveAsTextFile方法,其中有个添加时间戳的方法。


于是我根据源码自己使用foreachRDD,生成文件使用saveAsTextFile


resultRdd.foreachRDD{

rdd=>{}

rdd.map(x=>x).saveAsTextFile("hdfs:ip//data/storage/20181010/"+(new Date()))  //new Date()自行转化

}



ssc.start()

ssc.awaitermination()


现在hsfs中目录显示为

   /data/storage/20181010/201810100708223

   /data/storage/20181010/201810100708460


达到自己想要的结果,根据streaming 间隔时间生成文件夹,并其中包含文件。

<think>嗯,用户问的是Spark Streaming中DStream的输出操作是否真正触发所有转换操作进行计算。我需要仔细回忆一下Spark Streaming的工作原理。 首先,Spark Streaming处理的是实时数据流,它将数据分成小批次,形成DStream。DStream上的转换操作和RDD的转换类似,分为转换(Transformation)和动作(Action)。在普通的Spark中,RDD的转换是惰性的,只有遇到动作操作时才会真正执行计算。那DStream的情况是不是一样呢? DStream的转换操作,比如map、filter这些,应该也是惰性的,也就是说它们只是记录了转换操作,但不会立即执行。而输出操作,比如print、saveAsTextFiles、foreachRDD这些,可能相当于动作操作,触发实际的计算。因为如果用户没有调用输出操作,Spark Streaming可能不会执行任何计算,毕竟系统不知道用户想要输出什么结果。 不过,我需要确认一下官方文档或者权威资料中的说法。比如,Spark的官方文档中提到,DStream的输出操作类似于RDD的Action,会触发整个DStream链条的执行。每个输出操作都会让系统处理数据并将结果输出到外部系统,这时候才会真正执行所有之前的转换操作。所以用户的问题应该是正确的,输出操作确实触发了计算。 另外,用户可能对Spark Streaming的机制不太清楚,可能误以为定义转换就会立即执行,但实际上需要输出操作来触发。因此,题目中的描述是对的,答案应该选“对”。</think>**答案:对** **解析**: 在 Spark Streaming 中,**DStream 的输出操作(如 `print()`, `saveAsTextFiles()`, `foreachRDD()` 等)是触发实际计算的入口**。具体原理如下: --- ### **1. DStream 的惰性计算机制** - **转换操作(Transformations)的惰性**: - DStream 的转换操作(如 `map`, `filter`, `reduceByKey`)仅记录计算逻辑,**不会立即执行**。 - *公式*: $$ \text{DStream 转换} = \text{逻辑计划(未执行)} $$ - **输出操作(Actions)的触发作用**: - 输出操作是 DStream 的**“动作”**,会强制 Spark Streaming 将累积的转换逻辑提交到集群执行。 - *示例*: ```scala dstream .filter(...) // 转换:记录过滤逻辑 .map(...) // 转换:记录映射逻辑 .print() // 输出操作:触发计算 ``` --- ### **2. 输出操作的本质** - **生成 Spark Job**: 每次调用输出操作时,Spark Streaming 会为当前批次的数据生成一个或多个 **Spark Job**,并提交到集群执行。 - *公式*: $$ \text{输出操作} \Rightarrow \text{Job 提交} \Rightarrow \text{物理执行} $$ - **执行所有依赖的转换**: 输出操作会追溯 DStream 的依赖链,执行所有关联的转换操作(如上游的 `filter`、`map`)。 --- ### **3. 特殊场景验证** - **无输出操作时**: - 若仅定义转换但无输出操作,**数据流不会处理**(无 Job 提交)。 - *示例*: ```scala dstream.map(x => x * 2) // 无输出操作,无实际计算 ``` - **多次输出操作的副作用**: - 若对同一 DStream 调用多个输出操作(如多次 `print()`),**每个输出操作会触发独立的计算流程**,可能导致重复处理。 --- **结论**: 题目描述**正确**。DStream 的输出操作是触发实际计算的必要条件,所有上游转换操作会在此时执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值