初识Spark Streaming

参考官网:http://spark.apache.org/streaming/

Spark Streaming特点

Spark Streaming makes it easy to build scalable fault-tolerant streaming applications.
Spark Streaming使得 去构建可扩展的能容错的流式应用程序 变得容易。
(RDD容错体现在哪些方面?)
特点:

  • Ease of Use易用性
    可以通过高级别的API操作进行构建应用程序,可以像写批处理(离线处理)的job那样去写Streaming job,比如你会core、sql,在这里很相似。
  • Fault Tolerance容错机制
    Spark Streaming不需要额外的代码,就可以恢复挂掉的工作流以及操作的状态。
  • Spark Integration Spark集成
    能够把Streaming和批处理和交互式查询综合起来使用。通过在Spark上运行,Spark流允许您重用相同的代码进行批处理、根据历史数据连接流,或者对流状态运行即席查询。构建强大的交互式应用程序,而不仅仅是分析。比如假如你之前用的是批处理,现在要修改成流式处理,什么业务逻辑代码都不需要改变,那么只要把代码稍微修改一下,改一下输入输出即可。
  • 运行模式多种多样,可以从HDFS, Flume, Kafka, Twitter and ZeroMQ上读取数据,也可以自定义数据源,可以跑在standalone上,yarn上等等。

常用的模式是:Flume→消息队列(比如Kafka)→Spark Streaming

Spark Streaming概览

参考官网:http://spark.apache.org/docs/latest/streaming-programming-guide.html

Spark Streaming是Spark core API的扩展,它的底层还是Spark RDD来实现的,它支持对实时数据流进行可横向扩展、高吞吐量、容错的流处理。
既然是数据流,肯定有输入、处理和输出。
输入:Spark Streaming数据可以有很多数据源:Kafka, Flume, Kinesis, or TCP sockets,工作中用的比较多的是Kafka、TCP 。
处理:数据进来后可以被Spark Streaming的引擎处理,这些进来的数据可以被复杂的算法去处理,这些算法是用高级别的函数来表达的,比如: map, reduce, join and window这些函数。
输出:最后被处理后的数据,可以被吐到文件系统、数据库、实时dashboards上去。
另外:在Spark Streaming纸上可以使用机器学习和图计算的处理算法。这也验证了Spark Streaming可以和Spark生态圈里的框架做很好的集成,可以混合起来使用。
源可以分为有receiver和没有receiver,后面会讲到。
在这里插入图片描述

实质上,Spark Streaming的工作原理如下:Spark Streaming接收实时输入数据流,并将数据分为批(把数据切开,切成一个一个的批次),然后由Spark engine进行处理,最后也是以批次(一批一批的)的形式,产生最终的结果流。(其实就是mini batch微批处理)
这说明Spark Streaming并不是真正的实时处理的框架,它会每隔多少时间比如10秒,批处理一次,微批处理。
对于Spark,可以这样说:Spark是以批处理为准,使用微批来解决实时问题。

而Flink,以Stream实时为主,来解决批处理/离线问题。
在这里插入图片描述
上图:一个持续的数据流(就是一个DStream)输入进来,通过Spark Streaming进行设置,比如几秒钟读一次,把数据流按照时间划分为一个一个的批次(就是一个一个的RDD),由Spark engine进行处理,最后以一批一批的输出。

Internally, a DStream is represented as a sequence of RDDs.
Spark Streaming提供了一种高级抽象,它叫做discretized stream 或者 DStream,它是Spark Streaming进行开发的时候一个顶级的接口,DStream代表了持续的数据流(数据会源源不断的过来)。DStreams可以从数据源进行创建,比如 Kafka, Flume, and Kinesis,在其它DStreams上面作用于一个高级别的操作来产生一个DStreams。实质上,一个DStream代表了一个RDD的sequence,就是说一个DStream是由n多个RDD的sequence所构成的。

Spark Streaming:不同的数据源经过Spark Streaming处理之后,将结果输出到某个地方上去。

在这里插入图片描述
小知识点:部署了Spark就不需要再单独部署Spark Streaming,Spark Streaming是Spark里的一个模块。
面试:有了storm,你为什么还要去使用Spark Streaming?

Spark Streaming应用场景

比如电商上面,淘宝、京东、天猫等,上面推荐等(也可以使用storm等)。
再比如:公司的系统有很多,系统会采用log4j这样的日志框架,把日志输出,输出的日志分布在各个节点之上,节点有很多很多,整个是个大集群。那么如何把这些日志采集过来,用流处理进行分析?比如从log里面,把error的信息给搜集过来,error又分为好多种,这个时候可以为error打个标签,什么样的error做什么样的处理,根据error发送短信或者邮件,a error发送给这些人,b error发送给那些人。

流处理过程

一般用Flume采集来的数据,可以分为两个方向:
在这里插入图片描述
前面Flume通过Kafka sink到Kafka topic是属于Flume,后面Kafka到SparkStreaming,是属于SparkStreaming的内容。

Spark Streaming案例

数据源为TCP socket(演示一下,生产上很少用这种方式),数据内容为word,统计word的数量,然后打印出来。


需要添加依赖:

    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-streaming_2.11</artifactId>
      <version>${spark.version}</version>
    </dependency>


先导入相关的类、隐式转换。
导入包:

import org.apache.spark._
import org.apache.spark.streaming._
import org.apache.spark.streaming.StreamingContext._


Spark core RDD里面要有一个SparkContext,SparkSQL DF/DS里面有SparkSession,在Spark Streaming里面要有StreamingContext。
StreamingContext是所有streaming功能的入口点,创建一个StreamingContext,设置成两个执行线程、每秒一个批次。
(spark2.x之后,可以使用统一的SparkSession)

object ExampleStreamingApp {
  def main(args: Array[String]): Unit = {
    val conf = new SparkConf().setMaster("local[2]").setAppName("ExampleStreamingApp")
    val ssc = new StreamingContext(conf, Seconds(1))

//TODO业务逻辑。。。。

    ssc.start()
    ssc.awaitTermination()
  }
}

④业务逻辑

package com.ruozedata.spark.com.ruozedata.spark.streaming
import org.apache.spark._
import org.apache.spark.streaming._
import org.apache.spark.streaming.StreamingContext._

//这个作业是一直在跑的,一直在运行的,这个不是离线的,离线是跑完作业就没了,就会停下来
//这个作业要是停掉了,数据就接收不了,就会丢的
object ExampleStreamingApp {
  def main(args: Array[String]): Unit = {
    //这个master要是2个core
    val conf = new SparkConf().setMaster("local[2]").setAppName("ExampleStreamingApp")
    val ssc = new StreamingContext(conf, Seconds(10))
    //批次的时间是10秒,10秒处理一次


    //这个是把server数据源转换成了DStream
    val lines = ssc.socketTextStream("hadoop001",9999)

    //下面就是之前的wordcount代码
    val words = lines.flatMap(_.split(" "))
    val pairs = words.map(word => (word, 1))
    val wordCounts = pairs.reduceByKey(_ + _)

    //把这个DStream产生的每个RDD的前10个元素打印到控制台上
    wordCounts.print()


    //开始计算
    ssc.start()
    //等待计算结束
    ssc.awaitTermination()

  }
}

小知识点:

  def socketTextStream(
      hostname: String,
      port: Int,
      //默认存储级别为:内存、磁盘序列化 2  ,这个和Spark core里面不一样
      storageLevel: StorageLevel = StorageLevel.MEMORY_AND_DISK_SER_2
    ): ReceiverInputDStream[String] = withNamedScope("socket text stream") {
    socketStream[String](hostname, port, SocketReceiver.bytesToLines, storageLevel)
  }

上面运行起来之后,要在命令行启动Netcat,在控制台输入:

//如果没有nc命令,需要yum install 安装一下
[root@hadoop001 ~]# nc -lk 9999
aaa bbb aaa  bbb
aaa
bb  cc  aaa
//这个是时间戳,可以转换为我们平时看到的时间的
-------------------------------------------
Time: 1564322940000 ms
-------------------------------------------
-------------------------------------------
Time: 1564322960000 ms
-------------------------------------------
-------------------------------------------
Time: 1564323020000 ms
-------------------------------------------
(bbb,2)
(,3)
(bb,1)
(cc,1)
(aaa,4)

看页面:http://localhost:4040
在这里插入图片描述
下面这个Streaming在调优的时候必须要用到的
Streaming Statistics 流处理统计信息
Running batches of 10 seconds for 9 minutes 32 seconds since 2019/07/28 22:05:09 (58 completed batches, 11 records)
从什么时候开始运行了多少个批次。
从下面可以看到, Input Rate、SocketReceiver-0、Scheduling Delay、Processing Time、Total Delay信息。这些信息很重要的。
在生产上面,如果kafka过来的数据太多,可能会有很大的延迟。在生产上面,想办法要去保证一个批次的作业在一个批次里把它完成。如果保证不了,就是说,这个批次没有完成,那么下个批次又来了,那么后面会越积越多。(可以是kafka限速,或者Spark Streaming限流与背压原理)
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值