一个完整的 Storm 流处理程序被称为 Storm topology(拓扑)。它是一个是由 Spouts
和 Bolts
经过 Stream
链接起来的有向无环图,Storm 会保持每一个提交到集群的 topology 持续地运行,从而处理源源不断的数据流,直到你将主动其杀死 (kill) 为止。html
Stream
是 Storm 中的核心概念。一个 Stream
是一个无界的、以分布式方式并行建立和处理的 Tuple
序列。Tuple 能够包含大多数基本类型以及自定义类型的数据。简单来讲,Tuple 就是流数据的实际载体,而 Stream 就是一系列 Tuple。git
Spouts
是流数据的源头,一个 Spout 能够向不止一个 Streams
中发送数据。Spout
一般分为可靠和不可靠两种:可靠的 Spout
可以在失败时从新发送 Tuple, 不可靠的 Spout
一旦把 Tuple 发送出去就置之不理了。github
Bolts
是流数据的处理单元,它能够从一个或者多个 Streams
中接收数据,处理完成后再发射到新的 Streams
中。Bolts
能够执行过滤 (filtering),聚合 (aggregations),链接 (joins) 等操做,并能与文件系统或数据库进行交互。数据库
spouts
和 bolts
在集群上执行任务时,是由多个 Task 并行执行 (如上图,每个圆圈表明一个 Task)。当一个 Tuple 须要从 Bolt A 发送给 Bolt B 执行的时候,程序如何知道应该发送给 Bolt B 的哪个 Task 执行呢?apache
这是由 Stream groupings 分组策略来决定的,Storm 中一共有以下 8 个内置的 Stream Grouping。固然你也能够经过实现 CustomStreamGrouping
接口来实现自定义 Stream 分组策略。网络
Shuffle grouping架构
Tuples 随机的分发到每一个 Bolt 的每一个 Task 上,每一个 Bolt 获取到等量的 Tuples。负载均衡
Fields grouping分布式
Streams 经过 grouping 指定的字段 (field) 来分组。假设经过 user-id
字段进行分区,那么具备相同 user-id
的 Tuples 就会发送到同一个 Task。大数据
Partial Key grouping
Streams 经过 grouping 中指定的字段 (field) 来分组,与 Fields Grouping
类似。可是对于两个下游的 Bolt 来讲是负载均衡的,能够在输入数据不平均的状况下提供更好的优化。
All grouping
Streams 会被全部的 Bolt 的 Tasks 进行复制。因为存在数据重复处理,因此须要谨慎使用。
Global grouping
整个 Streams 会进入 Bolt 的其中一个 Task,一般会进入 id 最小的 Task。
None grouping
当前 None grouping 和 Shuffle grouping 等价,都是进行随机分发。
Direct grouping
Direct grouping 只能被用于 direct streams 。使用这种方式须要由 Tuple 的生产者直接指定由哪一个 Task 进行处理。
Local or shuffle grouping
若是目标 Bolt 有 Tasks 和当前 Bolt 的 Tasks 处在同一个 Worker 进程中,那么则优先将 Tuple Shuffled 处处于同一个进程的目标 Bolt 的 Tasks 上,这样能够最大限度地减小网络传输。不然,就和普通的 Shuffle Grouping
行为一致。
也叫作 Master Node,是 Storm 集群工做的全局指挥官。主要功能以下:
也叫作 Worker Node , 是 Storm 集群的资源管理者,按需启动 Worker 进程。主要功能以下:
Nimbus 和 Supervisor 进程都被设计为快速失败(遇到任何意外状况时进程自毁)和无状态(全部状态保存在 Zookeeper 或磁盘上)。 这样设计的好处就是若是它们的进程被意外销毁,那么在从新启动后,就只须要从 Zookeeper 上获取以前的状态数据便可,并不会形成任何数据丢失。
Storm 集群的任务构造者 ,构造 Spoult 或 Bolt 的 Task 实例,启动 Executor 线程。主要功能以下:
Storm 集群的任务执行者 ,循环执行 Task 代码。主要功能以下:
1 个 Worker 进程执行的是 1 个 Topology 的子集,不会出现 1 个 Worker 为多个 Topology 服务的状况,所以 1 个运行中的 Topology 就是由集群中多台物理机上的多个 Worker 进程组成的。1 个 Worker 进程会启动 1 个或多个 Executor 线程来执行 1 个 Topology 的 Component(组件,即 Spout 或 Bolt)。
Executor 是 1 个被 Worker 进程启动的单独线程。每一个 Executor 会运行 1 个 Component 中的一个或者多个 Task。
Task 是组成 Component 的代码单元。Topology 启动后,1 个 Component 的 Task 数目是固定不变的,但该 Component 使用的 Executor 线程数能够动态调整(例如:1 个 Executor 线程能够执行该 Component 的 1 个或多个 Task 实例)。这意味着,对于 1 个 Component 来讲,#threads<=#tasks
(线程数小于等于 Task 数目)这样的状况是存在的。默认状况下 Task 的数目等于 Executor 线程数,即 1 个 Executor 线程只运行 1 个 Task。
总结以下:
更多大数据系列文章能够参见 GitHub 开源项目: 大数据入门指南