spark学习(11)之SparkStreaming实时计算

Spark Streaming基础:
Spark Streaming makes it easy to build scalable fault-tolerant streaming applications.
Spark Streaming使得大规模容错型的流失计算应用变得十分容易
它的特点:
(1)支持多种语言:java scala python sql
(2)容易集成:当部署好spark的时候就spark Streaming已经集成了
(3)容错机制:核型数据模型就是DataStream,DataStream就是离散的RDD
容易出错的地方:
在sparkStreaming实时计算的时候要求最小cpu核数为2,一个负责接收发过来的流数据,一个负责处理数据
DataStream数据模型采样:
在这里插入图片描述
一个简单流式数据计算

import org.apache.log4j.Logger
import org.apache.log4j.Level
import org.apache.spark.SparkConf
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.Seconds
import org.apache.spark.storage.StorageLevel

object demo1 {
  def main(args: Array[String]): Unit = {
    //不打印多余的日志配置
    Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
    Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    //获取StreamingContext对象
    val conf=new SparkConf().setAppName("StreamTest2").setMaster("local[2]")
    val ssc=new StreamingContext(conf,Seconds(2))
     //得到DStream,是一个scoket输入流                  ip               端口                     
    val dstream = ssc.socketTextStream("192.168.112.111", 1234, StorageLevel.MEMORY_AND_DISK_SER)
    dstream.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).print()
    
    //启动流式计算
    ssc.start()
    ssc.awaitTermination()
  }
}

host:192.168.112.111,
port:1234
是我在linux服务下使用netcat当做一个socket服务在发送数据
nc -l -p 1234
nc :是命令
-l :使用的监听模式
-p :端口使用的是1234
在这里插入图片描述
在这里插入图片描述
还需要注意的是:
1、

dstream.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_).print()

必须需要有那个print()输出函数,不然的话会报一个错误,说没有输出函数:

Exception in thread "main" java.lang.IllegalArgumentException: requirement failed: No output operations registered, so nothing to execute

语法异常,没有输出操作注册,没有需要执行的操作。
2、每隔2秒钟采样一次,但是每次计算只是这2秒的内容,如果想把以前累加起来还需要自己做一个缓存操作,恰好spark给提供了一个处理以前状态的算子updateStateByKey



import org.apache.spark.SparkConf
import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.Seconds
import org.apache.spark.storage.StorageLevel
import org.apache.log4j.Logger
import org.apache.log4j.Level

object MyNetWorkWordCountTotal {
   def main(args: Array[String]): Unit = {
    //不打印多余的日志配置
    Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
    Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    //获取StreamingContext对象
    val conf=new SparkConf().setAppName("StreamTest2").setMaster("local[2]")
    val ssc=new StreamingContext(conf,Seconds(2))
    //设置检查点
    ssc.checkpoint("hdfs://192.168.112.111:9000/ckpt/day0529")
     //得到DStream,是一个scoket输入流                  ip               端口                     
    val dstream = ssc.socketTextStream("192.168.112.111", 1234, StorageLevel.MEMORY_AND_DISK_SER)
    val dStream2=dstream.flatMap(_.split(" ")).map((_,1))
   /* val updateFunc=(currentValues:Seq[Int],previousValues:Option[Int]) => {
      //当前要累加的总数
      System.out.print(currentValues.length)
      val currentSum = currentValues.sum
      val previousValue=previousValues.getOrElse(0)
      Some(currentSum+previousValue)
    }*/
    dStream2.updateStateByKey(updateFunc).print()
    
    //启动流式计算
    ssc.start()
    ssc.awaitTermination()
  }
   def updateFunc(currentValues:Seq[Int],previousValues:Option[Int])={
     //当前要累加的总数
      System.out.print(currentValues.length)
      val currentSum = currentValues.sum
      val previousValue=previousValues.getOrElse(0)
      Some(currentSum+previousValue)
   }
}

使用这个函数的时候需要设置一个检查点,不然的话会报一下错误:
Exception in thread “main” java.lang.IllegalArgumentException: requirement failed: The checkpoint directory has not been set. Please set it by StreamingContext.checkpoint().
updateStateByKey的算子需要传入一个处理以前状态和现在状态的函数,注释掉的定义的updateFunc方法和下面定义的方法都可以。
S表示你要保存起来对应value的类型
Seq[Int]中的int类型是由操作你的DataStream流所决定的,比如的流中的value是Int那就是Int,如果是String那就是String
def updateStateByKey[S](updateFunc: (Seq[Int], Option[S]) => Option[S])(implicit evidence$4: ClassTag[S]): DStream[(String, S)]
3、sparkStreaming的一个窗口计算的算子

import org.apache.spark.streaming.StreamingContext
import org.apache.spark.streaming.Seconds
import org.apache.log4j.Logger
import org.apache.log4j.Level
import org.apache.spark.SparkConf
import org.apache.spark.storage.StorageLevel

object MyNetWorkWordCountWithWindow {
  def main(args: Array[String]): Unit = {
    //不打印多余的日志配置
    Logger.getLogger("org.apache.spark").setLevel(Level.ERROR)
    Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF)
    //获取StreamingContext对象
    val conf=new SparkConf().setAppName("StreamTest2").setMaster("local[2]")
    val ssc=new StreamingContext(conf,Seconds(2))
    //得到DStream,是一个scoket输入流                  ip               端口                     
    val dstream = ssc.socketTextStream("192.168.112.111", 1234, StorageLevel.MEMORY_AND_DISK_SER)
    val pairRdd=dstream.flatMap(_.split(" ")).map((_,1))
    pairRdd.reduceByKeyAndWindow((a:Int,b:Int)=>a+b, Seconds(30), Seconds(10)).print()
    //启动流式计算
    ssc.start()
    ssc.awaitTermination()
  }
}

reduceByKeyAndWindow中有俩个时间,Seconds(30)是窗口的大小,Second(10)是窗口滑动的时间,也是多长时间计算一次。和上边Second(2)的关系是,Second(2)是负责采样连续的数据形成离散的RDD的DStream,但不是说采样完了就立马计算,是过Second(10)时间才计算,而且计算的是当前往后的30s采样的数据。这样在窗口滑动的过程中,其实有重叠的部分
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枣泥馅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值