什么是Spark Streaming??
用于流式数据的处理,具有高吞吐量和容错能力强等的特点
SparkStreaming:
是一个可扩展的,高吞吐量,实时的流式处理
可以和多个数据源进行整合
将数据流分批次的进行处理,每一个批次就是一个时间段
DStream是一个离散流,是SparkStreaming的基本数据抽象,它由连续的RDD构成
DStream之间是有依赖关系的
什么是DStream??
Discretized(离散) Stream是Spark Streaming 的基础抽象,代表持续性的数据流和经过各种Spark原语操作后的结果数据流;
在内部实现上,DStream是一系列连续的RDD来表示.每个RDD含有一段时间间隔内的数据
实战:
1.安装并启动生成者
首先在一台Linux上用yum安装nc工具
yum install -y nc
启动一个服务端并监听8888端口
nc -lk 8888
Spark Streaming Kafka整合
1.安装并配置zk
2.安装并配置kafka
3.启动zk
4.启动kafka
5.创建topic
编写Spark Streaming应用程序
package myRPC.qf.itcast.SparkStreaming
import myRPC.qf.itcast.spark.LoggerLevels
import org.apache.spark.{HashPartitioner, SparkConf}
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
/**
* 实现按批次累加的功能,需要调用updateStateByKey方法
* 其中需要自定义一个函数,在函数中,第一个参数代表每一个单词
* 第二个参数代表当前批次单词出现的次数,表现形式为Seq(1,1,1,1)
* 第三个参数代表之前批次累加的结果
*/
object LoadKafkaDataAndWC {
def main(args: Array[String]): Unit = {
LoggerLevels.setStreamingLogLevels()
//请求kafka所需要的几个参数
val Array(zkQuorum,group,topics,numThreads) = args
val conf = new SparkConf().setAppName("LoadKafkaDataAndWC").setMaster("local[2]")
val ssc = new StreamingContext(conf,Seconds(10))
//检查点
ssc.checkpoint("hdfs://minimaster:9000/ck20171031")
//获取每一个Topic放在一个Map里
val topicToMap: Map[String, Int] = topics.split(",").map((_,numThreads.toInt)).toMap
//调用KafkaUtils工具类的createStream来获取kafka的数据
val data: ReceiverInputDStream[(String, String)] =
KafkaUtils.createStream(ssc,zkQuorum,group,topicToMap)
//把获取的数据value值留下,因为value值才是实际的数据
val lines: DStream[String] = data.map(_._2)
val tup: DStream[(String, Int)] = lines.flatMap(_.split(" ")).map((_,1))
val res: DStream[(String, Int)] =
tup.updateStateByKey(func,new HashPartitioner(ssc.sparkContext.defaultParallelism),false)
res.print()
res.saveAsTextFiles("hdfs://minimaster:9000/20171031/out_2017")
ssc.start()
ssc.awaitTermination()
}
val func = (it: Iterator[(String,Seq[Int],Option[Int])]) => {
it.map {
case (x, y, z) => (x,y.sum+z.getOrElse(0))
}
}
}
在Linux上执行:
./kafka-topics.sh –create –zookeeper minimaster:2181 –replication-factor 1 partitions 1 –topic dance
以前已经展示过了
在IDEA上先配置:
minimaster:2181,miniSlave1:2181,miniSlave2:2181 group1 dance 2
运行后的结果:
SparkStreaming 中窗口函数的展示:
窗口函数:一段时间内数据发生的变化
两个重要的参数:
window length: 窗口长度,代表窗口持续的时间(也就是说该窗口包含几个批次间隔)
sliding interval : 滑动间隔,代表执行窗口操作的间隔(也就是说窗口从一个地方滑动到另一个地方需要的时间)
这两个参数必须是DStream批次间隔的倍数
Spark Streaming中窗口函数的IDEA上代码实现:
package myRPC.qf.itcast.SparkStreaming
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{Seconds, StreamingContext}
object WindowOperationWC {
def main(args: Array[String]): Unit = {
LoggerLevels.setStreamingLogLevels()
val conf = new SparkConf().setAppName("WindowOperationWC").setMaster("local[2]")
val ssc = new StreamingContext(conf,Seconds(10))
ssc.checkpoint("c://ck_2017")
//获取数据
val dStream: ReceiverInputDStream[String] = ssc.socketTextStream("minimaster",8888)
val tup: DStream[(String, Int)] = dStream.flatMap(_.split(" ")).map((_,1))
//调用窗口操作来计算数据的聚合,批次间隔为10秒,设置窗口长度是10秒,滑动间隔是10秒
val result: DStream[(String, Int)] = tup.reduceByKeyAndWindow((x:Int, y:Int) => (x+y),Seconds(10),Seconds(10))
result.print()
ssc.start()
ssc.awaitTermination()
}
}
在Linux上执行:
在IDEA上的结果显示:
执行完毕后在c://目录下显示:
上面的文件打开都是以乱码的形式展示