目录
2.4 DStream中的transformation和action算子
2.5 Driver HA(Standalone或者Mesos)
1 什么是SparkStreaming
1.1 SparkStreaming简介、
官网:http://spark.apache.org/streaming/
特点:
- 便于使用
- 容错
- spark集成
SparkStreaming是流式处理框架,是Spark API的扩展,支持可扩展、高吞吐量、容错的实时数据流处理,实时数据的来源可以是:Kafka, Flume, Twitter, ZeroMQ或者TCP sockets,并且可以使用高级功能的复杂算子来处理流数据。例如:map,reduce,join,window 。最终,处理后的数据可以存放在文件系统,数据库等,方便实时展现。
和Spark基于RDD的概念很相似,Spark Streaming使用离散化流(discretized stream)作为抽象表示,叫作DStream。DStream 是随时间推移而收到的数据的序列。在内部,每个时间区间收到的数据都作为 RDD 存在,而 DStream 是由这些 RDD 所组成的序列(因此 得名“离散化”)。
DStream 可以从各种输入源创建,比如 Flume、Kafka 或者 HDFS。创建出来的DStream 支持两种操作,一种是转化操作(transformation),会生成一个新的DStream,另一种是输出操作(output operation),可以把数据写入外部系统中。DStream 提供了许多与 RDD 所支持的操作相类似的操作支持,还增加了与时间相关的新操作,比如滑动窗口。
Discretized Stream or DStream 是 Spark Streaming 提供的基本抽象. 它代表了一个连续的数据流, 无论是从 source(数据源)接收到的输入数据流, 还是通过转换输入流所产生的处理过的数据流. 在内部, 一个 DStream 被表示为一系列连续的 RDDs, 在一个 DStream 中的每个 RDD 包含来自一定的时间间隔的数据,所以说应用与DStream的任何操作转化在底层来说都是对于RDDs的操作:如下图所示.
1.2 SparkStreaming与Storm的区别
- Storm是纯实时的流式处理框架,SparkStreaming是准实时的处理框架(微批处理)。因为微批处理,SparkStreaming的吞吐量比Storm要高。
- Storm 的事务机制要比SparkStreaming的要完善。
- Storm支持动态资源调度。(spark1.2开始和之后也支持)
- SparkStreaming擅长复杂的业务处理,Storm不擅长复杂的业务处理,擅长简单的汇总型计算。
2 SparkStreaming初始
2.1 官方自带的WordCount程序
[root@hadoop103 ~]# nc -lk 9999
-bash: nc: command not found //如果出现这个提示
[root@hadoop103 ~]# yum -y install nc //安装即可
然后在另一台节点上监听hadoop103节点的9999端口,运行下面spark自带的WordCount程序
$SPARK_HOME/bin/run-example streaming.NetworkWordCount hadoop103 9999
注意:如果虚拟机的cores 只有一个,sparkstreaming的程序就不能读取数据,详解往下面看
2.2 IDEA编程
操作SparkStreaming首先导入下面的依赖
<!-- 导入SparkStreaming的依赖 --> <dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-streaming_2.11</artifactId> <version>2.2.0</version> </dependency>
// 配置日志的显示级别,
Logger.getLogger("org").setLevel(Level.ERROR) //具体日志信息问题:请点这里def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[*]").setAppName(this.getClass.getSimpleName)
val sc = new SparkContext(conf)
val ssc: StreamingContext = new StreamingContext(sc,Seconds(2)) //Seconds() 设置一个批次的时间间隔
//读取socket端口的数据
val textStream: ReceiverInputDStream[String] = ssc.socketTextStream("hadoop103",9999)
//对读取到的数据进行处理
val result: DStream[(String, Int)] = textStream.flatMap(_.split(" ")).map((_,1)).reduceByKey(_+_)
//调用action算子
result.print() //默认打印10行
//Spark Streaming 程序的必备
ssc.start()
//阻塞程序,挂起
ssc.awaitTermination()
}
2.3 StreamingContext的cores配置
如果程序给定的cores 只有一个:
// master 需要至少 2 个核, 以防止饥饿情况(starvation scenario).
val conf = new SparkConf().setMaster("local[1]").setAppName(this.getClass.getSimpleName)
//如果给一个cores,会警告如下:
19/04/06 13:38:27 WARN StreamingContext: spark.master should be set as local[n], n > 1 in local mode if you have receivers to get data, otherwise Spark jobs will not get resources to process the received data.
一个StreamingContext创建多个input Dstream,会创建多个Receiver,Spark会为每个Receiver 分配一个core用于其运行。
故若SparkStreaming 程序一共分配了k个core,运行n个Receiver,应保证k>n,这时会有n个core用于运行Receiver接收外部数据,k-n个core用于真正的计算。
一个Receiver 占用了一个core,这里两个Receiver占用了2个core,如果这个job的启动资源是 --master "local[4]" 那么真正能用于运算的core只有两个了。
val ssc: StreamingContext = new StreamingContext(sc,Seconds(2))
// 读取socket端口的数据, 需要一个cores
val textStream: ReceiverInputDStream[String] = ssc.socketTextStream("hadoop103",9999)
// 占用一个cores
val textStream2: ReceiverInputDStream[String] = ssc.socketTextStream("hadoop102",9999)