Spark Streaming 基础
1. SparkStreaming概述
1).Spark Streaming用于流式数据的处理,Spark Streaming有高吞吐量和容错能力强等特点。
2).他导入kafka、flume、hdfs等数据源,经过处理输出到hdfs、databases等。
2. StreamingContext
1).通过SparkConf获取
val conf = new SparkConf().setAppName(appName).setMaster(master)
val ssc = new StreamingContext(conf, Seconds(1))
2).通过SparkContext获取
val sc = ... // existing SparkContext
val ssc = new StreamingContext(sc, Seconds(1))
3).通过StreamingContext获取SparkContext
SparekContext sc = ssc.sparkContext;
3.StreamingContext编程
4. DStream概述
1).Discretized Stream是Spark Streaming的基础抽象,代表持续性的数据流和经过各种Spark原语操作后的结果数据流。
2).在内部实现上,DStream是一系列连续的RDD来表示。每个RDD含有一段时间间隔内的数据----->对数据的操作也是按照RDD为单位来进行的------>计算过程由Spark engine来完成。
5. Dstream 的分类
Dstream 主要分为三大类:InputDStream,Transformed DStream,Output DStream
1. InputStream
输入的数据有两种方式:
第一种方式:Basic sources,通过StreamingContext API 获取
eg: val lines = ssc.socketTextStream(“localhost”, 9999)
eg: val lines = ssc.textFileStream(“hdfs://192.168.126.31:9000/test/”)
第二种方式:Advanced sources,资源来自Kafka, Flume, Kinesis, etc.
特别注意:Spark 与 Flume 、 Kafka,版本必须要兼容,比如
Kafka: Spark Streaming 2.1.1 is compatible with Kafka broker versions 0.8.2.1 or higher. See the Kafka Integration Guide for more details.
Flume: Spark Streaming 2.1.1 is compatible with Flume 1.6.0. See the Flume Integration Guide for more details.
Kinesis: Spark Streaming 2.1.1 is compatible with Kinesis Client Library 1.2.1. See the Kinesis Integration Guide for more details.
2. Transformed Dstream
DStreams支持许多用在一般Spark RDD上的转换。其中一些常用的如下:
map(func):将源DStream中的每个元素通过一个函数func从而得到新的DStreams。
flatMap(func):和map类似,但是每个输入的项可以被映射为0或更多项。
filter(func):选择源DStream中函数func判为true的记录作为新DStreams
repartition(numPartitions):通过创建更多或者更少的partition来改变此DStream的并行级别。
union(otherStream):联合源DStreams和其他DStreams来得到新DStream
count:统计源DStreams中每个RDD所含元素的个数得到单元素RDD的新DStreams。
reduce(func):通过函数func(两个参数一个输出)来整合源DStreams中每个RDD元素得到单元素RDD的DStreams。这个函数需要关联从而可以被并行计算。
countByValue:对于DStreams中元素类型为K调用此函数,得到包含(K,Long)对的新DStream,其中Long值表明相应的K在源DStream中每个RDD出现的频率。
reduceByKey(func, [numTasks]):对(K,V)对的DStream调用此函数,返回同样(K,V)对的新DStream,但是新DStream中的对应V为使用reduce函数整合而来。Note:默认情况下,这个操作使用Spark默认数量的并行任务(本地模式为2,集群模式中的数量取决于配置参数spark.default.parallelism)。你也可以传入可选的参数numTaska来设置不同数量的任务。
join(otherStream,[numTasks]):两DStream分别为(K,V)和(K,W)对,返回(K,(V,W))对的新DStream。
cogroup(otherStream,[numTasks]):两DStream分别为(K,V)和(K,W)对,返回(K,(Seq[V],Seq[W])对新DStreams
transform(func):将RDD到RDD映射的函数func作用于源DStream中每个RDD上得到新DStream。这个可用于在DStream的RDD上做任意操作。
updateStateByKey(func):得到”状态”DStream,其中每个key状态的更新是通过将给定函数用于此key的上一个状态和新值而得到。这个可用于保存每个key值的任意状态数据。
3. Output DStream
foreachRDD
foreachRDD通常用来把SparkStream运行得到的结果保存到外部系统比如HDFS、Mysql、Redis等等,一个分区使用一个连接池来维护连接对象。
dstream.foreachRDD { rdd =>
rdd.foreachPartition { partitionOfRecords =>
// ConnectionPool is a static, lazily initialized pool of connections
val connection = ConnectionPool.getConnection()
partitionOfRecords.foreach(record => connection.send(record))
ConnectionPool.returnConnection(connection) // return to the pool for future reuse
}
6. 简单示例
1.依赖库
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>2.1.1</version>
</dependency>
2.编码
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[2]").setAppName("FirstTestCase")
val ssc = new StreamingContext(conf, Seconds(2))
//监听一个端口数据
val lines = ssc.socketTextStream("192.168.126.31", 9999)
//监听一个文件夹 val lines = ssc.textFileStream("hdfs://192.168.126.31:9000/test")
val words = lines.flatMap(_.split(" "))
val pairs = words.map(word => (word, 1))
val wordCounts = pairs.reduceByKey(_+_)
wordCounts.print()
ssc.start()
ssc.awaitTermination()
}
3.测试
在192.168.126.31 节点上使用命令输入内容:
nc -lk 9999