1、SparkStreaming概述
1、SparkStreaming是什么?
SparkStreaming用于处理流式数据
2、SparkStreaming应用场景: 实时领域
3、DStream:
DStream是SparkStreaming的数据抽象
DStream流动的是RDD,每个RDD代表一个批次
SparkStreaming是微批次的实时处理引擎,不是来一条数据处理一条,而是等到积累一个批次时间之后统一处理
一个批次会封装成一个RDD
4、背压机制
sparkstreaming从kafka拉取数据消费,如果sparkstreaming消费能力不足,就可能导致批次累积<sparkstreaming在处理批次数据的时候,必须等到上一个批次处理完才会处理下一个批次>,所以sparkstreaming提交了一个背压机制。
背压机制会根据sparkstreaming的消费能力动态调整拉取数据速率,如果消费能力比较强,拉取数据的速率比较多,如果消费能力不足,拉取的数据比较少。
如何开启背压机制:
设置spark.streaming.backpressure.enabled=true
2、DStream创建
val ssc = new StreamingContext(new SparkConf().setAppName("..").setMaster(".."),批次时间)
1、RDD队列<只用于测试、演示>
ssc.queueStream(RDD队列,oneAtATime)
oneAtATime=false: 代表取出一个批次时间内RDD队列中传入的所有RDD作为一个批次数据
oneAtATime=true:代表从RDD队列中取出一个RDD作为一个批次的数据
2、自定义数据源
1、创建class继承Receiver[接受的数据类型] (StorageLevel.XXX)
2、重写抽象方式:
onStart: 是receiver启动的时候调用
onStop: 是receiver停止的时候调用
3、创建自定义数据源对象
4、从自定义数据源中读取数据: ssc.receiverStream(自定义数据源对象)
3、kafka数据源 <工作使用>
//消费者常用参数
val params = Map[String,Object] (
//设置key的反序列化器
"key.deserializer" -> "org.apache.kafka.common.serialization.StringDeserializer",
//设置value的反序列化器
"value.deserializer" -> "org.apache.kafka.common.serialization.StringDeserializer",
//设置topic所在集群地址
"bootstrap.servers" -> "hadoop102:9092,hadoop103:9092,hadoop104:9092",
//消费者组的id
"group.id" -> "ks01",
//设置消费者组第一次开始消费topic的时候从哪个位置开始消费
"auto.offset.reset" -> "earliest",
//是否自动提交offset
"enable.auto.commit" -> "true"
)
KafkaUtil.createDirectStream[K的类型,V的类型] (ssc,LocationStrategies.PreferConsistent,ConsumerStrategies.SubscribeK的类型,V的类型)
3、DStream转换
1、无状态<不需要其他批次数据>
map、flatMap、reduceByKey、...
2、有状态<需要其他批次数据>
1、updateStateByKey(func:(Seq[V的类型],Option[U])=>Option[U]): 统计key的全局结果
func第一个参数代表当前批次中该key对应的所有的value值
func第二个参数代表本批次之前该key统计的结果
使用updateStateByKey的时候因为需要保存每次统计的全局结果,所以需要设置checkpoint,用于保存全局结果<状态>
2、窗口
1、window(窗口长度,滑动长度)
2、reduceByKeyAndWindow(func:(V的类型,V的类型)=>V的类型,窗口长度,滑动长度) = window(窗口长度,滑动长度)+reduceByKey(func)
3、reduceByKeyAndWindow(func1:(V的类型,V的类型)=>V的类型,func2:(V的类型,V的类型)=>V的类型,,窗口长度,滑动长度): 反向reduce
应用场景: 如果窗口长度包含大量的批次,滑动长度批次比较少,此时两个窗口有很多共同的批次数据,此时为了减少数据重复计算提交执行效率,可以将这一部分数据不用重复计算。
func1函数:将上一个窗口的结果+滑入长度的结果
func2函数: 将上一个窗口的结果-滑出长度的结果
窗口长度与滑动长度必须是批次时间的整数倍
4、DStream的输出
SparkStreaming不推荐将数据保存到HDFS,因为每次计算之后保存的时候都会在HDFS创建一个目录,会生成很多小文件
SparkStreaming一般都是将结果数据保存到Mysql、Hbase、Redis等写入读取速度比较快的存储介质中。
SparkStreaming可以使用foreachRDD方法将数据保存到mysql.
5、SparkStreaming关闭
SparkStreaming程序有可能需要升级需要停止之前启动的程序,此时可以在sparkstreaming程序中监听mysql表某个字段/监听HDFS某个路径,一旦mysql字段的值发生改变或者HDFS路径改变,此时停止SparkStreaming程序。
ssc.stop(stopSparkContext=true,stopGracefully=true) 用来关闭sparkstreaming程序
stopGracefully=true代表等到之前接收到的批次数据全部处理完成之后才会停止程序 <推荐>
stopGracefully=false代表直接强制停止sparkstreaming程序