Spark Streaming消费kafka的数据(0.8版本kafka)

15 篇文章 1 订阅

导入依赖

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-streaming-kafka-0-8_2.11</artifactId>
    <version>2.1.1</version>
</dependency>

Receiver连接方式

  • 在kafka-0.8的版本,offset维护在zookeeper中。
  • 如果程序停止过程中,kafka生产了数据,那么程序再次启动时,可以消费到停止期间生产的数据。
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setAppName(this.getClass.getSimpleName).setMaster("local[*]")
    val ssc = new StreamingContext(conf,Seconds(3))
    //接收kafka生产的数据
    val dataDStream: ReceiverInputDStream[(String, String)] = KafkaUtils.createStream(
      ssc,
      //zookeeper地址
      "hadoop01:2181,hadoop02:2181,hadoop03:2181",
      //消费者组
      "bigdata0330",
      //指定topic和分区数
      Map[String, Int]("SparkStreaming" -> 2)
    )
    //取出value,统计词频
    val resDStream: DStream[(String, Int)] = dataDStream.map(_._2).flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
    resDStream.print()
    //开始采集
    ssc.start()
    ssc.awaitTermination()

  }

Direct连接方式

自动维护offset

  • 偏移量会保存到checkpoint目录中。
  • 获取StreamingContext的方式需要改变。
  • 此种方式会丢失消息。
  • 小文件过多。
  • 再次执行spark程序时,会从上一次记录的时间戳开始,到当前的时间,将时间段内所有的周期都执行一遍。
  def main(args: Array[String]): Unit = {
    // 如果不存在StreamingContext,则创建,如果有,就返回checkpoint目录
    val ssc: StreamingContext = StreamingContext.getActiveOrCreate(
      "D:\\develop\\workspace\\bigdata2021\\spark2021\\checkpoint",
      () => createContext()
    )
    //开始采集
    ssc.start()
    ssc.awaitTermination()


  }

    // 创建StreamingContext对象
    def createContext(): StreamingContext = {
      val conf: SparkConf = new SparkConf().setAppName(this.getClass.getSimpleName).setMaster("local[*]")
      val ssc = new StreamingContext(conf, Seconds(3))
      //设置检查点目录
      ssc.checkpoint("D:\\develop\\workspace\\bigdata2021\\spark2021\\checkpoint")
      //kafka配置参数
      val kafkaParams = Map[String,String](
        ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG -> "hadoop01:9092,hadoop02:9092,hadoop03:9092",
        ConsumerConfig.GROUP_ID_CONFIG -> "bigdata0330"
      )

      //消费kafka的数据
      //泛型分别为:消息key的类型,消息value的类型,消息key的编解码方式,消息value的编解码方式
      val dataDStream: InputDStream[(String, String)] = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](
        ssc,
        kafkaParams,
        //topic集合
        Set("SparkStreaming")
      )
      //取出value,进行统计
      val resDStream: DStream[(String, Int)] = dataDStream.map(_._2).flatMap(_.split(" ")).map((_, 1)).reduceByKey(_ + _)
      resDStream.print()

      ssc
    }

手动维护offset

  • 实际项目中,为了保证数据的准确一致性,将消费后的offset保存到有事务的介质中,比如MySQL。
  def main(args: Array[String]): Unit = {
    val conf: SparkConf = new SparkConf().setAppName(this.getClass.getSimpleName).setMaster("local[*]")
    val ssc = new StreamingContext(conf,Seconds(3))
    //kafka配置参数
    val kafkaParams = Map[String,String](
      //kafka节点
      ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG -> "hadoop01:9092,hadoop02:9092,hadoop03:9092",
      //消费者组
      ConsumerConfig.GROUP_ID_CONFIG -> "bigdata0330"
    )

    //上一次消费的偏移量
    //实际项目中,为了保证数据的准确一致性,将消费后的offset保存到有事务的介质中,比如Mysql
    val fromOffsets = Map[TopicAndPartition,Long](
      TopicAndPartition("SparkStreaming", 0) -> 10L,
      TopicAndPartition("SparkStreaming", 1) -> 10L
    )

    //从指定offset读取数据进行消费
    val dataDStream: InputDStream[String] = KafkaUtils
      //泛型:消息key类型,消息value类型,消息key的编解码,消息value的编解码,消息的返回值类型
      .createDirectStream[String,String,StringDecoder,StringDecoder,String](
      ssc,
      kafkaParams,
      //获取上一次消费偏移量
      fromOffsets,
      //获取消息
      (m: MessageAndMetadata[String, String]) => m.message()
    )
    //消费完后,更新偏移量
    var ranges: Array[OffsetRange] = Array.empty[OffsetRange]
    dataDStream.transform {
      rdd => {
        ranges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
        rdd
      }
    }.foreachRDD(
      rdd => {
        for (o <- ranges) {
          println(s"${o.topic} ${o.partition} ${o.fromOffset} ${o.untilOffset}")
        }
      }
    )

    ssc.start()
    ssc.awaitTermination()
  }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值