简述
Spark Streaming是核心Spark API的扩展,近实时计算框架。特点可伸缩,高吞吐量,容错流处理。而我们之前讲的Spark SQL是负责处理离线数据。
既然是计算框架,那么实战的过程中还是三个步骤,读取数据源、计算数据、数据存储:
数据源:可以从Kafka, Flume, Kinesis, or TCP sockets等数据源读入
数据计算:同样可以使用同样的map,reduce,join等算子进行数据计算,还有Spark Streaming 特有的window窗口函数。
数据存储:可以将处理后的数据推送到文件系统HDFS,数据库的话比较常用的是MySQL,Mongo DB和HBase等,对于实时数据的展示和监控方面,我们比较常用的是将数据写入Elasticsearch中,并且使用Kibana或者Grafana来进行展示。
Spark Streaming 提供一个对于流数据的抽象 DStream。DStream 可以由来自 Apache Kafka、Flume 或者 HDFS 的流数据生成,也可以由别的 DStream 经过各种转换操作得来,底层 DStream 也是由很多个序列化的 RDD 构成,按时间片(比如一秒)切分成的每个数据单位都是一个 RDD。
然后,Spark 核心引擎将对 DStream 的 Transformation 操作变为针对 Spark 中对 RDD 的 Transformation 操作,将 RDD 经过操作变成中间结果保存在内存中。之前的 DataFrame 和 DataSet 也是同样基于 RDD,所以说 RDD 是 Spark 最基本的数据抽象。就像 Java 里的基本数据类型(Primitive Type)一样,所有的数据都可以用基本数据类型描述。也正是因为这样,无论是 DataFrame,还是 DStream,都具有 RDD 的不可变性、分区性和容错性等特质。
所以,Spark 是一个高度统一的平台,所有的高级 API 都有相同的性质,它们之间可以很容易地相互转化。Spark 的野心就是用这一套工具统一所有数据处理的场景。由于 Spark Streaming 将底层的细节封装起来了,所以对于开发者来说,只需要操作 DStream 就行。接下来,让我们一起学习 DStream 的结构以及它支持的转换操作
对比
一般在讲述Spark Streaming的时候,其他博主都会列一个表格,将Storm,Spark Streaming,Flink三个实时计算框架进行对比,这里我就不进行三者之间的比较了,直接根据我这几年使用的经验来分享一下直接的结果,
Storm是一个早期的流式计算框架,可以做到毫秒级别的计算,但是编程语言使用的是Java,代码量很多,编程复杂度会高一些,并且目前很少有公司使用Storm,我实习期后,在第一家公司的第一个任务就是改写现有的Storm任务,迁移到Spark Streaming。
Spark Streaming的流式计算,准确的来讲,可以说是近实时或者微批计算,所以在一般情况下,对于时间要求不是太严格的情况下,Spark Streaming可以满足大部分的场景了。支持Java,Scala, Python三种语言。但是Spark Streaming有一个缺点,就是某些需求中,我们的计算结果应该是基于event time数据产生时间,但是在Spark Streaming中,有时会因为延迟的原因,计算结果会基于process time 数据到达的时间。针对这个问题,我在后面的Structured Streaming也会讲到。
Flink可以说是流式计算的后起之秀,并且就是为了流计算而诞生,它采用了基于操作符(Operator)的连续流模型,可以做到微秒级别的延迟。同样支持Java,Scala,Python三种语言,在我还认认真真写Spark代码的时候,每天都能看到铺天盖地的Flink新闻,Flink 用流处理去模拟批处理的思想,比 Spark 用批处理去模拟流处理的思想扩展性更好,所以我相信将来 Flink 会发展的越来越好,生态和社区各方面追上 Spark。比如,阿里巴巴就基于 Flink 构建了公司范围内全平台使用的数据处理平台 Blink,美团、饿了么等公司也都接受 Flink 作为数据处理解决方案。
实例
这里用一个实例来展示一下实际工作中,Spark Streaming的大概流程:
数据的采集或者网站数据收集—>Kafka—>Spark Streaming—>show data or save data
下面这端python代码是数据采集或者收集,打到Kafka的阶段。我本想写个爬虫来做实时数据的,但是我想起来我的Elasticsearch集群中正在实时的爬取某博数据,所以就直接间隔调用ES,来打入Kafka中。
1 | # -*- coding: utf-8 -*- |
打入数据的格式:
1 | {'datetime': '2017-04-10 18:29:42', 'keywordList': '特朗普,得志,领头羊,治国,爱心,美国,本领'} |
下面的spark streaming代码比较简单,只是读取数据,从json格式中解析出来,随后打印,这里我没有直接写入的数据库或者es中,主要是给出一个spark streaming的程序框架。
1 | package streaming |
1 | 手机,安卓,像素,摄像头,国产品牌,品牌,华为,小米,旗舰,英寸,屏幕,电池容量,对焦,逆光,音质,系统,后置,机身,光线,光学 |