kafka和hive一起使用,SparkSession StreamingContext一起使用

object RealTimeRequestParamCollect {
 // 在伪分布式中,一个spark 应用对应了一个main函数,放在一个driver里,driver里有一个对应的实例(spark context).driver 负责向各个节点分发资源以及数据。
  // 那么如果你把创建实例放在了main函数的外面,driver就没法分发了。所以如果这样写在local模式下是可以成功的,在分布式就会报错。
  // https://blog.csdn.net/sinat_33761963/article/details/51723175
  // 这里使用lazy 懒加载解决这个问题
  private lazy val spark = SparkSession.builder().appName("线上日志收集").config("spark.serializer", "org.apache.spark.serializer.KryoSerializer").config("hive.exec.dynamic.partition.mode", "nonstrict")
    .enableHiveSupport()
    // 本地启动使用,并且本地调试只用使用run模式,debug模式看不到日志 start
    //    .master("local[2]")
    // 本地启动使用 end
    .getOrCreate()
    
 def main(args: Array[String]): Unit = {
    val batchInterval = 60
    val brokers = "123.234.231.111:9092" //指的是kafka的地址
    val topics = "aaaa_topic" // 监听的topic 英文“,”分割
    val groupId = "consumer_group" //注意,这个也就是我们的消费者的名字

    //步骤一:如下两个参数配置了以后,就可以在spark界面上看到监控,不配置就看不到
    // https://stackoverflow.com/questions/49307317/how-to-use-sparksession-and-streamingcontext-together
    // sc 为了保证StreamingContext和SparkSession使用一个SparkConf配置
    // 当同时存在多个SparkConf时,会抛出这个异常:org.apache.spark.SparkException: Only one SparkContext may be running in this JVM (see SPARK-2243). To ignore this error, set spark.driver.allowMultipleContexts = true
    val sc = spark.sparkContext
    //    sparkConf.set("spark.streaming.kafka.ui.enable", "1")
    sc.getConf.set("spark.streaming.kafka.groupid", groupId)
    val ssc = new StreamingContext(sc, Seconds(batchInterval))

    // 监听的topic 英文“,”分割
    val topicsSet = topics.split(",").toSet

    val kafkaParams = Map[String, String](
      "metadata.broker.list" -> brokers,
      "group.id" -> groupId
    )

    //步骤二:设置转转监听器,帮我们完成偏移量的提交
    ssc.addStreamingListener(
      new FFListener(kafkaParams));

    //键步骤三: 创建对象,然后通过这个对象获取到上次的偏移量,然后获取到数据流
    val km = new KafkaManager(kafkaParams)
    val messages = km.createDirectStream[String, String, StringDecoder, StringDecoder](
      ssc, kafkaParams, topicsSet)
      //完成你的业务逻辑即可
    messages.foreachRDD(rdd => {
      //获取当前消息所属的topic
      val offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
      var topic: String = ""
      offsetRanges.take(1).foreach(osr => topic = osr.topic)

      // 处理日志
      rdd.flatMap(_._2.split("\n")).filter(
        msg => PATTERN.matcher(msg).find()).take(100).foreach(c => {
        logger.info("method=rdd.foreach topic :"+topic +" record:" + c);
      })
    })

    ssc.start()
    ssc.awaitTermination()
    //    ssc.stop()
  }
 }

参考资料:https://blog.csdn.net/sinat_33761963/article/details/51723175
https://stackoverflow.com/questions/49307317/how-to-use-sparksession-and-streamingcontext-together

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章