DStream的转化和输出

DStream的转化和输出

1.无状态的转化

处理只关心当前采集周期内的数据,上个周期采集到的数据不做保留和处理
在这里插入图片描述

2.有状态的转化

在这里插入图片描述
如上图,第一个采集周期5s内的数据,如果需要拿去和第二个5s内的数据进行交互,就叫做有状态的转换。否则就是无状态的操作。
例子:依旧是统计单词的个数,之前只能统计一个采集周期内的单词的个数,现在可以统计所有的单词的个数。
需要注意的点:

  1. 使用updateStateByKey来完成有状态的统计
  2. 要设定检查点存储的位置
object updata {
  def main(args: Array[String]): Unit = {
    //使用sparkstreaming来完成wordcount

    //spark的配置对象
    val conf = new SparkConf().setMaster("local[*]").setAppName("WordCount")

    //实时分析的环境对象
    //采集周期:以指定的时间为周期采集实时数据
    val streamingContext = new StreamingContext(conf, Seconds(5))

    //保存数据的状态,需要设定检查点路径
    streamingContext.sparkContext.setCheckpointDir("cp")

    //从指定的端口中采集数据
    val socketLineDStream: ReceiverInputDStream[String] = streamingContext.socketTextStream("hadoop102", 9999)

    //将采集的数据进行分解
    val wordDStream = socketLineDStream.flatMap(line => line.split(" "))

    //将数据进行结构的转变进行统计分析
    val mapDStream = wordDStream.map((_, 1))

    //将转换结构后的数据进行聚合处理
    //无状态的情况
    //val wordToSumDStream = mapDStream.reduceByKey(_ + _)
    //这里使用updateStateByKey来完成有状态的单词统计
    val stateDStream: DStream[(String, Int)] = mapDStream.updateStateByKey {
      case (seq, buffer) => {
        val sum = buffer.getOrElse(0) + seq.sum
        Option(sum)
      }
    }
    //将结果打印
    stateDStream.print()

    //结束,不需要stop(),因为是流式数据,需要一直采集下去。

    //要完成采集器不停,整个程序不能停的效果
    //启动采集器
    streamingContext.start()

    //Driver等待采集器的执行
    streamingContext.awaitTermination()
  }
}
3.Window Operations

窗口函数介于有状态和无状态之间,根据window(窗口大小,步长)两个参数来修改处理参数的范围(是几个采集周期,移动是怎么移动的),这两个参数的大小都要是采集周期的整数倍。
使用这个函数可以明显的看出数据在时间的流动过程中的变化,适合用来分析带有时间属性的流动数据。
使用的时候只要设定一下window()函数即可。

object Windows {
  def main(args: Array[String]): Unit = {
    //使用sparkstreaming来完成wordcount

    //spark的配置对象
    val conf = new SparkConf().setMaster("local[*]").setAppName("WordCount")

    //实时分析的环境对象
    //采集周期:以指定的时间为周期采集实时数据
    val streamingContext = new StreamingContext(conf, Seconds(3))

    //从指定的端口中采集数据
    val socketLineDStream: ReceiverInputDStream[String] = streamingContext.socketTextStream("hadoop102", 9999)

    //窗口大小应该是采集周期的整数倍,步长也要采集周期的整数被
    val windowDStream = socketLineDStream.window(Seconds(9),Seconds(3))

    //将采集的数据进行分解
    val wordDStream = windowDStream.flatMap(line => line.split(" "))

    //将数据进行结构的转变进行统计分析
    val mapDStream = wordDStream.map((_, 1))

    //将转换结构后的数据进行聚合处理
    val wordToSumDStream = mapDStream.reduceByKey(_ + _)

    //将结果打印
    wordToSumDStream.print()

    //结束,不需要stop(),因为是流式数据,需要一直采集下去。

    //要完成采集器不停,整个程序不能停的效果
    //启动采集器
    streamingContext.start()

    //Driver等待采集器的执行
    streamingContext.awaitTermination()
  }
}

4.transform

transform也是用来做RDD的转换的,它和map的区别如下图:
在这里插入图片描述
transform可以在内层实现每隔采集周期就进行一次Driver的操作,这是map做不到的。

5.Join

连接操作(leftOuterJoin, rightOuterJoin, fullOuterJoin也可以),可以连接Stream-Stream,windows-stream to windows-stream、stream-dataset
底层实现就是join()

6.DStream的输出

输出操作如下:

  1. print():在运行流程序的驱动结点上打印DStream中每一批次数据的最开始10个元素。这用于开发和调试。在Python API中,同样的操作叫print()。
  2. saveAsTextFiles(prefix,[suffix]):以text文件形式存储这个DStream的内容。每一批次的存储文件名基于参数中的prefix和suffix。
  3. saveAsObjectFiles(prefix, [suffix]):以Java对象序列化的方式将Stream中的数据保存为
    SequenceFiles 。Python中目前不可用。
  4. saveAsHadoopFiles(prefix, [suffix]):将Stream中的数据保存为 Hadoop files.
    Python API Python中目前不可用。
  5. foreachRDD(func):这是最通用的输出操作,即将函数 func 用于产生于stream的每一个RDD。其中参数传入的函数func应该实现将每一个RDD中数据推送到外部系统,如将RDD存入文件或者通过网络将其写入数据库。注意:函数func在运行流应用的驱动中被执行,同时其中一般函数RDD操作从而强制其对于流RDD的运算。
    这个得到是stream中的每个RDD,可以在fun中对这些RDD进行操作。

tips:在进行一些数据库的连接时

  • 连接不能写在driver层面:connection无法序列化
  • 如果写在foreach则每个RDD都创建,得不偿失;
  • 增加foreachPartition,在分区创建。
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值