package SparkStreaming import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream} import org.apache.spark.streaming.kafka.KafkaUtils import org.apache.spark.streaming.{Seconds, StreamingContext} import org.apache.spark.{SparkConf, SparkContext} /** * Created by 古城小巷少年 on 2020-01-02 16:29 * 采用Receiver-based Approach的方式从Kafka拉取数据,偏移量记录在zookeeper上,调用高级API,但是效率低 * 1)高级API优点 * 高级API 写起来简单 * 不需要自行去管理offset,系统通过zookeeper自行管理。 * 不需要管理分区,副本等情况,.系统自动管理。 * 消费者断线会自动根据上一次记录在zookeeper中的offset去接着获取数据(默认设置1分钟更新一下zookeeper中存的offset) * 可以使用group来区分对同一个topic 的不同程序访问分离开来(不同的group记录不同的offset,这样不同程序读取同一个topic才不会因为offset互相影响) * 2)高级API缺点 * 不能自行控制offset(对于某些特殊需求来说) * 不能细化控制如分区、副本、zk等 */ object KafkaWordCount { def main(args: Array[String]): Unit = { val conf = new SparkConf().setAppName("kafkaWordCount").setMaster("local[*]") val ssc = new StreamingContext(conf, Seconds(5)) // 创建DSteam,需要KafkaDStream val zkQuorum = "hadoop102:2181,hadoop103:2181,hadoop104:2181" val groupId = "g1" val topic = Map[String, Int]("test"-> 1) val data: ReceiverInputDStream[(String, String)] = KafkaUtils.createStream(ssc, zkQuorum, groupId, topic) // 对数据进行处理 val lines: DStream[String] = data.map(_._2) val reduced: DStream[(String, Int)] = lines.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_) // 打印结果 reduced.print() // 启动执行 ssc.start() // 等待优雅地退出 ssc.awaitTermination() } }