STORM 官方文档翻译 -- 概念

本页列出Storm的主要概念和资源链接,在资源连接中你会发现更多信息。我们讨论的概念如下:

1.Topologies
2.Streams
3.Spouts
4.Bolts
5.Stream groupings
6.Reliability
7.Tasks
8.Workers

Topologies

实时计算程序的逻辑被封装到一个Storm topology中。Storm topology跟MapReduce job很相似,区别是MapReduce会结束,而topology将一直运行(直到你手动终止它)。topology还可以当做是spout和bolt与数据流组成的拓扑图。这些内容我们会在下文中进行描述。

相关资料:

Streams

stream(数据流)是Storm中的核心抽象概念。一个stream是分布式系统中并行创建处理的无边界的元组序列。stream中的元组中包含名为field的schema。在默认情况下,元组可以包含integers、longs、shorts、bytes、strings、doubles、floats、booleans、和byte arrays。你也可以定义自己的序列化对象来实现自定义元组类型。

每一个stream声明的时候需要给予一个id。因为一般情况下使用的是单一stream的spout和bolt,OutputFieldsDeclarer可以方便的声明一个stream而不需要指定id。此时stream会获得一个默认的id “default”.

相关资料:

Spouts

spout是topology中数据流的数据源。spout通常通过一个外部数据源读取元组并把它们发送到topology (例如Kestrel队列或Twitter API)。 Spout可以定义为可靠地,也可以定义为不可靠的。一个可靠地spout会在元组处理失败的时候从新发送该元组,而失不可靠spout在失败之后直接丢弃该元组。

spout可以发送多个数据流。要这样做,首先需要使用OutputFieldsDeclarerdeclareStream方法声明多个数据流然后使用SpoutOutputCollectoremit方法来发送数据流。

spout主要的方法为nextTuplenextTuple作用是发送一个元组到topology或者没有新元组发送的时候直接返回。有一点要注意的是,因为storm在同一个线程上调用所有spout方法,因此nextTuple不会阻塞任何spout的实现。

另外两个spout的主要方法为ackfail,它们分别用来检测发送给topology的元组是否被成功处理或者失败后的进一步处理。ackfail方法只有可靠spout支持。可以查看Javadoc获取更多信息。

相关资料:

Bolts

Topology中所有的数据处理都是Bolt完成的。通过数据过滤(filtering)、函数处理(functions)、聚合(aggregations)、连接(joins)、数据库交互等功能,Bolt几乎能够完成任何一种数据处理需求。

一个Bolt可以简单的进行数据流转换。而复杂的数据流转换通常需要多个Bolt组合处理。例如将一个推特的数据流转换成“热门图片”至少需要两个步骤:其中一个Bolt用于对每个被转发图片进行滚动计数(rolling count),另一个或多个Bolt将数据流输出为“转发最多的图片”结果(相对于使用2个Bolt,如果使用3个 Bolt你可以让这种转换具有更好的可扩展性)。

与Spout相同,Bolt也可以输出多个数据流。要这样做,可以先通过OutputFieldsDeclarerdeclareStream方法来声明定义不同的数据流,然后通过OutputCollectoremit方法中发送数据流。

当定义Bolt的输入数据流时,你需要从其他的Storm组件中订阅指定的数据流。如果你需要从其他组件中订阅所有数据流,你必须一个个进行订阅操作。InputDeclarer有个语法糖(syntactic sugar)用于订阅声明为默认id的数据流,declarer.shuffleGrouping("1")表示订阅组件“1”的默认数据流,该语句等价于declarer.shuffleGrouping("1", DEFAULT_STREAM_ID)

Blot的主要方法为execute方法,该方法用来接受一个元组输入。然后使用OutputCollector对象发送新的元组。Bolt必须
为每个处理的元组调用OutputCollectorack方法。以便Storm能够了解元组是否处理完成(并且最终决定是否可以响应最初的
Spout元组)。一般情况下,对于每个元组处理后发送0或多个元组,然后相应输入元组,Storm提供IBasicBolt接口来实现自动应答。

在blot中开启新先乘坐异步处理是非常好的,OutputCollector是线程安全的,可以随时调用。

相关资料:

Stream groupings

定义topology的其中一部分是为每个bolt指定接收的输入数据流。流分组定义了如何在螺栓的任务之间分配该流。数据流分组(stream grouping)定义了在Bolt的任务中划分数据流的方式。

在Storm中内置了八种数据分组方式,而且你可以通过实现CustomStreamGrouping接口来自定义数据流分组:

1.Shuffle grouping: 元组会被随机分配到各个bolt任务,每个bolt获得的元组数基本一致。
2.Fields grouping: 这种数据流通过指定的字段来进行分组。例如数据流通过”user-id”字段进行分组,那么相同的”user-id”元组都会被发送到同一个任务。
3.Partial Key grouping: 这个数据流分组跟前面一个Fields grouping很像,但是当数据倾斜的时候会在下游的两个bolt进行负载平衡,从而更好的利用资源。这篇文章很好的解释了这种工作方式的原理。
4.All grouping: 把数据流发送到所有的bolt的任务。使用这种方式的时候要小心。
5.Global grouping: 整个数据流都发送到bolt的同一个任务中。具体来说数据会被发送到id最小的那个任务。
6.None grouping: 使用该分组类型表示你不关心数据流的分组。当前版本下Tnone groupings等效shuffle groupings。不过以后Storm可能会考虑通过none grouping的方式来让bolt和它所订阅spout在一个线程中执行。
7.Direct grouping: 这是一种特殊的分组方式。使用这种方式意味着元组的发送者可以指定下游的哪个任务可以接收这个元组。Direct groupings只有在数据流被声明为direct stream的时候才能使用。发送元组的时候需要使用emitDirect中的一个方法。bolt可以通过TopologyContext获得下游消费者的任务id,也可以通过跟踪OutputCollectoremit(元组发送以后会返回任务id)方法获得任务id。
8.Local or shuffle grouping: 如果在同个worker进程中bolt有一个或多个任务,元组会被随机分配到这些同一个work线程任务中。这种分配有点像 shuffle grouping。

相关资料:

  • TopologyBuilder: 用此类定义topologies
  • InputDeclarer: 在 TopologyBuilder中调用setBolt方法时会返回这个对象的实例,通过该对象就可以定义Bolt的输入数据流以及数据流的分组方式

Reliability

Storm可以通过topology来保证每个spout的元组都会被完全处理。它通过跟踪元组构成的元组树来确定是否成功处理完成。每一个topology都配有一个”消息延时(message timeout)” 参数,如果检测到spout的元组在规定时间内没有成功处理,则他会被标记为失败,并且稍后会重新处理。

为更好的利用Storm的可靠性机制,你必须在一个元组树建立及完成的时候通知Storm。以上这些可以通过bolt的OutputCollector对象发送元组。emit方法实现锚定(Anchoring)

关于更多内容可以参考可靠消息处理(Guaranteeing message processing)

Tasks

每个spout或bolt集群中由多个任务来执行。每个任务对应一个执行线程,stream grouping定义了如何将一组任务的元组发送到另一组任务。你可以通过TopologyBuildersetSpoutsetBolt方法设置每个spout或bolt的并行度。

Workers

Topologie是在一个或多个工作进程(work process)中执行的。每个工作进程是一个JVM并且处理一系列topology的子任务。例如,如果topology的并行度是300,然后分配了50个工作进程,俺么每个工作进程会执行6个任务(worker中的线程)。Storm会在群集中分散任务,使得群集负载平衡。

相关资料:

官方链接:http://storm.apache.org/releases/1.1.0/Concepts.html

坚持原创技术分享,您的支持将鼓励我继续创作!