1.SparkStreaming,是Spark生态栈中的一个能够用于进行实时计算的模块。
实时计算的典型代表框架就是apache storm,准实时计算的典型代表框架就是SparkStreaming,现在由有开始流行Flink(时间延迟介于storm和sparkStreaming之间)
Spark Streaming是Spark Core API的一种扩展,它可以用于进行大规模、高吞吐量、容错的实时数据流的处理。它支持从很多种数据源中读取数据,比如Kafka、Flume、Twitter、ZeroMQ、Kinesis、ZMQ或者是TCP Socket。并且能够使用类似高阶函数的复杂算法来进行数据处理,比如map、reduce、join和window。处理后的数据可以被保存到文件系统、数据库、Dashboard等存储中。
-
SparkStreaming的工作原理
接收实时输入数据流,然后将数据拆分成多个batch,比如每收集1秒的数据封装为一个batch,然后将每个batch交给Spark的计算引擎进行处理,最后会生产出一个结果数据流,其中的数据,也是由一个一个的batch所组成的。
a. 核心概念DStream
类似于SparkCore中的RDD和SparkSQL中的Dataset、DataFrame,在SparkStreaming中的编程模型是DStream(离散化的流)。DStream是对一个时间段内产生的一些列RDD的封装,也就是说一个DStream内部包含多个RDD。
DStream可以通过输入算子来创建,也可以通过高阶算子,比如map、flatMap等等进行转换产生。
如图所示,该DStream,就包含了过去4个时间单位内产生的多个RDD数据
b.工作原理
1、对DStream应用的算子,比如map,其实在底层会被翻译为对DStream中每个RDD的操作。比如对一个DStream执行一个map操作,会产生一个新的DStream。但是,在底层,其实其原理为,对输入DStream中每个时间段的RDD,都应用一遍map操作,然后生成的新的RDD,即作为新的DStream中的那个时间段的一个RDD。底层的RDD的transformation操作。
2、还是由Spark Core的计算引擎来实现的。Spark Streaming对Spark Core进行了一层封装,隐藏了细节,然后对开发人员提供了方便易用的高层次的API.
-
常见流式框架的对比分析
.
组合式:操作更加基础的API操作,一步步精细控制,各组建组合定义成拓扑;
声明式:提供封装后的高阶函数。封装后可提供初步的优化;可提供窗口管理、状态管理等高级操作;
a. Storm V.S. SparkStreaming
1、Spark Streaming绝对谈不上比Storm、Flink优秀。这两个框架在实时计算领域中,都很优秀,只是擅长的细分场景并不相同。
2、Spark Streaming在吞吐量上要比Storm优秀。
3、Storm在实时延迟度上,比Spark Streaming就好多了,前者是纯实时,后者是准实时。而且,Storm的事务机制、健壮性/容错性、动态调整并行度等特性,都要比Spark Streaming更加优秀。
4、Spark Streaming,有一点是Storm绝对比不上的,就是:它位于Spark整个生态技术栈中,因此Spark Streaming可以和Spark Core、Spark SQL、Spark Graphx无缝整合,换句话说,我们可以对实时处理出来的中间数据,立即在程序中无缝进行延迟批处理、交互式查询等操作。这个特点大大增强了Spark Streaming的优势和功能。
对于Storm来说:
1、建议在需要纯实时,不能忍受1秒以上延迟的场景下使用,比如实时计算系统,要求纯实时进行交易和分析时。
2、在实时计算的功能中,要求可靠的事务机制和可靠性机制,即数据的处理完全精准,一条也不能多,一条也不能少,也可以考虑使用Storm,但是Spark Streaming也可以保证数据的不丢失。
3、如果我们需要考虑针对高峰低峰时间段,动态调整实时计算程序的并行度,以最大限度利用集群资源(通常是在小型公司,集群资源紧张的情况),我们也可以考虑用Storm
对于Spark Streaming来说:
1、不满足上述3点要求的话,我们可以考虑使用Spark Streaming来进行实时计算。
2、考虑使用Spark Streaming最主要的一个因素,应该是针对整个项目进行宏观的考虑,即,如果一个项目除了实时计算之外,还包括了离线批处理、交互式查询、图计算和MLIB机器学习等业务功能,而且实时计算中,可能还会牵扯到高延迟批处理、交互式查询等功能,那么就应该首选Spark生态,用Spark Core开发离线批处理,用Spark SQL开发交互式查询,用Spark Streaming开发实时计算,三者可以无缝整合,给系统提供非常高的可扩展性。
b. SparkStreaming V.S. Flink
对于Flink来说:
支持高吞吐、低延迟、高性能的流处理
支持带有事件时间的窗口(Window)操作
支持有状态计算的Exactly-once语义
支持高度灵活的窗口(Window)操作,支持基于time、count、session,以及data-driven的窗口操作
支持具有Backpressure功能的持续流模型
支持基于轻量级分布式快照(Snapshot)实现的容错
一个运行时同时支持Batch on Streaming处理和Streaming处理
Flink在JVM内部实现了自己的内存管理
支持迭代计算
支持程序自动优化:避免特定情况下Shuffle、排序等昂贵操作,中间结果有必要进行缓存
http://flink.apache.org
4.实时案例实战
a. 导入maven依赖
org.apache.spark
spark-streaming_2.11
2.2.2
b.基础编程
StreamingContext:sparkStreaming中的程序入口,java版本的入口就是JavaStreamingContext。
为了构建StreamingContext,至少需要两个参数,SparkConf,BatchDuration。
/**
- 通过基础案例来学习SparkStreaming的编程
- 通过网络端口|socket读取该端口的数据,加载进程sparkstreaming,进行wordcount的统计
- nc -lk bigdata01 9999
*/
object _01SparkStreamingWordCountOps {
def main(args: Array[String]): Unit = {
if(args == null || args.length ❤️) {
println(
“”"
|Parameter Errors ! Usage:
“”".stripMargin)
System.exit(-1)
}
val Array(batchInterval, host, port) = args //模式匹配
val conf = new SparkConf()
.setAppName("_01SparkStreamingWordCountOps")
.setMaster(“local[2]”)
val ssc = new StreamingContext(conf, Seconds(batchInterval.toLong))
/**
* 流式计算中的数据为啥要持久化
-
主要是为了多次计算过程中,原数据会被释放的原因
- 为啥默认的是MEMORY_AND_DISK_SER_2
* 进行数据的容错
*/
val linesDStream:ReceiverInputDStream[String] = ssc.socketTextStream(host, port.toInt)
// linesDStream.print()//dataframe.show
val wordsDStream:DStream[String] = linesDStream.flatMap(.split("\s+"))
val pairsDStream:DStream[(String, Int)] = wordsDStream.map(word => (word, 1))
val retDStream = pairsDStream.reduceByKey(+_)
retDStream.print()
ssc.start()//启动流式计算
ssc.awaitTermination()//要想程序持续不断的运行,就需要该方法被调用
}
}