概念对比
静态数据和流数据
静态数据,例如数据仓库中存放的大量历史数据,特点是不会发生更新,可以利用数据挖掘技术和 OLAP(On-Line Analytical Processing)工具从静态数据中找到有价值的信息
流数据,例如 Web 应用和电信金融等领域产生的数据,特点是数据以大量,快速,时变的流形式持续到达
从概念上说,流数据是指在时间分布和数量上无限的一系列动态数据的集合体;数据记录是流数据的最小组成单元
流数据具有以下特征
-
数据快速持续到达,潜在大小也许是无穷无尽的
-
数据来源众多,格式复杂
-
数据量大,但是不十分关注存储,数据流中的某个元素经过处理后可能被丢弃或归档
-
注重数据的整体价值,不过分关注个别数据
-
数据顺序颠倒或不完整,系统无法控制将要处理的新到达的数据元素的顺序
批量计算和实时计算
静态数据对应批量计算,流数据对应实时计算
批量计算以静态数据为对象,可以在较为充裕的时间内对海量数据进行批量处理,从数据中发掘出有价值的信息
Hadoop 就是典型的批处理模型,由 HDFS 和 HBase 存放大量静态数据,由 MapReduce 对它们执行批量计算
流数据不适合用传统的关系模型建模,不能把源源不断的流数据保存到数据库中,因此流数据不适合采用批量计算
流数据被处理后,一部分进入数据库成为静态数据,其他部分则被丢弃
传统关系数据库可以满足信息的实时交互需求,例如零售系统和银行系统,但不擅长存储快速连续到达的流式数据
流数据必须采用实时计算,实时计算最重要的一个需求是能够实时得到计算结果,一般要求响应时间为秒级
流计算系统的评价
流计算秉承一个基本概念,即数据的价值随着时间的流逝而降低。因此,当时间出现时就应该立即处理,而不是缓存起来一并批量处理。及时处理流数据需要一个低延时,可扩展和高可靠的处理引擎,一般的评价标准如下
-
高性能,这是处理大数据的基本要求,例如每秒处理几十万条数据
-
海量式,支持 TB 级甚至 PB 级的数据规模
-
实时性,保证一个较低的延迟时间,例如秒级或亚秒级
-
分布式,支持大数据的基本架构,可扩展性要高
-
易用性,支持快速部署和开发
-
可靠性,能够可靠的处理快速连续到来的流数据
流计算的阶段划分
-
数据的实时采集阶段,需要保证实时性,低延迟和可靠性。数据采集系统的基本架构一般有三个部分,①Agent,主动采集数据,并把数据推送到 Collector 部分 ②Collector,接受多个 Agent 的数据,并实现有序,可靠和高性能的转发 ③Store,存储 Collector 转发过来的数据。但是在流计算框架下,Store 部分不进行数据的存储,而是将采集的数据直接发送给流计算平台进行实时计算
-
数据的实时计算阶段,对采集的数据进行实时的分析和计算,计算结果可选择存储或丢弃
-
实时查询服务,由流计算框架得出的结果可供用户进行实时查询,展示或储存。相比起传统数据处理流程用户需要主动发起查询,流处理流程中的实时查询服务可以不断更新结果。即使传统数据处理系统可以定时查询以更新结果,但是这与实时结果仍然有本质的区别
Apache Storm
Storm 对于实时计算的意义类似于 Hadoop 对于批处理的意义,Storm 可以简单,高效并可靠地处理流数据
Storm 有以下的主要特点
-
整合性,Storm 可以方便地与队列系统和数据库系统进行整合
-
Storm 拥有简洁的 API
-
可扩展性,Storm 的并行特性导致它可以运行在分布式集群中
-
容错性,Storm 可以自动进行故障节点的重启,以及节点故障时任务的重新分配
-
可靠的消息处理,Storm 保证每个消息都能完整处理
-
Storm 支持使用各种编程语言来定义任务
-
Storm 支持快速部署和使用
-
Storm 是一款开源的框架,可以免费使用,这一点是相比以往许多金融或政府机构高价定制流处理系统而言的
Storm 的设计思想
-
Streams,Storm 将流数据 Streams 描述为一个无线的 Tuple 序列,这些 Tuple 序列会以分布式的方式并行的创建和处理
-
Spouts,Storm 认为 Streams 都有一个源头,把它抽象为 Spouts,Spouts 从外部读取流数据并持续发出 Tuple
-
Bolts,Storm 将 Streams 的状态转换过程抽象为 Bolts,Bolts 既可以处理 Tuple,也可以将处理后的 Tuple 作为新的 Streams 发送给其他 Bolts,对 Tuple 的处理逻辑都被封装在 Bolts 中,可以执行过滤,聚合或查询等操作
-
Topology,Storm 将 Spouts 和 Bolts 组成的网络抽象成 Topology,Topology 是 Storm 中最高层次的抽象概念,它可以被提交到 Storm 集群执行,一个 Topology 就是一个流转换图,图中节点是一个 Spout 或 Bolt,图中边则表示 Bolt 订阅了那个 Stream,Spout 或者 Bolt 发送 Tuple 的时候会把 Tuple 发送到每个订阅了该 Stream 的 Bolt 上。对于 Topology 的具体实现,Storm 中的 Topology 定义仅仅是一些 Thrift 结构体,Thrift 是基于二进制的高性能的通信中间件,它支持各种编程语言进行定义,因此可以使用各种编程语言创建和提交 Topology
-
Stream Groupings,Storm 中的 Stream Groupings 用于告知 Topology 如何在两个组件之间,例如 Spout 和 Blot 之间或者不同的 Blot 之间,进行 Tuple 的传送,包括至少六种方式,①ShuffleGrouping,随机分组,随机分发 Stream 中的 Tuple,保证每个 Blot 的 Task 接受 Tuple 的数量大体一致 ②FieldsGrouping,按照字段分组,保证相同字段的 Tuple 分配到同一个 Task 中 ③AllGrouping,广播发送,每一个 Task 都会收到所有的 Tuple ④GlobalGrouping,全局分组,所有 Tuple 都发送到同一个 Task 中 ⑤NonGrouping,不分组,Task 和它的被订阅者在同一个线程执行 ⑥DirectGrouping,直接分组,直接指定由某个 Task 来执行 Tuple 处理
Storm 的框架设计
Hadoop 上运行的 MapReduce 作业在完成计算时结束运行,Storm 的 Topology 将持续处理消息直到人为终止
Storm 集群采用 Master-Worker 的节点方式,其中 Master 节点运行名为 Nimbus 的后台程序,负责在集群范围内分发代码,为 Worker 分配任务和检测故障,而每个 Worker 节点运行名为 Supervisor 的后台程序,负责监听分配给它所在机器的工作,即根据 Nimbus 分配的任务来决定启动或停止 Worker 进程
Storm 采用 Zookeeper 作为分布式协调组件,负责 Nimbus 和多个 Supervisor 之间的所有协调工作,一个完整的 Topology 可能被分为多个子 Topology,并由多个 Supervisor 完成
Nimbus 后台进程和 Supervisor 后台进程都是快速失败(Fail-fast)和无状态(Stateless)的,Master 节点并没有直接和 Worker 节点通信,而是借助 Zookeeper 将状态信息存放在 Zookeeper 中或者本地磁盘中,以便节点故障时进行快速恢复,若 Nimbus 进程或 Supervisor 进程异常终止,重启后即可恢复到之前的状态并继续工作
基于这样的架构,Storm 工作流程如下
-
客户端提交 Topology 到 Storm 集群
-
Nimbus 将分配给 Supervisor 的任务写入 Zookeeper
-
Supervisor 从 Zookeeper中获取所分配的任务,并启动 Worker 进程
-
Worker 进程执行具体任务
Spark Streaming
Spark Streaming 是构建在 Spark 上的实时计算框架,它扩展了 Spark 处理大规模流式数据的能力
Spark Streaming 可结合批处理和交互查询,适合一些需要对历史数据和实时数据进行结合信息的应用场景
Spark Streaming 的设计
Spark Streaming 为 Spark 提供了可扩展,高吞吐和容错的流计算能力
Spark Streaming 可整合多种输入数据源,包括 Kafka,Flume ,HDFS,甚至是 TCP 套接字,经过处理后的数据可以存储到文件系统或数据库里,也可以显示在 Dashboard
Spark Streaming 的基本原理是将实时输入的数据流以秒级时间片为单位进行拆分,然后经 Spark 引擎以类似批处理的方式处理每个时间片数据,因此 Spark Streaming 是通过 micro-batching 的方式实现流计算的
Spark Streaming 最主要的抽象是 DStream(Discretized Stream),表示连续不断的数据流。在内部实现上,Spark Streaming 的输入数据按照时间片分成一段一段的 DStream,每一段数据转换成为 Spark 中的 RDD,并且对 DStream 的操作都最终转变为对相应的 RDD 的操作
Spark Streaming 与 Apache Storm 的对比
最核心的区别是,Spark Streaming 无法实现毫秒级的流计算,而 Storm 可以实现毫秒级的响应
Spark Streaming 无法实现毫秒级的流计算,是因为它将数据流划分为一系列 micro-batching,这个过程产生多个 Spark 作业并且每一段数据的处理都会经过 Spark DAG 图分解和任务调度过程
Spark Streaming 无法满足实时性要求非常高的场景,例如高频实时交易的场景,但是足以胜任一般的流式准实时计算场景,相比之下,Storm 的处理单位是 Tuple,只需要极小的延迟
Spark Streaming 构建在 Spark 上,相比于 Storm,RDD 数据集更容易做高效的容错处理
Spark Streaming 采用 micro-batching 的处理方式,使得它可以同时兼容批量和实时数据处理的逻辑和算法,因此方便了一些需要历史数据和实时数据联合分析的特定应用场合