SparkStreaming02

MapWithState 了解

UpdateStateBykeyMapWithState都是对DStream做批次累加操作,都可以将每个批次的结果进行累加计算,但是UpdateStateByKey是真正基于磁盘存储的,所有批次结果都会累加至磁盘,每次取值的时候也会直接访问磁盘,不管当前批次是否有值,都会获取之前批次结果数据,而MapWithState,虽然也是基于磁盘存储,但是 它合理使用内存,也就是缓存,MapWithState会首先将数据刷入内存,进行缓存操作,然后在把结果写入磁盘,而当批次没有数据的时候,不会访问磁盘,也不会打印当前数据,当有数据进来才会输出,并且首先访问内存,如果内存数据被清空再去访问磁盘数据,来做每次累加操作。

Transform

(类似Transforamtion)
可以在DStream中,使用RDD进行操作,然后返回的还是RDD,最后转换为DStream,一句话,在流中使用RDD

可以解决RDD与RDD之间的Join等,比如我们读取的字段文件,那么现在想把字典文件进行关联获取的数据流,需要将流转换为RDD处理。

案例:过滤广告黑名单
/**
  * 案例:过滤广告黑名单
  * 用户对网站上的广告进行点击,点击之后,要进行计费,点一次算一次的钱
  * 但是,有的无良的商家恶意刷广告,那么我们需要一个黑名单系统
  * 进行过滤黑名单用户
  */
object BlackListFilter {
  def main(args: Array[String]): Unit = {
    // 屏蔽log
    Logger.getLogger("org").setLevel(Level.WARN)
    val conf = new SparkConf().setAppName("filter").setMaster("local[2]")
    val ssc = new StreamingContext(conf,Seconds(3))
    // 设置黑名单
    val blackList = Array(("zhangsan",false),("lisi",false))
    // 创建RDD
    val rdd = ssc.sparkContext.parallelize(blackList)
    // val broad = ssc.sparkContext.broadcast(rdd.collect())
    // 获取数据源
    val inputDStream = ssc.socketTextStream("node4",9999)
    // 数据流进行过滤
//    inputDStream.transform(user=>{
//      user.filter(!broad.value.toList.contains(_))
//    }).print()
    inputDStream.transform(user=>{
      val tuples = user.map((_,1))
      // 如果用join的话,那数据没有匹配上,也不会保存,所以用LeftJoin操作
      val leftJoin: RDD[(String, (Int, Option[Boolean]))] = tuples.leftOuterJoin(rdd)
      val tuple = leftJoin.filter(tuple =>{
        tuple._2._2.getOrElse(true)
      })
      tuple.map(_._1)
    }).print()

    ssc.start()
    ssc.awaitTermination()
  }
}

foreachRDD

(类似Action)
输出方法,也是对RDD操作,但是无返回值,一般用于调用各种Connection连接使用,和Transform的区别在,一个是转换操作,一个是输出操作

滑动窗口(Window)

两个概念:

滑动时间:必须是每个批次提交的倍数 比如每批次提交5秒,那么滑动时间就必须是5的倍数

滑动距离:滑动距离是你批次的倍数,比如 每次滑动时间10秒,那么滑动距离可以是10,也可以是20或者15

在这里插入图片描述

滑动窗口的应用:

可以使用滑动窗口进行多批次统计,比如按照时间需求可以统计前几次批次结果集,例如:1分钟统计前10分钟的批次的结果集

例如:每五分钟显示前1小时的数据结果集

注意:每个窗口长度一定是批次的倍数

手动维护Offset(Zookeeper)重点

  1. 连接Zookeeper和Kafka
  2. 获取Offset(判断当前的Offset是否是第一次消费)
  3. 处理数据后,将Offset维护到ZK

好处:保证数据不丢失,同时保证每次数据消费的精准性,同时Zookeeper分布式的,可以分布式存储,保存offset安全,如果当前消费数据程序挂掉,计算结果没出来,那么Offset将不会被更新,下次继续消费当前数据

SparkStreaming的反压机制

设置最大接收速率 - 如果集群资源不够大,streaming 应用程序能够像接收到的那样快速处理数据,则可以通过设置 记录/秒 的最大速率限制。Direct Kafka 方法的 spark.streaming.kafka.maxRatePerPartition,在Spark 1.5中,引入了一个称为背压的功能,无需设置此速率限制,因为Spark Streaming会自动计算速率限制,并在处理条件发生变化时动态调整速率限制。可以通过将 配置参数 spark.streaming.backpressure.enabled 设置为 true 来启用此 backpressure。

在这里插入图片描述

数据序列化

可以使用Spark中的内部序列化机制 Kryo序列化方式,进行序列化操作,相比较Java的序列化方式,速度要快10倍以上,序列化的大小要小于Java的序列化

保证消费一次性

dempotent updates(幂等更新):多次尝试总是写入相同的数据。例如,saveAs***Files 总是将相同的数据写入生成的文件。

Transactional updates(事务更新):所有更新都是事务性的,以便更新完全按原子进行。这样做的一个方法如下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值