sparkStreaming-获取kafka数据并按批次累加
import org.apache.spark.{HashPartitioner, SparkConf}
import org.apache.spark.streaming.dstream.ReceiverInputDStream
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
//获取kafka数据并按批次累加
object LoadKafkaDataAndWC {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("LoadKafkaDataAndWC").setMaster("local[*]")
val ssc = new StreamingContext(conf,Seconds(5))
//指定整合kafka相关的参数
val zkQueue = "192.168.88.130:2181,192.168.88.131:2181,192.168.88.132:2181"
val groupId = "group1"
val topic = Map[String,Int]("test"->1)
//设置检查点
ssc.checkpoint("D:\\数据\\checkpoint")
//调用kafkaUtils工具获取kafka的数据
val data: ReceiverInputDStream[(String, String)] = KafkaUtils.createStream(ssc,zkQueue,groupId,topic)
//因为DStream里面的key是offset值,把DStream里面的value数据取出来
val lines = data.map(_._2)
//形成元祖的形式
val tup = lines.flatMap(_.split(" ")).map((_,1))
//使用updateStateByKey实现更新状态
val res = tup.updateStateByKey(func,new HashPartitioner(ssc.sparkContext.defaultParallelism),true)
res.print()
ssc.start()
ssc.awaitTermination()
}
/**
* 实现按批次累加功能,需要调用updateStateByKey
* 其中需要自定义一个函数,该函数是对历史结果数据和当前批次数据的操作过程
* 该函数中第一个参数代表每个单词
* 第二个参数代表当前批次单词出现的次数:Seq(1,1,1,1)
* 第三个参数代表之前批次累加的结果,可能有值,也可能没有值,所以在获取的时候要用getOrElse方法
*/
val func = (it: Iterator[(String, Seq[Int], Option[Int])]) => {
it.map(x => {
(x._1, x._2.sum + x._3.getOrElse(0))
})
}
}