Storm架构原理详解!

目录

一、Storm概述

Apache Storm是一个免费的开源分布式实时计算系统。 Storm可以轻松地处理无限数据流, 并且实时处理Hadoop批处理任务。 可以和任何编程语言一起使用,并且使用起来非常有趣!

Storm有许多用例:实时分析,在线机器学习,连续计算,分布式RPC,ETL等等。 Storm是快速 的:一个基准计算每个节点每秒处理超过一百万个元组。 它具有可扩展性,容错性,可确保您的 数据得到处理,且易于设置和操作。

Storm集成了您已经使用的队列和数据库技术。 Storm拓扑消耗数据流,并以任意复杂的方式处理 这些流,然后重新分配计算的每个阶段之间的流。

二、Storm特性

Storm特点:

  • 开源分布式流式计算
  • 无顺序流数据计算
  • 到达海量数据无穷无尽
  • 计算速度快
  • 扩展性、容错性、可靠性、高可用性、易用性

storm应用场景:
推荐系统(实时推荐,根据下单或加入购物车推荐相关商品)、金融系统、预警系统、网站统计(实时销量、流量统计,如淘宝双11效果图)、交通路况实时系统等等。

  • 1.流数据处理,Storm可以用来处理源源不断流进来的消息,处理之后将结果写入到某个存储中去。
  • 2.分布式rpc,由于storm的处理组件是分布式的,而且处理延迟极低,所以可以作为一个通用的分布式rpc框架来使用。
  • 3.持续计算,任务一次初始化,一直运行,除非你手动kill它。

三、Storm架构原理

与Hadoop主从架构一样,Storm也采用Master/Slave体系结构,分布式计算由Nimbus和Supervisor两类服务进程实现,Nimbus进程运行在集群的主节点,负责任务的指派和分发,Supervisor运行在集群的从节点,负责执行任务的具体部分。架构图如下:

Storm架构原理详解!

如图所示:

  • Nimbus: Storm集群的Master节点,负责资源分配和任务调度,负责分发用户代码,指派给具体的Supervisor节点上的Worker节点,去运行Topology对应的组件(Spout/Bolt)的Task。
  • Supervisor: Storm集群的从节点,负责接受Nimbus分配的任务,启动和停止属于自己管理的worker进程。通过Storm的配置文件中的supervisor.slots.ports配置项,可以指定在一个Supervisor上最大允许多少个Slot,每个Slot通过端口号来唯一标识,一个端口号对应一个Worker进程(如果该Worker进程被启动)。
  • Worker: 负责运行具体处理组件逻辑的进程。Worker运行的任务类型只有两种,一种是Spout任务,一种是Bolt任务。
  • Task: worker中每一个spout/bolt的线程称为一个task。同一个spout/bolt的task可能会共享一个物理线程,该线程称为executor。
  • ZooKeeper: 用来协调Nimbus和Supervisor,如果Supervisor因故障出现问题而无法运行Topology,Nimbus会第一时间感知到,并重新分配Topology到其它可用的Supervisor上运行。

四、Storm服务组件

(1)Topology(拓扑)

实时应用程序的逻辑被封装在 Storm topology(拓扑)中。Storm topology(拓扑)类似于 MapReduce 作业。两者之间关键的区别是 MapReduce 作业最终会完成, 而 topology(拓扑)任务会永远运行(除 非 kill 掉它)。一个拓扑是 Spout 和 Bolt 通过 stream groupings 连接起 来的有向无环图。Storm架构原理详解!
Stream 是 Storm 中的核心概念.一个 stream 是一个*的、以分布式方式并行创建和处理的 Tuple 序列. stream 以一个 schema 来定义, 这个 schema 用来命名 stream tuple(元组)中的字段.默认情况下 Tuple 可以包含 integers, longs, shorts, bytes, strings, doubles, floats, booleans, and byte arrays 等数据类型.你也可以定义自己的 serializers, 以至于可以在 Tuple 中使用自定义的类型.

每一个流在声明的时候会赋予一个 ID. 由于只包含一个 stream 的 Spout 和 Bolt 比较常见, OutputFieldsDeclarer 有更方便的方法可以定义一个单一的 stream 而不用指定ID. 这个 stream 被赋予一个默认的 ID, “default”.

Topology模型图:
Storm架构原理详解!
Storm架构原理详解!
其中包含:

  • Spout: Storm中的消息源,用于为Topology生产消息(数据),一般是从外部数据源(如Message
    Queue、RDBMS、NoSQL、Realtime Log )不间断地读取数据并发送给Topology消息(tuple元组)。

  • Bolt: Storm中的消息处理者,用于为Topology进行消息的处理,Bolt可以执行过滤,聚合, 查询数据库等操作,而且可以一级一级的进行处理。

(2) 数据模型Tuple

  • storm使用tuple来作为它的数据模型。每个tuple是一堆值,每个值有一个名字,并且每个值可以是任何类型,在我的理解里面一个tuple可以看作一个java对象。总体来看,storm支持所有的基本类型:字符串以及字节数组作为tuple的值类型。你也可以使用你自己定义的类型来作为值类型,只要你实现对应的序列化器(serializer)。
  • 一个Tuple代表数据流中的一个基本的处理单元,它可以包含多个Field,每个Field表示一个属性。
  • Tuple是一个Key-Value的Map,由于各个组件间传递的tuple的字段名称已经事先定义好了,所以Tuple只需要按序填入各个Value,所以就是一个Value List。一个没有边界的,源源不断的,连续的Tuple序列就组成了Stream。
  • topology里面的每个节点必须定义它要发射的tuple的每个字段。

(3)Spout

  • Spout 是一个 topology(拓扑)中 streams 的源头. 通常 Spout 会从外部数据源读取 Tuple,然后把他们发送到 拓扑中(如 Kestel 队列, 或者 Twitter API). Spout 可以是 可靠的 或 不可靠的. 可靠的 Spout 在 Storm 处理失败的时 候能够重放 Tuple, 不可靠的 Spout 一旦把一个 Tuple 发送出去就撒手不管了.
  • Spout 中的最主要的方法是 nextTuple. nextTuple 要么向 topology(拓扑)中发送一个新的 Tuple, 要么在没有 Tuple 需要发送的情况下直接返回. 对于任何 Spout 实现, nextTuple 方法都必须非阻塞的, 因为 Storm 在一个线程中调 用所有的 Spout 方法.
  • Spout 的另外几个重要的方法是 ackfail. 这些方法在 Storm 检测到 Spout 发送出去的 Tuple 被成功处理或者 处理失败的时候调用. ackfail只会在可靠的 Spout 中调用

(4)Bolt

  • 拓扑中所有的业务处理都在 Bolts 中完成. Bolt 可以做很多事情,过滤, 函数, 聚合, 关联, 与数据库交互等.
  • 拓扑中所有的业务处理都在 Bolts 中完成. Bolt 可以做很多事情,过滤, 函数, 聚合, 关联, 与数据库交互等.
  • Bolt 中最主要的方法是 execute 方法, 当有一个新 Tuple 输入的时候会进入这个方法. Bolt 使用OutputCollector 对象发送 新的 Tuple. Bolt 必须在每一个 Tuple 处理完以后调用 OutputCollector 上的 ack 方法, Storm 就会知道 tuple 什么时候完成 ( 最终可以确定 调用源 Spout Tuple 是没有问题的). 当处理一个输入的 Tuple:会基于这个 Tuple 产生零个或者多个 Tuple 发 送出去,当所有的tuple 完成后,会调用 acking. Storm 提供了 IBasicBolt 接口会自动执行 acking .
  • 最好在 Bolt 中启动新的线程异步处理 tuples. OutputCollector 是线程安全的, 并且可以在任何时刻调用.

(5)并行元素(Worker、Executor、Task)的关系

一个Storm在集群上运行一个Topology时,主要通过以下3个实体来完成Topology的执行工作:

  • Worker(进程)
  • Executor(线程)
  • Task

下图简要描述了这3者之间的关系:

Storm架构原理详解!
1个worker进程执行的是1个topology的子集(注:不会出现1个worker为多个topology服务)。1个worker进程会启动1个或多个executor线程来执行1个topology的component(spout或bolt)。因此,1个运行中的topology就是由集群中多台物理机上的多个worker进程组成的。

executor是1个被worker进程启动的单独线程。每个executor只会运行1个topology的1个component(spout或bolt)的task(注:task可以是1个或多个,storm默认是1个component只生成1个task,executor线程里会在每次循环里顺序调用所有task实例)。

一个 task 执行实际的数据处理 - 在您代码中实现的每个 spout 或 bolt 在整个集群上都执行了许多的 task(任 务), 组件的 task(任务)数量在 topology(拓扑)的整个生命周期中总是相同的, 但组件的 executors(线程) 数量可能会随时间而变化。 这意味着以下条件成立: #threads ≤ #tasks. 默认情况下,tasks(任务)数量与 executors(执行器)设置成一样,即1个executor线程只运行1个task。

六、Storm工作原理

Nimbus 负责在集群分发的代码,topo只能在nimbus机器上提交,将任务分配给其他机器,和故障监测。

Supervisor,监听分配给它的节点,根据Nimbus 的委派在必要时启动和关闭工作进程。 每个工作进程执行topology 的一个子集。一个运行中的topology 由很多运行在很多机器上的工作进程组成。

在Storm中有对于流stream的抽象,流是一个不间断的*的连续tuple,注意Storm在建模事件流时,把流中的事件抽象为tuple即元组

Storm架构原理详解!
Storm认为每个stream都有一个源,也就是原始元组的源头,叫做Spout(管口)

处理stream内的tuple,抽象为Bolt,bolt可以消费任意数量的输入流,只要将流方向导向该bolt,同时它也可以发送新的流给其他bolt使用,这样一来,只要打开特定的spout再将spout中流出的tuple导向特定的bolt,bolt又对导入的流做处理后再导向其他bolt或者目的地。

可以认为spout就是水龙头,并且每个水龙头里流出的水是不同的,我们想拿到哪种水就拧开哪个水龙头,然后使用管道将水龙头的水导向到一个水处理器(bolt),水处理器处理后再使用管道导向另一个处理器或者存入容器中。

Storm架构原理详解!

为了增大水处理效率,我们很自然就想到在同个水源处接上多个水龙头并使用多个水处理器,这样就可以提高效率。

七、Storm与Hadoop的对比

结构 Hadoop Storm
主节点 JobTracker Nimbus
从节点 TaskTracker Supervisor
应用程序 Job Topology
工作进程名称 Child Worker
计算模型 Map / Reduce Spout / Bolt

以上内容仅供参考学习,如有侵权请联系我删除!
如果这篇文章对您有帮助,左下角的大拇指就是对博主最大的鼓励。
您的鼓励就是博主最大的动力!

上一篇:Codeforces Round #501 (Div. 3) F. Bracket Substring


下一篇:理解Java虚拟机(九)垃圾收集器的选择权衡