Spark Streaming的编程和Spark的编程如出一辙,对于编程的理解也非常类似。对于Spark来说,编程就是对于RDD的操作;而对于Spark Streaming来说,就是对DStream的操作。下面将通过一个大家熟悉的WordCount的例子来说明Spark Streaming中的输入操作、转换操作和输出操作。
val ssc = new StreamingContext(“Spark://…”, “WordCount”, Seconds(1), [Homes], [Jars])
Spark Streaming 磁盘输入编程实现
特别的,对于文件,DStream可以这样创建:
//创建FileInputStream,并指向特定目录
val lines = scc.textFileStream(dataDirectory
)
Spark Streaming将会监视dataDirectory目录下的任何Hadoop兼容的文件系统,并且处理这个目录下创建的任何文件。
注意:
For more details on streams from files, Akka actors and sockets, see the API documentations of the relevant functions in StreamingContext for Scala and JavaStreamingContext for Java.
此外,通过源,例如Kafka、Flume和 Twitter创建DStream的功能可以通过导入并添加正确的依赖,就像前面的章节中解释的那样。 在Kafka的情况下,在添加artifact spark-streaming-kafka_2.10到项目的依赖后,你可以像这样创建一个来自Kafka的DStream:
import org.apache.spark.streaming.kafka.*; KafkaUtils.createStream(jssc, kafkaParams, ...);
另一类就是网络流的方式,目前支持Kafka、Flume、Twitter和TCP socket。在WordCount例子中,假定通过网络socket作为输入流,监听某个特定的端口,最后得出输入 DStream(lines)。
val lines = ssc.socketTextStream(“localhost”,8888)
val words = lines.flatMap(_.split(“ ”))
val wordCounts = words.map(x => (x, 1)).reduceByKey(_ + _)
另外,Spark Streaming有特定的窗口操作,窗口操作涉及两个参数:一个是滑动窗口的宽度(Window Duration);另一个是窗口滑动的频率(Slide Duration),这两个参数必须是batch size的倍数。例如以过去5秒钟为一个输入窗口,每1秒统计一下WordCount,那么我们会将过去5秒钟的每一秒钟的WordCount都进行统计,然后进行叠加,得出这个窗口中的单词统计。
val wordCounts = words.map(x => (x, 1)).reduceByKeyAndWindow(_ + _, Seconds(5s),seconds(1))
但上面这种方式还不够高效。如果我们以增量的方式来计算就更加高效,例如,计算t+4秒这个时刻过去5秒窗口的WordCount,那么我们可以将t+3时刻过去5秒的统计量加上[t+3,t+4]的统计量,在减去[t-2,t-1]的统计量(如图5所示),这种方法可以复用中间三秒的统计量,提高统计的效率。
val wordCounts = words.map(x => (x, 1)).reduceByKeyAndWindow(_ + _, _ - _, Seconds(5s),seconds(1))
图5 Spark Streaming中滑动窗口的叠加处理和增量处理
wordCounts = saveAsHadoopFiles(“WordCount”)
ssc.start()