Spark Streaming: 实时流式数据处理机制(1)

一、基本原理

Spark Streaming是一种实时流式数据处理机制,用于实时处理实时产生的数据流,具有高吞吐量、容错等特点。Spark Streaming构架如下图:

数据源可以是本地数据、HDFS、TCP socket、Kafka和Flume等等,Spark Streaming从数据源接收数据流,根据时间片将数据流分割成多个批,分批处理,并将处理结果输出到文件系统、数据库或屏幕。

关于Spark Streaming更详细的概念,例如DStream,窗口等概念,此处不详述,后面涉及的时候用实例解释。

二、两种数据源示例

1. TCP socket作为实时数据流

读取数据流以及实时处理代码如下:命名为NetworkWordCount.py

# -*- coding: utf-8 -*-

from pyspark import SparkContext
from pyspark.streaming import StreamingContext


# 创建 sc对象, local[2]表示“本地2个核”, NetworkWordCount为应用名称
sc = SparkContext("local[2]", "NetworkWordCount")
# 设置日志级别
sc.setLogLevel("WARN")
# 创建Spark Streaming Context对象, 此处的5表示5秒钟为一个单位接收数据流
ssc = StreamingContext(sc, 5)

# 从一个端口为9999的服务器接收TCP socket数据流
lines = ssc.socketTextStream("localhost", 9999)

# 下面是实时处理的过程,单词计数
words = lines.flatMap(lambda line: line.split(" "))
pairs = words.map(lambda word: (word, 1))
wordCounts = pairs.reduceByKey(lambda x, y: x + y)
wordCounts.map(lambda x: (x[0].encode('utf-8'), x[1])).pprint()

# 启动应用
ssc.start()
# 等待应用结束
ssc.awaitTermination()

接下来,启动NetCat工具,创建一个端口号为9999的服务器,代码如下图所示:

然后,在另一个终端的命令行,提交上面写的NetworkWordCount.py代码,如下图:

然后,在NetCat工具启动的终端,输入一些字符,作为实时流,如下图:

观察代码提交的终端,结果如下:

可以看到,进行了实时数据处理。

2. 本地文件系统作为实时数据流

上面这个例子中,实时数据流是TCP socket数据流,下面测试一下数据源为本地文件系统的情形。做法是:通过一个shell脚本,产生虚拟的日志文件。SparkStreaming实时处理这些日志文件。

实时处理数据流的FileWordCount.py文件代码如下

# -*- coding: utf-8 -*-

from pyspark import SparkContext
from pyspark.streaming import StreamingContext


sc = SparkContext("local[2]", "NetworkWordCount")
sc.setLogLevel("WARN")
# 设置时间为10秒
ssc = StreamingContext(sc, 10)

# 数据源
lines = ssc.textFileStream("file:///InputFile/")

# 依然是WordCount实例
words = lines.flatMap(lambda line: line.split(" "))
pairs = words.map(lambda word: (word, 1))
windowWordCounts = pairs.reduceByKey(lambda x, y: x + y)
windowWordCounts.map(lambda x: (x[0].encode('utf-8'), x[1])).pprint()

ssc.start()
ssc.awaitTermination()

在一个终端(终端1)提交代码,命令如下图:

产生虚拟日志文件的shell脚本(create_fake_log.sh)代码如下:

#!/bin/bash
cd ~/InputFile
rm * -f
i=0
while(( 1 > 0 ))
do
    touch input$i.log
    time=$(date "+%Y-%m-%d %H:%M:%S")
    echo ${time} > input$i.log;
    echo "write into input$i.log"
    stime=`expr $RANDOM % 10`
    stime=`expr $stime % 3`
    sleep $stime
    i=`expr $i + 1`
done

注意,shell脚本需要赋予权限,才可以执行。chmod 777 create_fake_log.sh

这个脚本,进入InputFile目录,然后通过死循环,实时产生input*.log文件,然后写入当前的日期和时间,然后随机休眠几秒钟。下面,执行这个脚本,模拟产生实时数据流,如下:

在另一个终端(终端2),执行这个脚本,如下图:

然后观察终端1的结果,如下图:

可以继续观察,日志文件是不断产生的(由于脚本的死循环),SparkStreaming对这个数据流的处理也是实时的。

猜你喜欢

转载自blog.csdn.net/ten_sory/article/details/82185649