Spark之 Spark Streaming整合kafka(并演示reduceByKeyAndWindow、updateStateByKey算子使用)
Kafka0.8版本基于receiver接受器去接受kafka topic中的数据(并演示reduceByKeyAndWindow的使用)
依赖
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming-kafka-0-8_2.11</artifactId>
<version>2.1.3</version>
</dependency>
代码
package com.zy.kafka2streaming
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}
import scala.collection.immutable
/**
* sparkStreaming整合kafka: 基于receiver接受器去接受kafka topic中的数据,使用高级api(消息的偏移量由zk维护)
* kafka0.8版本才有createStream 1.0就没有了
* reduceByKeyAndWindow算子使用(开窗函数)
*
* 前提:需要开启生产者往kafka中写入数据
*/
object SparkStreamingKafkaReceiver {
def main(args: Array[String]): Unit = {
//sparkConf 开启WAL日志,保证数据源的安全性
val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingKafkaReceiver").setMaster("local[4]").set("spark.streaming.receiver.writeAheadLog.enable", "true")
//sc
val sc: SparkContext = new SparkContext(sparkConf)
sc.setLogLevel("WARN")
//构建ssc
val ssc: StreamingContext = new StreamingContext(sc, Seconds(5))
//设置checkpoint目录
ssc.checkpoint("./spark-receiver")
//接收kafka数据
//1 指定zk地址
val zkQuorum = "bigdata-01:2181,bigdata-02:2181,bigdata-03:2181"
//2 消费者groupid
val groupId = "zyTest"
// 指定topic有关信息 key:表示topic的名称,value:表示每一个receiver接收器使用多少个线程去消费topic数据
val topic = Map("sparkDemo" -> 1)
//使用多个receiver接收(循环创建 并放到集合中)
val receiverList: immutable.IndexedSeq[ReceiverInputDStream[(String, String)]] = (1 to 3).map(x => {
val stream: ReceiverInputDStream[(String, String)] = KafkaUtils.createStream(ssc, zkQuorum, groupId, topic)
stream
})
//把一个集合中多个Dstream数据汇总成一个Dstream
val unionStream: DStream[(String, String)] = ssc.union(receiverList)
//获取topic数据 第二个是value
val data: DStream[String] = unionStream.map(_._2)
//切分
val words: DStream[String] = data.flatMap(_.split(","))
//计数
val wordsAndOne: DStream[(String, Int)] = words.map((_, 1))
//聚合
//val result: DStream[(String, Int)] = wordsAndOne.reduceByKey(_ + _)
/**
* 开窗函数 reduceByKeyAndWindow 三个参数
* 第一个:逻辑函数
* 第二个:表示窗口的长度
* 第三个:表示窗口的滑动时间间隔,每隔多久计算一次
*
* 每5秒统计前15秒的结果
*/
val result: DStream[(String, Int)] = wordsAndOne.reduceByKeyAndWindow((x: Int, y: Int) => x + y, Seconds(15), Seconds(5))
//打印
result.print()
//开启流计算
ssc.start()
ssc.awaitTermination()
}
}
Kafka1.0版本整合Kafka(并演示updateStateByKey的使用)
依赖
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming-kafka-0-10_2.11</artifactId>
<version>2.1.3</version>
</dependency>
代码
package com.zy.kafka2streaming import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.spark.streaming.dstream.DStream
import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
import org.apache.spark.streaming.kafka010.KafkaUtils
import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext} /**
* sparkStreaming整合kafka:利用低级api(消息的offset不再由zk去维护,有streaming处理完数据去维护)
* updateStateByKey算子的使用(历史累计)
* 前提:需要开启生产者往kafka中写入数据
*/
object SparkStreamingKafkaDirect {
def main(args: Array[String]): Unit = {
//sparkConf
val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingKafkaDirect").setMaster("local[4]")
//sc
val sc: SparkContext = new SparkContext(sparkConf)
sc.setLogLevel("WARN") //sparkStreaming
val ssc: StreamingContext = new StreamingContext(sc, Seconds(5)) //checkpoint
ssc.checkpoint("./spark-direct") //----------------获取kafka中的数据------------------- //kafka0.8版本写法
//注意 这里0.8版本的参数是zk的地址 1.0版本的是kafka的地址
// val kafkaParams = Map("bootstrap.servers" -> "bigdata-01:9092,bigdata-02:9092,bigdata-03:9092", "groupId" -> "sparkDirect")
//topic 可以设置多个topic
// val topics = Set("sparkDemo") // KafkaUtils.createDirectStream 0.8版本的写法
// val dstream: InputDStream[(String, String)] = KafkaUtils.createDirectStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topics) /**
* 官网kafka1.0版本 Creating a Direct Stream 示例
* import org.apache.kafka.clients.consumer.ConsumerRecord
* import org.apache.kafka.common.serialization.StringDeserializer
* import org.apache.spark.streaming.kafka010._
* import org.apache.spark.streaming.kafka010.LocationStrategies.PreferConsistent
* import org.apache.spark.streaming.kafka010.ConsumerStrategies.Subscribe
* *
* val kafkaParams = Map[String, Object](
* "bootstrap.servers" -> "localhost:9092,anotherhost:9092",
* "key.deserializer" -> classOf[StringDeserializer],
* "value.deserializer" -> classOf[StringDeserializer],
* "group.id" -> "use_a_separate_group_id_for_each_stream",
* "auto.offset.reset" -> "latest",
* "enable.auto.commit" -> (false: java.lang.Boolean)
* )
* *
* val topics = Array("topicA", "topicB")
* val stream = KafkaUtils.createDirectStream[String, String](
* streamingContext,
* PreferConsistent,
* Subscribe[String, String](topics, kafkaParams)
* )
* *
*stream.map(record => (record.key, record.value))
*/ //1.0版本的写法
val kafkaParams = Map[String, Object](
"bootstrap.servers" -> "bigdata-01:9092,bigdata-02:9092,bigdata-03:9092",
"key.deserializer" -> classOf[StringDeserializer],
"value.deserializer" -> classOf[StringDeserializer],
"group.id" -> "zy_test_direct",
"auto.offset.reset" -> "latest",
"enable.auto.commit" -> (false: java.lang.Boolean)
)
val topics = Set("sparkDemo")
val dstream = KafkaUtils.createDirectStream[String, String](ssc, PreferConsistent, Subscribe[String, String](topics, kafkaParams)) //--------------------------获取topic数据---------------------------- //0.8版本可以这么写 1.0版本不能这么写了
//val data: DStream[String] = dstream.map(_._2) //1.0版本 DStream.map
val data: DStream[String] = dstream.map(_.value())
//切分
val words: DStream[String] = data.flatMap(_.split(","))
//计数
val wordsAndOne: DStream[(String, Int)] = words.map((_, 1))
//聚合
//val result: DStream[(String, Int)] = wordsAndOne.reduceByKey(_ + _) /**
* 使用updateStateByKey 累计统计单词出现的次数
* 需要传一个函数进去
*/
val result: DStream[(String, Int)] = wordsAndOne.updateStateByKey(updateFunction) //打印
result.print() //开启流计算
ssc.start()
ssc.awaitTermination()
} /**
*
* @param newValues 表示当前批次汇总成的(word,1)中相同单词的所有的1
* @param historyCount 历史的所有相同key的value总和
* @return
*/
def updateFunction(newValues: Seq[Int], historyCount: Option[Int]): Option[Int] = {
//新的计数等于原来的计数加上这次数据的sum
val newCount: Int = historyCount.getOrElse(0) + newValues.sum
//将累加后的结果放到Option的子集Some中返回
Some(newCount)
}
}
Spark之 Spark Streaming整合kafka(并演示reduceByKeyAndWindow、updateStateByKey算子使用)的更多相关文章
- Spark学习之路(十六)—— Spark Streaming 整合 Kafka
一.版本说明 Spark针对Kafka的不同版本,提供了两套整合方案:spark-streaming-kafka-0-8和spark-streaming-kafka-0-10,其主要区别如下: s ...
- Spark 系列(十六)—— Spark Streaming 整合 Kafka
一.版本说明 Spark 针对 Kafka 的不同版本,提供了两套整合方案:spark-streaming-kafka-0-8 和 spark-streaming-kafka-0-10,其主要区别如下 ...
- spark streaming 整合 kafka(一)
转载:https://www.iteblog.com/archives/1322.html Apache Kafka是一个分布式的消息发布-订阅系统.可以说,任何实时大数据处理工具缺少与Kafka整合 ...
- spark streaming 整合kafka(二)
转载:https://www.iteblog.com/archives/1326.html 和基于Receiver接收数据不一样,这种方式定期地从Kafka的topic+partition中查询最新的 ...
- Spark之 Spark Streaming整合kafka(Java实现版本)
pom依赖 <properties> <scala.version>2.11.8</scala.version> <hadoop.version>2.7 ...
- spark streaming整合kafka
版本说明:spark:2.2.0: kafka:0.10.0.0 object StreamingDemo { def main(args: Array[String]): Unit = { Logg ...
- Spark Streaming 整合 Kafka
一:通过设置检查点,实现单词计数的累加功能 object StatefulKafkaWCnt { /** * 第一个参数:聚合的key,就是单词 * 第二个参数:当前批次产生批次该单词在每一个分区出现 ...
- Spark Streaming和Kafka整合保证数据零丢失
当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制.为了体验这个关键的特性,你需要满足以下几个先决条件: 1.输入的数据来自可靠的数据源 ...
- Spark Streaming和Kafka整合是如何保证数据零丢失
转载:https://www.iteblog.com/archives/1591.html 当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢 ...
随机推荐
- 关于浏览器和IIS基础的简单理解
浏览器 输入域名或者IP地址,按回车访问后:发生了什么??IIS是如何工作的?为什么能这么工作?? 1 浏览器和IIS 分别是两个应用程序:浏览器访问网址实际就是 两个应用程序的数据交互往来: ...
- 性能指标术语&理发店模型
2015-11-26 09:13:53 响应时间 响应时间=呈现时间+系统响应时间 呈现时间取决于数据在被客户端收后到呈现出页面所消耗的时间: 系统响应时间指应用系统从请求发出开始到客户端接收到数据所 ...
- leaflet简单操作demo
今天大意了解了一下leaflet这个开源的 JavaScript 库,很强大. 结合腾讯地图,做了个简单的demo,作为一个学习的起点吧(各种API结合自身的业务) <!DOCTYPE html ...
- ubuntu 修改分辨率为自定义分辨率
在ubuntu14.04虚拟机上修改自定义大小的桌面屏幕分辨率,使用的命令:cvt,xrandr 0.首先查看下当前已经提供的分辨率设置:xrandr -q root@xxx:/home/xxx/De ...
- php 常用方法
//返回json数据给js function json_output($err_code = 0 , $error_message = '' , $data = [] , $redirect = '' ...
- 黄聪:使用Add-on SDK开发火狐扩展
2014年3月7号更新:火狐已经关闭Add-on SDK服务啦!我也转用360急速浏览器来开发浏览器插件了. 如果精通JS.HTML.CSS开发的朋友,直接看这个教程估计就能懂了 ---------- ...
- LockSupport分析
LockSupport是java.util.concurrent.locks包中的一个工具类,主要提供了一些在创建锁和同步类中用来阻塞其他线程的原始操作. 当有多个线程需要获取同一个资源的锁的时候,如 ...
- easyui datagrid 格式化列显示两位小数、千分位
{ field: , formatter: function (value, row, index) { if (row != null) { ); } } }, //二位小数.千分位 { field ...
- C语言经典面试题 与 C语言面试宝典
1 预处理 问题1:什么是预编译?何时需要预编译? 答: 预编译又称预处理,是整个编译过程最先做的工作,即程序执行前的一些预处理工作.主要处理#开头的指令.如拷贝#include包含的文件代码.替换# ...
- 【洛谷】P1052 过河(状压dp)
题目描述 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数 ...