前言


Ref: 一文读懂 Spark 和 Spark Streaming【简明扼要的概览】

在讲解 "流计算" 之前,先做一个简单的回顾,亲!

一、MapReduce 的问题所在

MapReduce 模型的诞生是大数据处理从无到有的飞跃。但随着技术的进步,对大数据处理的需求也变得越来越复杂,MapReduce 的问题也日渐凸显。

通常,我们将 MapReduce 的输入和输出数据保留在 HDFS 上,很多时候,复杂的 ETL、数据清洗等工作无法用一次 MapReduce 完成,所以需要将多个 MapReduce 过程连接起来:

Figure,上图中只有两个 MapReduce 串联,实际上可能有几十个甚至更多,依赖关系也更复杂。

这种方式下,每次中间结果都要写入 HDFS 落盘保存,代价很大(别忘了,HDFS 的每份数据都需要冗余若干份拷贝)。

另外,由于本质上是多次 MapReduce 任务,调度也比较麻烦,实时性无从谈起。

二、Spark 与 RDD 模型

Fault-tolerance

一般来说,想做到 fault-tolerance 只有两个方案:

    1. 要么存储到外部(例如 HDFS),
    2. 要么拷贝到多个副本。
    3. Spark 大胆地提出了第三种——重算一遍。

但是之所以能做到这一点,是依赖于一个额外的假设:所有计算过程都是确定性的(deterministic)。

Spark 借鉴了函数式编程思想,提出了 RDD(Resilient Distributed Datasets),译作“弹性分布式数据集”。

Figure,上图演示了 RDD 分区的恢复。为了简洁并没有画出分区,实际上恢复是以分区为单位的。

只读的、分区的 数据集合

RDD 的数据由多个分区(partition)构成,这些分区可以分布在集群的各个机器上,这也就是 RDD 中 “distributed” 的含义。

熟悉 DBMS(数据库管理系统)的同学可以把 RDD 理解为逻辑执行计划,partition 理解为物理执行计划。

窄依赖 & 宽依赖

之前有涉及到一部分内容:[Spark] 01 - What is Spark

简单的说,宽依赖就是 "一对多“。

在执行时,窄依赖可以很容易的按流水线(pipeline)的方式计算:对于每个分区从前到后依次代入各个算子即可。

然而,宽依赖需要等待前继 RDD 中所有分区计算完成;

换句话说,宽依赖就像一个栅栏(barrier)会阻塞到之前的所有计算完成。整个计算过程被宽依赖分割成多个阶段(stage),如上右图所示。

声明式编程 - Spark SQL

命令式 & 声明式 编程:声明式的要简洁的多!但声明式编程依赖于执行者产生真正的程序代码,所以除了上面这段程序,还需要把数据模型(即 schema)一并告知执行者。

声明式编程最广为人知的形式就是 SQL。Spark SQL 就是这样一个基于 SQL 的声明式编程接口。

你可以将它看作在 Spark 之上的一层封装,在 RDD 计算模型的基础上,提供了 DataFrame API 以及一个内置的 SQL 执行计划优化器 Catalyst。

代码生成(codegen)转化成直接对 RDD 的操作

DataFrame 就像数据库中的表,除了数据之外它还保存了数据的 schema 信息。

Catalyst 是一个内置的 SQL 优化器,负责把用户输入的 SQL 转化成执行计划。

Catelyst 强大之处是它利用了 Scala 提供的代码生成(codegen)机制,物理执行计划经过编译,产出的执行代码效率很高,和直接操作 RDD 的命令式代码几乎没有分别。

上图是 Catalyst 的工作流程,与大多数 SQL 优化器一样是一个 Cost-Based Optimizer (CBO),但最后使用代码生成(codegen)转化成直接对 RDD 的操作。

流计算框架:Spark Streaming


基本认识

一、批处理 & 流计算

"批处理"和"流计算"被看作大数据系统的两个方面。

    • 以 Kafka、Storm 为代表的流计算框架用于实时计算,
    • 而 Spark 或 MapReduce 则负责每天、每小时的数据批处理。

在 ETL 等场合,这样的设计常常导致同样的计算逻辑被实现两次,耗费人力不说,保证一致性也是个问题。

Spark Streaming 基于 Spark,另辟蹊径提出了 D-Stream(Discretized Streams)方案:将流数据切成很小的批(micro-batch),用一系列的短暂、无状态、确定性的批处理实现流处理。

开发者只需要维护一套 ETL 逻辑即可同时用于批处理和流计算。

更快速的失败恢复

The figure,

    • 左图,为了在持续算子模型的流计算系统中保证一致性,不得不在主备机之间使用同步机制,导致性能损失,Spark Streaming 完全没有这个问题;
    • 右图,D-Stream 的原理示意图。

实际上,新的状态 RDD 总是不断生成,而旧的 RDD 并不会被“替代”,而是作为新 RDD 的前继依赖。

对于底层的 Spark 框架来说,并没有时间步的概念,有的只是不断扩张的 DAG 图和新的 RDD 节点。

Spark SQL 之 流处理

Spark 通过 Spark Streaming 拥有了流计算能力,那 Spark SQL 是否也能具有类似的流处理能力呢?答案是肯定的。

只要将数据流建模成一张不断增长、没有边界的表,在这样的语义之下,很多 SQL 操作等就能直接应用在流数据上。

出人意料的是,Spark Structured Streaming 的流式计算引擎并没有复用 Spark Streaming,而是在 Spark SQL 上设计了新的一套引擎。

因此,从 Spark SQL 迁移到 Spark Structured Streaming 十分容易,但从 Spark Streaming 迁移过来就要困难得多。

基于这样的模型,Spark SQL 中的大部分接口、实现都得以在 Spark Structured Streaming 中直接复用。

将用户的 SQL 执行计划转化成流计算执行计划的过程被称为增量化(incrementalize),这一步是由 Spark 框架自动完成的。

对于用户来说只要知道:每次计算的输入是某一小段时间的流数据,而输出是对应数据产生的计算结果。

二、窗口(window)

窗口(window)是对过去某段时间的定义。

批处理中,查询通常是全量的(例如:总用户量是多少);而流计算中,我们通常关心近期一段时间的数据(例如:最近24小时新增的用户量是多少)。

用户通过选用合适的窗口来获得自己所需的计算结果,常见的窗口有滑动窗口(Sliding Window)、滚动窗口(Tumbling Window)等。

三、水位(watermark)

水位(watermark)用来丢弃过早的数据。

在流计算中,上游的输入事件可能存在不确定的延迟,而流计算系统的内存是有限的、只能保存有限的状态,一定时间之后必须丢弃历史数据。

以双流 A JOIN B 为例,假设窗口为 1 小时,那么 A 中比当前时间减 1 小时更早的数据(行)会被丢弃;如果 B 中出现 1 小时前的事件,因为无法处理只能忽略。

四、三个角色

Spark 中有三个角色:Driver, Worker 和 Cluster Manager。

  • 驱动程序(Driver)即用户编写的程序,对应一个 SparkContext,负责任务的构造、调度、故障恢复等。驱动程序可以直接运行在客户端,例如用户的应用程序中;也可以托管在 Master 上,这被称为集群模式(cluster mode),通常用于流计算等长期任务。
  • Cluster Manager 顾名思义负责集群的资源分配,Spark 自带的 Spark Master 支持任务的资源分配,并包含一个 Web UI 用来监控任务运行状况。多个 Master 可以构成一主多备,通过 ZooKeeper 进行协调和故障恢复。通常 Spark 集群使用 Spark Master 即可,但如果用户的集群中不仅有 Spark 框架、还要承担其他任务,官方推荐使用 Mesos 作为集群调度器。
  • Worker节点 负责执行计算任务,上面保存了 RDD 等数据。

五、总结

Spark 是一个同时支持批处理和流计算的分布式计算系统。Spark 的所有计算均构建于 RDD 之上,RDD 通过算子连接形成 DAG 的执行计划,RDD 的确定性及不可变性是 Spark 实现故障恢复的基础。Spark Streaming 的 D-Stream 本质上也是将输入数据分成一个个 micro-batch 的 RDD。

Spark SQL 是在 RDD 之上的一层封装,相比原始 RDD,DataFrame API 支持数据表的 schema 信息,从而可以执行 SQL 关系型查询,大幅降低了开发成本。

Spark Structured Streaming 是 Spark SQL 的流计算版本,它将输入的数据流看作不断追加的数据行。

至此,通过 一文读懂 Spark 和 Spark Streaming 了解了大概框架和概念,下面继续”厦大“课程的学习,goto: 流计算概述

流计算概述

一、流计算特征

  • 快速到达,大小不定;
  • 来源众多,格式复杂;
  • 一次性处理,也可以之后丢弃;
  • 总体价值大于个别数据;
  • 顺序以及完整性不太重要;

二、流计算应用

对时间比较敏感,过去太久的数据,其价值迅速降低。比如:用户点击流

根据大数据,进行秒级响应进行商品推荐。

三、流计算框架

  • 高性能
  • 海量式
  • 实时性
  • 分布式
  • 可靠性
  • 商业级流计算平台:IBM StreamBase, IBM InfoSphere Streams
  • 开源流计算框架:Twitter Storm, Yahoo! S4
  • 定制流计算框架:Dstream (Baidu), Puma (Facebook)
  1. 数据实时采集(每秒数百MB的数据采集,such as Facebook Scribe, Linkedin Kafka, Chukwa, Flume
  2. 数据实时计算
  3. 数据实时服务

既然是实时结果,那自然是主动推送给用户,也就是实时推荐。

SparkStreaming解析

重要角色

DStream 角色

本质是“tiny batch processing",切分到秒级响应。

DStream就是一堆Tiny RDD的集合,使用”微小“批处理模拟流计算。

Receiver 角色

每个receiver 单独负责一个 Input DStream。

    • 套接字流
    • 文件流
    • 从Kafka中读取的输入流

Receiver监控这几种流,然后交给流计算组件去处理。

End.

[Spark] 06 - What is Spark Streaming的更多相关文章

  1. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  2. Spark小课堂Week2 Hello Streaming

    Spark小课堂Week2 Hello Streaming 我们是怎么进行数据处理的? 批量方式处理 目前最常采用的是批量方式处理,指非工作时间运行,定时或者事件触发.这种方式的好处是逻辑简单,不影响 ...

  3. 06、部署Spark程序到集群上运行

    06.部署Spark程序到集群上运行 6.1 修改程序代码 修改文件加载路径 在spark集群上执行程序时,如果加载文件需要确保路径是所有节点能否访问到的路径,因此通常是hdfs路径地址.所以需要修改 ...

  4. Spark练习之通过Spark Streaming实时计算wordcount程序

    Spark练习之通过Spark Streaming实时计算wordcount程序 Java版本 Scala版本 pom.xml Java版本 import org.apache.spark.Spark ...

  5. spark学习笔记总结-spark入门资料精化

    Spark学习笔记 Spark简介 spark 可以很容易和yarn结合,直接调用HDFS.Hbase上面的数据,和hadoop结合.配置很容易. spark发展迅猛,框架比hadoop更加灵活实用. ...

  6. hadoop之Spark强有力竞争者Flink,Spark与Flink:对比与分析

    hadoop之Spark强有力竞争者Flink,Spark与Flink:对比与分析 Spark是一种快速.通用的计算集群系统,Spark提出的最主要抽象概念是弹性分布式数据集(RDD),它是一个元素集 ...

  7. 【译】Spark官方文档——Spark Configuration(Spark配置)

    注重版权,尊重他人劳动 转帖注明原文地址:http://www.cnblogs.com/vincent-hv/p/3316502.html   Spark主要提供三种位置配置系统: 环境变量:用来启动 ...

  8. 【Spark学习】Apache Spark配置

    Spark版本:1.1.1 本文系从官方文档翻译而来,转载请尊重译者的工作,注明以下链接: http://www.cnblogs.com/zhangningbo/p/4137969.html Spar ...

  9. 【Spark学习】Apache Spark调优

    Spark版本:1.1.0 本文系以开源中国社区的译文为基础,结合官方文档翻译修订而来,转载请注明以下链接: http://www.cnblogs.com/zhangningbo/p/4117981. ...

随机推荐

  1. Net微信网页开发之使用微信JS-SDK获取当前地理位置

    前言: 前段时间有一个关于通过获取用户当前经纬度坐标,计算出该用户距离某指定地点之间的距离.因为做这个项目需要能够获取到比较精确的经纬度坐标,刚开始使用的是百度地图结果发现百度地图地位不太准确(有时候 ...

  2. SpringIoC和SpringMVC的快速入门

    更多内容,欢迎关注微信公众号:全菜工程师小辉~ Spring的优势? 降低了组件之间的耦合性 ,实现了软件各层之间的解耦 可以使用容易提供的众多服务,如事务管理,消息服务等 容器提供单例模式支持 容器 ...

  3. Vue仿微信app页面跳转动画

    10:14:11独立开发者在开发移动端产品时,为了更高效,通常会使用Web技术来开发移动端项目,可以同时适配Android.iOS.H5,稍加改动还可适配微信小程序. 在使用Vue.js开发移动端页面 ...

  4. 缓存系列-Redis入门教程

    Redis是什么? Redis (REmote DIctionary Server)是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列,是一个高性能的key-valu ...

  5. C#简单爬取数据(.NET使用HTML解析器ESoup和正则两种方式匹配数据)

    一.获取数据 想弄一个数据库,由于需要一些人名,所以就去百度一下,然后发现了360图书馆中有很多人名 然后就像去复制一下,发现复制不了,需要登陆 此时f12查看源码是可以复制的,不过就算可以复制想要插 ...

  6. Java中时间格式处理,指定N天/小时等之后的时间

    1)根据当前时间,获取具体的时刻的时间 N天前 M小时之前 可用 new Date().getTime() - 24 * 60 * 60 * 1000*N[N天之前]的方法来获取处理时间之后的具体的值 ...

  7. C/C++ 修改系统时间,导致sem_timedwait 一直阻塞的问题解决和分析

    修改系统时间,导致sem_timedwait 一直阻塞的问题解决和分析 介绍 最近修复项目问题时,发现当系统时间往前修改后,会导致sem_timedwait函数一直阻塞.通过搜索了发现int sem_ ...

  8. Java集合框架之TreeMap浅析

    Java集合框架之TreeMap浅析 一.TreeMap综述: TreeMap在Map中的结构如下:

  9. ZYNQ Block Design中总线位宽的截取与合并操作

    前言 在某些需求下,数据的位宽后级模块可能不需要原始位宽宽度,需要截位,而某些需求下,需要进行多个数据的合并操作. 在verilog下,截位操作可如下所示: wire [7:0] w_in; wire ...

  10. 求解区间问题的三种做法的区别 线段树、树状数组、RMQ

    树状数组主要用于计算区间的和,在区间元素修改值的时候能够快速修改而不是以O(n)的复杂度进行修改: 线段树是把区间以树的形式分拆为若干个小区间,每个小区间存的都有一个值(树状数组的元素存的是区间值), ...