Spark Streaming
一、流计算的定义
一般流式计算会与批量计算相比较。在流式计算模型中,输入是持续的,可以认为在时间上是无界的,也就意味着,永远拿不到全量数据去做计算。同时,计算结果是持续输出的,也即计算结果在时间上也是无界的。
流式计算一般对实时性要求较高,同时一般是先定义目标计算,然后数据到来之后将计算逻辑应用于数据。同时为了提高计算效率,往往尽可能采用增量计算代替全量计算。
批量处理模型中,一般先有全量数据集,然后定义计算逻辑,并将计算应用于全量数据。特点是全量计算,并且计算结果一次性全量输出
Spark Streaming是构建在Spark 批处理之上一款流处理框架。与批处理不同的是,流处理计算的数据是无界数据流,输出也是持续的。Spark Streaming底层将Spark RDD Batch 拆分成 Macro RDD Batch实现类似流处理的功能。因此spark Streaming在微观上依旧是批处理框架。
原文链接:https://blog.csdn.net/weixin_38231448/article/details/104529807
批处理 对比 流处理
类别类别 | 批处理 | 流处理 |
---|---|---|
数据类型 | 静态 | 持续动态 |
数据级别 | GB级别 | 一条记录,几百字节 |
延迟时间 | 30分钟或几个小时 | 几秒或亚秒 |
计算类型 | 最终停止 | 7*24小时 |
场景 | 离线 | 在线 |
目前的流处理框架
· kafka Streaming
· Apache Strom
· Spark Streaming
· Flink DataStream
Discretized Streams
(DStreams)
Discretized Stream或DStream是Spark Streaming提供的基本抽象。它表示连续的数据流,可以是从源接收的输入数据流,也可以是通过转换输入流生成的已处理数据流。在内部,DStream由一系列连续的RDD表示,这是Spark对不可变分布式数据集的抽象。DStream中的每个RDD都包含来自特定时间间隔的数据。
二、快速搭建测试
①.引入相关依赖 注:2.11指的是Scala的版本
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>2.4.5</version>
</dependency>
<build>
<plugins>
<!--scala编译插件-->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>scala-maven-plugin</artifactId>
<version>4.0.1</version>
<executions>
<execution>
<id>scala-compile-first</id>
<phase>process-resources</phase>
<goals>
<goal>add-source</goal>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
<!--创建fatjar插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<!--编译插件-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
②.编写Driver
import org.apache.spark.streaming.dstream.{
DStream, ReceiverInputDStream}
import org.apache.spark.{
SparkConf, SparkContext}
import org.apache.spark.streaming.{
Seconds, StreamingContext}
object SparkStreaming {
def main(args: Array[String]): Unit = {
//创建流所需要的环境
//①创建配置文件对象
val conf = new SparkConf().setAppName("SparkStreaming").setMaster("spark://hbase:7077")
//需要参数:1.sparkconf 配置文件 2. 批持续时间
val streamingContext = new StreamingContext(conf, Seconds(1))
//②.创建持续输入的 DStream
val lines: ReceiverInputDStream[String] = streamingContext.socketTextStream("hbase", 9999) //指定 netcat 的测试数据
//③.对离散流进行转换
val result: DStream[(String, Int)] = lines.flatMap(_.split("\\s+")).map(x=>(x,1)).reduceByKey(_+_)
//将结果打印到控制台
result.print()
//⑤.启动计算
streamingContext.start()
//等待系统关闭流计算
streamingContext.awaitTermination()
}
}
注:streamingContext的第二个时间参数设置的不能太小,应略大于 微批 的计算时间,避免数据在spark内存中积压
③.打包上传至Linux
④.校对时间
yum install -y ntp -y #安装时间校对插件
ntpdate time.apple.com #校对时间MAC 系统
ntpdate cn.pool.ntp.org# window系统
clock -w #保存此次时间
date #打印当前时间
⑤.安装netcat插件
yum install -y nc #z安装netcat 服务
nc -lk 9999 #启动netcat
⑥.启动spark测试
./bin/spark-submit --master spark://CentOS:7077 --deploy-mode client --class SparkStreaming --name wordcount --total-executor-cores 6 /root/Spark_Streaming-1.0-SNAPSHOT.jar
三、Input
在SparkStreaming中每个InputStream(除去File Stream)底层都对应着一个Receiver的实现。每个Receiver负责接收来自外围系统的数据,并且把接收的数据存储到Spark的内存中,用于后续的处理。Spark提供了两种内建的Source用于读取外围系统的数据。
Basic Sources
: socketTextStream(测试)、textFileStream(读文件)<==> fileStream
Advanced Sources
: Kafka、Flume 等可以借助工具创建,一般需要导入第三方依赖。
注意:一个Receiver也会占用一个Cores,因此大家在跑Spark Streaming的程序的时候,一定要给程序分配 n个core(n > recevicers个数),否则Spark只能接受,无法处理。
①.File Stream
可以读取任意一种能和HDFS文件系统兼容文件。DStream 可以通过 StreamingContext.fileStream[KeyClass, ValueClass, InputFormatClass]方式创建。
File streams不需要额外Receiver也就意味着不需要给FileStream分配计算资源cores
package com.baizhi
import org.apache.hadoop.io.{
LongWritable, Text}
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.{
DStream, InputDStream}
import org.apache.spark.streaming.{
Seconds, StreamingContext}
object FileStream {
def main(args: Array[String]): Unit = {
//1.创建StreamContext
val sparkConf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("FileStream")
//设置批持续时间
val ssc = new StreamingContext(sparkConf,Seconds(3))
//设置日志级别
ssc.sparkContext.setLogLevel("FATAL")
//2.获取持续的数据流
val lines: InputDStream[(LongWritable, Text)] = ssc.fileStream[LongWritable,Text