sparkStreaming读取kafka写入hive分区表

sparkStreaming读取kafka写入hive分区表

使用版本: hadoop-3.1.3,hive-3.1.2。

开始这个spark不是很熟悉,但是项目要用到,这就要临阵磨枪了。开始写入hive的时候一直在报一个错误,的不是很懂,就是说我没有 .enableHiveSupport() 我就很蒙我明明有用到,但是他就是说我没用到。
不多说了上代码。

def test:Unit={
//设置用户名
System.setProperty("HADOOP_USER_NAME", "root")
写配置信息
    val conf:SparkConf = new SparkConf().setMaster("local[4]").setAppName("CounusmerController").set("spark.testing.memory","2147480000")
    val ssc = new StreamingContext(conf, Seconds(5))
    // kafka topic
    val topic:String = "test3"
    //消费者
    val groupId:String = "test3"
    //从 Redis 中读取 Kafka 偏移量
    val kafkaOffsetMap: Map[TopicPartition, Long] = OffsetManagerUtil.getOffset(topic,groupId)
    var kafkaDStream: InputDStream[ConsumerRecord[String, String]] = null
    if(kafkaOffsetMap!=null&&kafkaOffsetMap.size>0){
      //Redis 中有偏移量 根据 Redis 中保存的偏移量读取
      kafkaDStream = ThisKafkaUtil.getKafkaStream(topic, ssc,kafkaOffsetMap,groupId)
    }else{
      // Redis 中没有保存偏移量 Kafka 默认从最新读取
      kafkaDStream = ThisKafkaUtil.getKafkaStream(topic, ssc,groupId)
    }
     //得到本批次中处理数据的分区对应的偏移量起始及结束位置
    // 注意:这里我们从 Kafka 中读取数据之后,直接就获取了偏移量的位置,因为 KafkaRDD 可以转换为 HasOffsetRanges,会自动记录位置
    var offsetRanges: Array[OffsetRange] = Array.empty[OffsetRange]
    val offsetDStream: DStream[ConsumerRecord[String, String]] = recordDstream.transform {
      rdd => {
        offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
        println(offsetRanges(0).untilOffset + "*****")
        rdd
      }
    }
    //打印采集结果
    offsetDStream.print(100)
    
    jsonStr.foreachRDD(rdd =>{
	val sparkSession = SparkSessionSingleton.getInstance(rdd.sparkContext.getConf)
	if(rdd.count() > 0){
	 import CounusmerController.sparkConf.implicits._
        import CounusmerController.sparkConf.sql
        //将数据写进临时表
        rdd.map(x =>{
          val test = x.value().split("\t")
          val entity = HttpLogEntity(test(0).toInt, test(1), test(2), test(3), test(4), test(5), test(6))
          entity
        }).toDF().createOrReplaceTempView("tmp")
        
         sql("use test")
        sql("set hive.exec.dynamici.partition=true")
        sql("set hive.exec.dynamic.partition.mode=nonstrict")
        sql("insert into table data" +
          " select date,user_id,httptext,type,source,http,id from tmp ")
	}
	})
	
	 ssc.start()
    ssc.awaitTermination()
}

中间的函数调用

object SparkSessionSingleton {
    @transient private var instance: SparkSession = _

    def getInstance(sparkConf: SparkConf): SparkSession = {
      if (instance == null) {
        instance = SparkSession
          .builder
          .enableHiveSupport()
          .config(sparkConf)
          .getOrCreate()
      }
      instance
    }
  }

这样,就是一直在给我报那个错误,最后我真的是左看看又看看,真的是给我弄得

修改后代码

object CounusmerController{
  private lazy val sparkConf = SparkSession.builder().appName("CounusmerController")
    .config("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    .config("hive.exec.dynamic.partition.mode", "nonstrict")
    .master("local[4]").config("spark.testing.memory","2147480000")
    .enableHiveSupport().getOrCreate()

}
class CounusmerController {
def linkHive:Unit={
    System.setProperty("HADOOP_USER_NAME", "root")
    val sc = CounusmerController.sparkConf.sparkContext
    val ssc = new StreamingContext(sc,Seconds(5))

    //===============消费 Kafka 数据基本实现===================
    val groupId = "wu3"
    val topic = "test3"
    //从 Redis 中读取 Kafka 偏移量
    val kafkaOffsetMap: Map[TopicPartition, Long] = OffsetManagerUtil.getOffset(topic,groupId)
    var recordDstream: InputDStream[ConsumerRecord[String, String]] = null
    if(kafkaOffsetMap!=null&&kafkaOffsetMap.size>0){
      //Redis 中有偏移量 根据 Redis 中保存的偏移量读取
      recordDstream = ThisKafkaUtil.getKafkaStream(topic, ssc,kafkaOffsetMap,groupId)
    }else{
      // Redis 中没有保存偏移量 Kafka 默认从最新读取
      recordDstream = ThisKafkaUtil.getKafkaStream(topic, ssc,groupId)
    }
    //得到本批次中处理数据的分区对应的偏移量起始及结束位置
    // 注意:这里我们从 Kafka 中读取数据之后,直接就获取了偏移量的位置,因为 KafkaRDD 可以转换为 HasOffsetRanges,会自动记录位置
    var offsetRanges: Array[OffsetRange] = Array.empty[OffsetRange]
    val offsetDStream: DStream[ConsumerRecord[String, String]] = recordDstream.transform {
      rdd => {
        offsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
        println(offsetRanges(0).untilOffset + "*****")
        rdd
      }
    }
    offsetDStream.print(100)
    offsetDStream.foreachRDD(rdd=>{
      if(rdd.count() > 0){
        import CounusmerController.sparkConf.implicits._
        import CounusmerController.sparkConf.sql
        rdd.map(x =>{
          val test = x.value().split("\t")
          val entity = HttpLogEntity(test(0).toInt, test(1), test(2), test(3), test(4), test(5), test(6))
          entity
        }).toDF().createOrReplaceTempView("tmp")
        sql("use test")
        sql("set hive.exec.dynamici.partition=true")
        sql("set hive.exec.dynamic.partition.mode=nonstrict")
        sql("insert into table data" +
          " select date,user_id,httptext,type,source,http,id from tmp ")
      }
    })
    ssc.start()
    ssc.awaitTermination()
  }
}

这样终于是把kafka中的数据读取出来了,写入hive了,真的是难死宝宝了

你可能感兴趣的:(big,data,spark,kafka,hive,scala)