曾经沧海难为水,除却巫山不是云。|

Joey-Wang

园龄:4年3个月粉丝:17关注:0

chapter7 流计算系统Storm

批处理:处理的输入数据是静态的,即输入数据在计算开始前已确定

流计算:处理的输入数据是动态的,即输入数据在计算开始后才逐步到达

流数据:大量、快速、时变并持续到达的数据

Storm 是开源的分布式流计算系统,用于支持实时计算。

1 设计思想

与MapReduce、Spark等批处理系统不同,Storm流计算系统要处理的数据以流(Stream)的形式存在,理论上是无界的,且计算需持续进行。

Storm系统将流数据抽象为无界的元组(Tuple)序列,并使用拓扑(Topology)来抽象计算过程。

1.1 连续处理

短时运行 🆚 长期驻留:

  • 批处理系统中负责执行计算的任务是短时运行
  • 流计算系统中负责执行计算任务的线程或进程长期驻留在系统中,因为数据以流的形式存在且理论上是无界的

连续处理:执行流计算的一种直观方式。输入的流数据记录不断地进入系统,计算任务长期驻留并且更新自身的状态。

状态:一种特殊的数据,用于保存从流计算开始到目前为止得到的计算结果

Why 要有状态?

输入的数据以流的形式存在,若发生故障,原数据无法再获取。
MapReduce和Spark中数据是静态的,若发生故障,最差也可用原数据重新运行。

1.2 数据模型:Tuple

Storm将流数据视为是一个无界的、连续的元组序列。

  • 一个元组就是系统处理的一条记录,每一条记录(元组)包含若干个字段。

🆚 数据模型的比较

  1. Storm的数据模型为元组 Tuple,系统处理的一条记录就是一个 Tuple
    • 字段角度,一个记录拥有多个字段
  2. MapReduce的数据模型为键值对 Key-value,系统处理的一条记录就是一个 Key-value
    • 字段角度:一个记录仅拥有两个字段:key、value
  3. Spark的数据模型为RDD,根据一组记录进行建模
    • Storm和MapReduce的数据模型都根据一条记录进行建模

1.3 计算模型

逻辑计算模型

Storm使用拓扑描述计算过程,逻辑上是由Spout和Bolts组成的DAG。

  • 顶点:Spout或Bolt(描述数据处理逻辑)
    • Spout:流数据的源头,负责从外部数据源读取数据,封装成Tuple发送给Bolt
    • Bolt:描述流数据的转换过程,将处理后的Tuple作为新的流数据发送给其他Bolt
  • 边:Bolt订阅的流数据(描述数据流动的方向)
    • 当Spout或Bolt发送元组时,会把元组发送到每个订阅了该流数据的Bolt上进行处理

物理计算模型

Spout/Bolt 物理上由若干任务(Task)实现,Storm需要相应的线程来运行任务。

image-20211228230025848

2 体系架构

2.1 架构图

采用主从架构,主要工作部件:Nimbus、Supervisor和Worker、ZooKeeper。

Nimbus位于主节点,Supervisor和Worker位于从节点,主从节点之间的协调和控制依赖于ZooKeeper。

  1. Nimbus:主节点运行的后台程序,负责分发代码、分配任务和监测故障
  2. Supervisor:从节点运行的后台程序
    • 负责监听所在机器的工作,根据Nimbus分配的任务来决定启动或停止Worker进程
    • 一个从节点上同时运行若干个Worker进程
  3. Zookeeper:负责Nimbus和Supervisor之间的所有协调工作
    • 若Nimbus或Supervisor进程意外终止,重启时能读取、恢复之前的状态并继续工作
  4. Worker:运行一个或多个 Executor 线程,从而实际执行任务
    • Executor:产生于worker进程内部的线程,会执行同一个组件的一个或多个task
    • Task:执行数据处理的代码实例(Spout/Bolt)
image-20211228230635868

Storm 🆚 MapReduce1.0 🆚 standalone模式的Spark:

  1. 系统进程角度:三者很相似,均由主节点负责整个系统管理的进程、从节点负责该节点管理的进程and负责任务执行的进程构成。只是不同系统使用了不同的名称。
  2. 任务执行角度:MapReduce采用多进程执行模型,Child进程执行任务代码Task;Spark采用多线程执行模型,Task任务代码同时以工作线程的形式存在;Storm采用多线程执行模型,Executor作为工作线程,在Task中仅实现任务代码。
  3. 基础接口角度:MapReduce仅提供Map、Reduce两个编程接口;Spark提供基于RDD的编程接口。Storm提供Spout、Bolt两个编程接口。
image-20211228231519759

2.2 应用程序执行流程

  1. 用户编写的Topology程序,经过序列化、打包并提交给主节点Nimbus
  2. Nimbus创建一个组件与物理节点的对应关系文件,将该文件原子地写入Zookeeper中某Znode
  3. 所有Supervisor监听Znode来得到通知从而获取所在节点所需执行的组件任务(Task)
  4. Supervisor从Nimbus处拉取可执行的代码
  5. Supervisor启动若干Worker进程执行具体的任务
  6. Worker进程根据ZooKeeper中获取的文件信息, 启动若干个Executor线程,该线程负责执行组件 (Spout或Bolt)所描述的任务(Task)
image-20211228231543148

3 工作原理

Spout负责数据的输入,Bolt负责数据的转换和输出。

Storm运行拓扑程序时,一个Spout/Bolt通常由多个任务Task同时执行。Spout和Bolt之间/不同的Bolt之间的 Tuple传输表现为属于上游组件的task和属于下游组件的task之间的Tuple传输

Task之间的Tuple传输的问题:

  1. 对于流数据(一组Tuple)来说,上游组件的task发送哪些Tuple给下游组件的task?
    • 如何对这组Tuple进行划分?
  2. 对于一条Tuple来说,上游组件的task如何向下游组件的task传递Tuple?
    • 立即传输还是等待多条Tuple成批次传输?

3.1 流数据分组策略

定义了两个有订阅关系的组件间(如Spout和Bolt之间,或者不同的Bolt之间)进行Tuple传输的方式。

组件在物理上由若干任务实现,上游的任务可能属于Spout/Bolt组件,下游任务必然属于Bolt组件。

  • 对于上游的组件来说,流数据的分组策略定义了:属于该组件的多个任务发送哪些Tuple给下游组件的任务
  • 对于下游的组件来说,流数据的分组策略定义了:下游组件的多个任务之间对于元组的划分策略

常见的流数据分组策略(Stream Groupings):

  1. 随机分组(Shuffle Grouping):随机分发Tuple,保证每个Bolt的Task接收Tuple数量大致一致
  2. 按照字段分组(Fields Grouping):保证指定字段相同的Tuple分配到同一个Task中
  3. 广播分组(All Grouping):每一个Task都会收到所有的Tuple
  4. 全局分组(Global Grouping):所有的Tuple都发送到同一个Task中
  5. 直接分组(Direct Grouping):直接指定由某个Task来执行Tuple的处理
  6. 本地或随机分组(Local or Shuffle Grouping):若下游组件有一个或多个任务与上游组件的任务在同一Worker进程中,则Tuple被随机分发到该进程的任务中。否则,此策略与随机分组策略相同。
image-20211229013823798

MapReduce中Shuffle采用的按键划分键值对,与Storm中按字段分组的流数据分组策略达到的效果类似

3.2 元组传递方式

Storm采用一次一元组或一次一记录的消息传递机制。

  • 一旦上游组件的任务处理完一条元组,就立即发送给下游组件的任务,且一次发送一条元组
  • 对于连续两条元组,上游组件的任务处理了第一条元组就可立即发送给下游组件的任务,而不必等待下一条元组的处理结果
  • 这种立即发送的消息传递机制有利于减少处理的延迟,从而满足实时性需求

流计算 🆚 批处理:

  1. 流计算:一次一元组;数据传输立即进行,无阻塞
  2. 批处理:数据传输成块进行;MapReduce和Spark的Shuffle阶段存在阻塞

4 容错机制

  1. 主节点故障:Nimbus进程故障:重启。
    • 但为了保证主节点的高可用,Storm可类似MapReduce、Spark,配置一个Nimbus列表(元信息存储在所有主备Nimbus或外部可靠的分布式存储系统e.g.,HDFS),一旦主Nimbus出故障,系统就在若干备Nimbus中选一个作为新的主Nimbus。
  2. 从节点故障:
    • Supervisor故障
      • 判断该节点能否重启Supervisor,若能则重新启动;
      • 若不能则启动新的Supervisor进程,原来监控的所有Worker重新调度、启动。
    • Worker故障:重新启动。
    • Supervisor与Worker同时故障:Nimbus命令其他节点的Supervisor启动Worker进程。
  3. ZooKeeper故障:ZooKeeper本身具有容错机制,可认为该部件是可靠的。极端情况下,ZooKeeper不可用将导致Storm系统无法正常工作

4.1 容错语义

简单重启Worker进程并不意味着能保证容错,容错保障还要考虑语义的正确性。

流计算系统的容错语义

  1. 至多一次(At Most Once):消息可能会丢失
    • 消息至多收到一次,意味着消息可能丢失
  2. 至少一次(At Last Once):消息不会丢失,可能会重复
    • 消息至少收到一次,意味着消息不会丢失但可能重复
  3. 准确一次(Exactly Once):消息不丢失,不重复
image-20211229020329618

可见,重启故障的Worker,容错语义级别为至多一次。

Storm采用的容错策略:

  1. Storm将Spout发出的每条源元组(Spout Tuple)及其后续衍生的Tuple视为一颗元组树,若元组树中所有Tuple均由系统成功输出,则源元组得到成功处理。
  2. 在运行拓扑的过程中,Storm使用ACK机制对元组树中的Tuple进行确认,一旦元组树中某一Tuple因故障无法得到确认,则系统从Spout将源元组重放

—— Spout所在线程无故障的前提下,此容错策略达到至少一次的容错语义。

4.2 元组树

Topology中的Spout会源源不断地发射出Tuple,每一条Tuple都会由后续的Bolt处理并演化为新的Tuple。

元组树:Spout发出的Tuple及其衍生出来的Tuple抽象为一棵树

  • Spout中每一条元组都对应一棵元组树

Spout-Tuple-id(STid):Spout中发射Tuple时用户可以为其指定标识

  • 该 STid 伴随 Tuple 在处理过程中的演化
  • 若该 Tuple 经 Bolt 处理产生多个 Tuple,则 STid 会绑定到产生的所有 Tuple 上
  • STid 由用户程序指定,可将多个 Tuple 绑定相同 STid
image-20211229021217996

4.3 ACK机制

Mid:元组树中Tuple传输物理表现为组件Task之间的消息传输,消息有64位标识Mid。

Mid 🆚 STid

Mid是系统定义的消息传递标识,每条消息的Mid都不同。
STid是用户定义的标识,同一元组树的STid都相同。

Storm里面有一类特殊的Task作为Acker,负责跟踪Spout发出的元组及其元组树。

ACK机制:

  • 上游组件的Task发射消息的同时,会向 Acker 报告 Mid、STid
  • 当下游组件的Task接收到消息时,向 Acker 报告 Mid、STid

最简单的消息确认机制:Acker记录上游组件报告的Mid、STid,根据下游组件报告的Mid、STid判断STid对应的元组树中标号为Mid的消息对应的Tuple是否成功传输。

但元组树中Tuple很多,且可能并行向Acker报告Mid和STid,
则Acker端需要维护类似于<STid, list<Mid>>的映射表,维护List对于Acker来说内存开销太大

Acker的数据结构:<STid, ack_val> 映射表

  1. 收到Spout发来消息时将相应 STid 的 ack_val 初始化为0
  2. Acker接收上下游组件消息时,将 Mid 与映射表对应 STid 的 ack_val 做异或操作
  3. 若Acker在设定的时间范围内收到处于拓扑最末端的Bolt报告并且ack_val为0,则Acker会告知相应的Spout:STid对应的元组树已成功处理完
image-20211229022407186

4.4 消息重放

Storm认为消息的传输发生故障

  • Acker在设定时间范围内未收到拓扑最末端Bolt发来的关于STid的确认消息 or STid对应的ack_val不为0。

Spout重新发送以STid为标识的元组

  • 但这种消息重放机制可能会导致消息的重复计算,达到的是至少一次的容错语义级别
image-20211229023410094

本文作者:Joey-Wang

本文链接:https://www.cnblogs.com/joey-wang/p/15789725.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Joey-Wang  阅读(175)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开