Spark DStreams
DStreams是什么
DStreams
是构建在Spark RDD
之上的一款流处理工具,意即Spark DStreams
并不是一个严格意义上的流处理,底层通过将RDD 在时间轴上分解成多个小的 RDD-micro batch
流 | 批处理
计算类型 | 数据量级 | 计算延迟 | 输入数据 | 输出 | 计算形式 |
---|---|---|---|---|---|
批处理 | MB=>GB=>TB | 几十分钟|几个小时 | 固定输入(全量) | 固定输出 | 最终终止(时间限制) |
流处理 | byte级别|记录级别 | 亚秒级延迟 | 持续输入(增量) | 持续输出 | 24*7小时 |
流处理框架:Kafka Streaming(工具级别)、Storm(实时流处理)一代
、Spark DStream(微批)-实时性差-二代
、Flink (实时流处理)-三代
由于
DStreams
构建在RDD
之上,对习惯了批处理的工程师来说,在使用上比较友好。很多大数据工程师都有着MapReduce
的使用经验,如果使用批去模拟流,比较容易接受,同时DStreams
是构建在RDD
(批处理)之上,因此从使用角度上讲,DStreams
操作流就好比是在操作批处理,因此在使用难度上比Storm
相对来说要简单。由于Spark
框架实现的核心偏向批处理,流处理只是从批处理中演变而来,因此DStreams
在做流处理的时候延迟较高
DStreams 原理
Discretized(离散) Streams (流)
(DStreams)在内部的工作原理:Spark Streaming
接收实时输入数据流并将数据分成批处理,然后由Spark
引擎处理以批量生成最终结果流
快速入门
- pom.xml文件
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_${scala.version}</artifactId>
<version>${spark.version}</version>
</dependency>
- Driver程序
//1.创建StreamingContext
val sparkConf = new SparkConf().setMaster("local[5]").setAppName("HelloWorld")
var ssc=new StreamingContext(sparkConf,Seconds(1)) //1s一次微批处理
//2.构建DStream对象 -细化
val lineStream = ssc.socketTextStream("centos",9999)
//3.对数据流进行计算 mirco-rdd 转换
lineStream.flatMap(_.split("\\s+")) //细化
.map((_,1))
.reduceByKey(_+_)
.print() //将计算结果打印
//4.启动计算
ssc.start()
ssc.awaitTermination()
- 启动网络服务
[root@centos ~]# yum install -y nc # 安装 netcat
[root@centos ~]# nc -lk 9999
this is a demo
this is a
this is
程序结构
- 创建
StreamingContext
- 指定流处理的数据源 #
socket-测试、文件系统-了解、Kafka-必须掌握、自定义Reciver-了解
- 对
DStreams
进行转换 # 基本上和RDD
转换保持一致- 启动任务ssc.start()
- 等待任务关闭ssc.awaitTermination() // 通过UI页面 kill
Input DStreams 和 Receivers
Spark
的每一个InputDstream
对应一个Receiver
实现(除文件系统输入流以外),每一个Receiver
对象负责接收外围系统的数据
,并且将数据存储到Spark的内存
中(设置存储级别-内存、磁盘),这也侧面反映了为什么说Spark DStreams
吞吐量比较大
Spark提供了两种类型的输入源:
- Basic sources:File System以及Socket 连接,无需用户导入第三方包
- Advanced sources:Spark本身不提供,需要导入第三方依赖,比如:Kafka
一般来说一个
Receiver
需要消耗一个Core计算资源,在Spark
运行流计算的时候,一定要提前预留多一些Core n,n > Receiver
个数
File Streams
以流的形式读取静态的资源文件,系统会尝试检测文件系统,一旦文件系统有新的数据产生,系统会加载新文件(仅仅加载一次)
注意:一定要确保文件系统时间和计算节点时间保持同步
val linesStream = ssc.textFileStream("hdfs://centos:9000/words")
linesStream.flatMap(_.split("\\s+")