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

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