Spark Streaming使用(Python版)

Spark Streaming使用(Python版)

本文使用的是PySpark,但如果用scala本质思想是一致的,只是语言不同。参考的是子雨老师的教程——子雨大数据之Spark入门教程(Python版)

Spark安装

PySpark版本参考

Spark2.1.0+入门:Spark的安装和使用(Python版)

scala版本参考

hadoop2.7.7+spark集群搭建

Spark Streaming简介

Spark Streaming是Spark的核心组件之一,为Spark提供了可拓展、高吞吐、容错的流计算能力。如下图所示,Spark Streaming可整合多种输入数据源,如Kafka、Flume、HDFS,甚至是普通的TCP套接字。经处理后的数据可存储至文件系统、数据库,或显示在仪表盘里。

Spark Streaming的基本原理是将实时输入数据流以时间片(秒级)为单位进行拆分,然后经Spark引擎以类似批处理的方式处理每个时间片数据,执行流程如下图所示。

Spark Streaming最主要的抽象是DStream(Discretized Stream,离散化数据流),表示连续不断的数据流。在内部实现上,Spark Streaming的输入数据按照时间片(如1秒)分成一段一段的DStream,每一段数据转换为Spark中的RDD,并且对DStream的操作都最终转变为对相应的RDD的操作。例如,下图展示了进行单词统计时,每个时间片的数据(存储句子的RDD)经flatMap操作,生成了存储单词的RDD。整个流式计算可根据业务的需求对这些中间的结果进一步处理,或者存储到外部设备中。

实现WordCount

编写程序

此处仅介绍文件流的输入来源,其它如套接字等可参见子雨老师的教程。

首先创建一个SparkContext,设置使用2个逻辑CPU的线程来本地化运行Spark。

from pyspark import SparkContext, SparkConf
from pyspark.streaming import StreamingContext
conf = SparkConf()
conf.setAppName('TestDStream')
conf.setMaster('local[2]')
sc = SparkContext(conf = conf)

然后创建spark streaming

ssc = StreamingContext(sc, 20) #每20s监听一下
lines = ssc.textFileStream('file:///usr/local/spark/mycode/streaming/logfile') #监听/usr/local/spark/mycode/streaming/logfile目录

处理数据

words = lines.flatMap(lambda line: line.split(' '))
wordCounts = words.map(lambda x : (x,1)).reduceByKey(add)
wordCounts.pprint() #输出结构

启动ssc

ssc.start() #实际上,这行启动监听
ssc.awaitTermination() #ssc.awaitTermination()是无法输入到屏幕上的,但是,为了程序完整性,这里还是给出ssc.awaitTermination

将代码合起来,新建一个wordCount.py,代码如下

from operator import add
from pyspark import SparkContext, SparkConf
from pyspark.streaming import StreamingContext
conf = SparkConf()
conf.setAppName('TestDStream')
conf.setMaster('local[2]')
sc = SparkContext(conf = conf)
ssc = StreamingContext(sc, 20)
lines = ssc.textFileStream('file:///usr/local/spark/mycode/streaming/logfile')
words = lines.flatMap(lambda line: line.split(' '))
wordCounts = words.map(lambda x : (x,1)).reduceByKey(add)
wordCounts.pprint()
ssc.start()
ssc.awaitTermination()

注意事项

  • 监听程序只监听”/usr/local/spark/mycode/streaming/logfile”目录下在程序启动后新增的文件,不会去处理历史上已经存在的文件。(这意味着如果把先前已经存在的文件从别的地方拖入到logfile目录下也是无效的——注意理解新增的概念
  • 因此,在开启spark streaming监听之后,需要到”/usr/local/spark/mycode/streaming/logfile”目录下再新建一个log3.txt文件,这时才能看到效果。

扩展(统计包含历史信息)

我们可以发现这每一次输出的数据都只针对当前文件,而与前面处理过的文件无关。但现实情况中,往往需要统计的数据。那要怎么办呢?

一个办法便是使用updateStateByKey操作,这需要我们设置checkpoint以及完成一个updateFunc的函数。

  • checkpoint顾名思义就是我们熟知的检查点,它帮助了updateStateByKey操作的实现。

  • Spark Streaming的updateStateByKey可以把DStream中的数据按key做reduce操作,然后对各个批次的数据进行累加。注意,wordDstream.updateStateByKeyInt每次传递给updateFunc函数两个参数,其中,第一个参数是某个key(即某个单词)的当前批次的一系列值的列表 ,updateFunc函数中 sum(new_values),就是计算这个被传递进来的与某个key对应的当前批次的所有值的总和,也就是当前批次某个单词的出现次数。传递给updateFunc函数的第二个参数是某个key的历史状态信息,也就是某个单词历史批次的词频汇总结果。

改写后的代码

from pyspark import SparkContext, SparkConf
from pyspark.streaming import StreamingContext

def updateFunc(new_values, last_sum):
        return sum(new_values) + (last_sum or 0)
 

conf = SparkConf()
conf.setAppName('TestDStream')
conf.setMaster('local[2]')
sc = SparkContext(conf = conf)
ssc = StreamingContext(sc, 20)
ssc.checkpoint("file:///usr/local/spark/mycode/streaming/")
lines = ssc.textFileStream('file:///usr/local/spark/mycode/streaming/logfile')
words = lines.flatMap(lambda line: line.split(' '))
wordCounts = words.map(lambda x : (x,1)).updateStateByKey(updateFunc)
wordCounts.pprint()
ssc.start()
ssc.awaitTermination()
  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值