Spark Streaming 是一个分布式数据流处理框架,它可以近乎实时的处理流数据,它易编程,可以处理大量数据,并且能把实时数据与历史数据结合起来处理。

Streaming 使得 spark 具有了流式处理的能力,它为数据流式处理提供了高层抽象,底层仍然是 spark,所以它具有 spark 的可扩展、可容错、高吞吐量的特点,而且它可以与 spark 的各种库结合使用,如 sparkSQL、MLib、ml 等

总体架构

Spark Streaming 是一个伪实时的流处理框架,它处理的是一个微批次的数据流,就是说他把数据流按照非常小的时间间隔切分成一批一批的数据,然后每次处理一批数据;

每一批数据仍然以 RDD 方式存储,然后使用 spark core 进行处理;

RDD 操作结果也是一批一批的输出;

数据流来源

Streaming 支持多种数据流来源,比较常用的有 TCP网络传输、Kafa、Flume 等,还有 Twitter、ZeroMQ、MQTT 等,

它也可以把一个文件当成流来处理,

也可以自定义数据流来源;

流数据经过 spark 处理后可以流向各种地方;

总结一下如下图

接收器

也叫数据采集器,接收器收到数据后存储在内存中;

Streaming 在每个 worker 上为每个数据流来源创建一个接收器;

一个 spark 应用可以同时接收多个数据流来源,然后统一处理;

API

Streaming API 有两个高度抽象 StreamingContext 和 离散流 DStream

StreamingContext

他是 Streaming 库的入口点,使得 Streaming 连接到 spark 上;

每个 Streaming 应用必须先创建一个 StreamingContext 实例;

创建 StreamingContext 实例

创建方法和 SparkContext 一样,创建 sc 的方法都能用来创建 StreamingContext;

不同的是多了一个参数,指定划分数据流的时间间隔;

from pyspark import SparkContext, StreamingContext, SparkConf
conf = SparkConf().setAppName('myapp1').setMaster('local[4]') # 设定 appname 和 master
ssc = StreamingContext(conf=conf, 10) # 10s 间隔 ## 或者这样
sc = SparkContext(conf=conf)
ssc = StreamingContext(sc, 10) # 直接传入 sc

StreamingContext 实例的方法

ssc.start()     # 启动 流式计算,在这之前,什么也不会发生
ssc.checkpoint('hdfs path') # 定期创建检查点数据,输入为 hdfs 的路径
ssc.stop() # 停止 流式计算
ssc.awaitTermination() # 等待流式计算结束

checkpoint

DStream     【内容比较多,故单独一章】

离散数据流;

他是 Streaming 处理数据流的一个高度抽象,也是一个抽象类,并且定义了一系列对该类的操作;

不同数据流来源有不同的 DStream 类;

DStream 实际上是一个 RDD 序列,Spark Streaming 把对 DStream 的操作转换成对 RDD 的操作;

因为他是 RDD 序列,所以具有 RDD 的特点:不可变、分区、容错

创建 DStream 实例

DStream 创建有两种方式,一种是从数据流来源直接创建,一种是从现有的 DStream 对象转换得到

socketTextStream:创建一个从 TCP 套接字连接 接收数据流的 DStream

3 个参数,host,port,第三个可选,指定接收数据的存储等级

def socketTextStream(self, hostname, port, storageLevel=StorageLevel.MEMORY_AND_DISK_2)

默认的存储等级为 StorageLevel.MEMORY_AND_DISK_2,顾名思义,表示接收到的数据先存储在内存中,如果内存放不下,多出来的数据会存放到硬盘上;

而且他会对接收到的数据 以 spark 序列化的方式 进行序列化操作;

所以这个存储等级会有序列化的开销,但是减少了 jvm 垃圾回收相关的问题;

接收到的数据会复制多份,提高容错;

选择合适的存储等级可以提高性能,比如 Streaming 采集周期很短,如几秒钟,也就是数据量很小,那么可以指定存储等级为只内存存储 StorageLevel.MEMORY_ONLY

textFileStream:创建一个 DStream 用于监控 hadoop 兼容的文件系统中是否有新文件创建

输入为被监控的目录;

如果有新文件创建,则将作为文本文件读出;

注意,写入被监控目录的文件必须是从同等文件系统中移动过来的,比如 linux 系统,新文件必须是用 mv 命令移动过来的

def textFileStream(self, directory)

actorStream:用户自己定义的 Akka actor 接收器的 DStream

python 好像没这个

KafkaUtils:创建从 Kafka 接收数据流的 DStream

class KafkaUtils(object):

    @staticmethod
def createStream(ssc, zkQuorum, groupId, topics, kafkaParams=None,
storageLevel=StorageLevel.MEMORY_AND_DISK_2,
keyDecoder=utf8_decoder, valueDecoder=utf8_decoder):
"""
Create an input stream that pulls messages from a Kafka Broker. :param ssc: StreamingContext object
:param zkQuorum: Zookeeper quorum (hostname:port,hostname:port,..).
:param groupId: The group id for this consumer.
:param topics: Dict of (topic_name -> numPartitions) to consume.
Each partition is consumed in its own thread.
:param kafkaParams: Additional params for Kafka
:param storageLevel: RDD storage level.
:param keyDecoder: A function used to decode key (default is utf8_decoder)
:param valueDecoder: A function used to decode value (default is utf8_decoder)
:return: A DStream object

还有一些其他的,参考 pyspark

DStream 操作

内容比较多,后面会专门写一篇博客

DStream 输出

Dstream 可以输出到各种地方,如文件、数据库或者其他应用程序

输出到文件

saveAsTextFiles:将 DStream 保存成文件,他为每个 RDD 创建一个目录,并在每个目录里创建多个副本;

目录名称为 用户定义的前缀-时间戳-可选后缀

DStream.saveAsTextFiles('/usr/lib/text')

saveAsObjectFiles:将 DStream 以序列化对象的形式保存成二进制 SequenceFile 文件,用法同 saveAsTextFiles

saveAsHadoopFiles:只有由键值对组成的 DStream 才能使用该方法

saveAsNewAPIHadoopFiles:自己试试

输出到控制台

pprint(n):打印指定输出元素个数

输出到数据库

foreachRDD:输入一个 func 逐个处理 DStream 中的每一个 RDD;

该方法无需返回任何东西;

    def foreachRDD(self, func):
"""
Apply a function to each RDD in this DStream.
"""
if func.__code__.co_argcount == 1:
old_func = func
func = lambda t, rdd: old_func(rdd)
jfunc = TransformFunction(self._sc, func, self._jrdd_deserializer)
api = self._ssc._jvm.PythonDStream
api.callForeachRDD(self._jdstream, jfunc)

对于 foreachRDD 需要理解的是:

1. func 是把 RDD 作为输入,并且可以使用 RDD 的所有操作;

2. foreachRDD 执行在 Driver 中,而 func 执行在 Executor 中;

3. foreachRDD 不仅仅用于存到数据库

存储到数据库需要注意的是:

1. 数据库连接比较耗时,不要频繁的连接、关闭

2. 数据库连接无法序列化,也就是无法从 Driver 发送给 Executor,故数据库连接只能在 worker 上创建,并且复用

3. RDD 的 foreachPartition 操作可以使用同一个数据库连接保存多个 DStream 中的元素,可在 func 中使用该方法

4. 利用数据库连接池进行优化

5. 也可以采用批量写入的方法来优化数据库存储

示例代码

数据流来源是 TCP 套接字

from __future__ import print_function
import sys from pyspark import SparkContext
from pyspark.streaming import StreamingContext if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: network_wordcount.py <hostname> <port>", file=sys.stderr)
sys.exit(-1) sc = SparkContext(appName="PythonStreamingNetworkWordCount")
# 以指定时间为周期采集实时数据
ssc = StreamingContext(sc, 30) # 采集周期为 x s ### 连接已经开启的 socket 服务器,注意必须事先开启 socket server
lines = ssc.socketTextStream(sys.argv[1], int(sys.argv[2])) # 采集数据
counts = lines.flatMap(lambda line: line.split(" "))\
.map(lambda word: (word, 1))\
.reduceByKey(lambda a, b: a+b)
counts.pprint() # 打印 DStream
## 如
# (u'a', 1)
# (u'e', 1)
# (u'd', 1)
counts.pprint(2) # 打印 DStream,并指定输出元素个数
## 如果 pprint 输出如上,pprint(2)输出如下
# (u'a', 1)
# (u'e', 1)
counts.saveAsTextFiles('/usr/lib/text') # DStream 保存至文件系统 ssc.checkpoint('/spark') ssc.start() # 启动采集器
ssc.awaitTermination() # 等待 socket ser 终止

TCP 服务器要事先存在,在 linux 上使用如下命令建立 TCP 服务器

nc -lk 9999

注意 nc 命令需要手动安装

数据流来源是 Kafka

import time
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.streaming.kafka import KafkaUtils
from operator import add sc = SparkContext(master="yarn",appName="PythonSparkStreamingRokidDtSnCount")
ssc = StreamingContext(sc, 2)
zkQuorum = '172.16.89.80:2181' # broker list
topic = {'':1} # topic name : partition
groupid = "test-consumer-group" # consumer group
lines = KafkaUtils.createStream(ssc, zkQuorum, groupid, topic)
lines1 = lines.flatMap(lambda x: x.split("\n"))
valuestr = lines1.map(lambda x: x.value.decode())
valuedict = valuestr.map(lambda x:eval(x))
message = valuedict.map(lambda x: x["message"])
rdd2 = message.map(lambda x: (time.strftime("%Y-%m-%d",time.localtime(float(x.split("\u0001")[0].split("\u0002")[1])/1000))+"|"+x.split("\u0001")[1].split("\u0002")[1],1)).map(lambda x: (x[0],x[1]))
rdd3 = rdd2.reduceByKey(add)
rdd3.saveAsTextFiles("/tmp/wordcount")
rdd3.pprint()
ssc.start()
ssc.awaitTermination()

其他场景参考 spark 自带的样例

参考资料:

《Spark大数据分析核心概念技术及实践OCR-2017》  电子书

spark教程(15)-Streaming的更多相关文章

  1. spark教程(16)-Streaming 之 DStream 详解

    DStream 其实是 RDD 的序列,它的语法与 RDD 类似,分为 transformation(转换) 和 output(输出) 两种操作: DStream 的转换操作分为 无状态转换 和 有状 ...

  2. Spark教程——(11)Spark程序local模式执行、cluster模式执行以及Oozie/Hue执行的设置方式

    本地执行Spark SQL程序: package com.fc //import common.util.{phoenixConnectMode, timeUtil} import org.apach ...

  3. [SQL基础教程] 1-5 表的删除和更新

    [SQL基础教程] 1-5 表的删除和更新 表的删除 语法 DROP TABLE <表名>; 法则 1-12 删除的表无法恢复 表定义的更新 语法 ALTER TABLE<表名> ...

  4. spark教程

    某大神总结的spark教程, 地址 http://litaotao.github.io/introduction-to-spark?s=inner

  5. Real Time Credit Card Fraud Detection with Apache Spark and Event Streaming

    https://mapr.com/blog/real-time-credit-card-fraud-detection-apache-spark-and-event-streaming/ Editor ...

  6. [译]Vulkan教程(15)图形管道基础之RenderPass

    [译]Vulkan教程(15)图形管道基础之RenderPass Render passes Setup 设置 Before we can finish creating the pipeline, ...

  7. Directx11教程(15) D3D11管线(4)

    原文:Directx11教程(15) D3D11管线(4) 本章我们首先了解一下D3D11中的逻辑管线,认识一下管线中每个stage的含义. 参考资料:http://fgiesen.wordpress ...

  8. WARN deploy.SparkSubmit$$anon$2: Failed to load org.apache.spark.examples.sql.streaming.StructuredNetworkWordCount.

    前言 今天运行Spark Structured Streaming官网的如下 ./bin/run-example org.apache.spark.examples.sql.streaming.Str ...

  9. 深度学习与计算机视觉教程(15) | 视觉模型可视化与可解释性(CV通关指南·完结)

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

随机推荐

  1. js基础( js嵌入方式、输出语句)

    s现在的作用 1.验证表单(以前的网速慢)  2.页面特效 (PC端的网页效果)  3.移动端 (移动 web 和app)  4.异步和服务器交互(ajax)  5.服务器端开发 (nodejs)   ...

  2. DMA数据传输

    从字面意思上看,DMA即为“直接内存读取”的意思,换句话说DMA就是用来传输数据的,它也属于一个外设.只是在传输数据时,无需占用CPU. 高速IO设备可以在处理器安排下直接与主存储器成批交换数据,称为 ...

  3. SRS之SrsRtmpConn::stream_service_cycle详解

    首先使用 obs 推流符合如下流程:参考自 Hanvision Makito X cann't publish to SRS.. FFMPEG: C/S: Handshake C: ConnectAp ...

  4. 爬取百度网盘资源报user is not authorized, hitcode:119

    爬取百度网盘资源报user is not authorized, hitcode:119 一.总结 一句话总结: 可能是百度网盘禁止非客户端环境下载大文件,所以将请求头改为客户端:'User-Agen ...

  5. kentico中page alias的使用

    这里设置的path or pattern,是针对于根目录而言的

  6. 自定义可拖动的Toast

    package com.loaderman.toastdemo; import android.content.Context; import android.graphics.PixelFormat ...

  7. spring mvc路径匹配原则

    Ant path 匹配原则 在Spring MVC中经常要用到拦截器,在配置需要要拦截的路径时经常用到<mvc:mapping/>子标签,其有一个path属性,它就是用来指定需要拦截的路径 ...

  8. 小D课堂 - 新版本微服务springcloud+Docker教程_3-02CAP理论知识

    笔记 2.分布式应用知识CAP理论知识     简介:讲解分布式核心知识CAP理论 CAP定理:             指的是在一个分布式系统中,Consistency(一致性). Availabi ...

  9. kvm的使用(2)

    一.远程管理kvm虚机 (2)有些情况下,有一个要配置的地方. 因为 KVM(准确说是 Libvirt)默认不接受远程管理,需要按下面的内容配置被管理宿主机中的两个文件: vim /etc/defau ...

  10. 在 Ubuntu 14.10 Server 上安装 Jetty

    Jetty提供了一个Web服务器和javax.servlet容器,为SPDY.WebSocket.OSGi.JMX.JNDI.JAAS以及许多其它集成套件添加了支持.这些组件都是开源的,也可用于商业用 ...