Storm是一个分布式的、可靠的、容错的数据流处理系统(流式计算框架,可以和mapreduce的离线计算框架对比理解)。 整个任务被委派给不同的组件,每个组件负责一个简单的特定的处理任务。Storm集群的输入流是一个叫spout的组件负责接入处理。spout把数据传 给bolt组件,bolt组件可以对数据完成某种转化。bolt组件可以把数据持久化,或者传送到其他的bolt。可以把Storm集群想象成一个 bolt组件链,每个组件负责对spout流入的数据(也可以是其他bolt流入的数据)进行某种形式的处理。
有个简单的例子可以说明这个概念。昨晚我看新闻,节目中发言人在谈论政治家以及他们在不用领域的立场。他们不停地在重复一些不同的名字,这时我想知道他们提到的每个名字出现的次数是否一样,还是在某些名字被提及次数更多。
把发言人的言语想象成数据的输入流。我们可以定义一个spout从文件(通过socket、HTTP或者其他方式)读取这些输入。当几行文本到来 时,spout把它们传送给bolt,bolt负责把文本分词。接着数据流被传送到另外一个bolt,这个bolt负责在一个已经定义好的政治家名单进行 比对。如果匹配到了,将数据库中对应的名字的计数加1。任何时候你想看结果,只要从数据库中查询就可以,因为当数据到达时整个过程都是实时更新的。这过程 中所有的组件(spout和bolt)以及他们之间的连接被称为拓扑(topology)(见图表 1-1)。
现在很容易想象定义每个bolt和spout并行度,这样可以无限地扩展整个拓扑。很神奇,对吧?尽管前面讲的只是一个简单的例子,不过你大概已经隐约感觉到Storm的强大了。
那么,Storm适用什么应用场景呢?
- 数据流处理:正如上述的例子,Storm不像其他流处理系统,因为Storm不需要中间队列。
- 持续计算:持续地向客户端发送数据,它们可以实时的更新以及展现数据,比如网站指标。
- 分布式远程过程调用:轻松地并行化CPU密集型操作。
(补充)从业务场景上,举例说明Storm的可以处理的具体业务(这部分是黄崇远总结的,觉得比较全面,摘抄在此)
- 条件过滤:这是Storm最基本的处理方式,对符合条件的数据进行实时过滤,将符合条件的数据保存下来,这种实时查询的业务需求再实际应用中很常见。
- 中间计算:我们需要改变数据中某一个字段(例如是数值),我们需要利用一个中间值经过计算(值比较、求和、求平均等等)后改变该值,然后将数据重新输出。
- 求TopN:相信大家对TopN类的业务需求也比较熟悉,在规定时间窗口内,统计数据出现的TopN,该类处理在购物及电商业务需求中,比较常见。
- 推荐系统:有时候在实时处理时会从mysql及hadoop中获取数据库中的信 息,例如在电影推荐系统中,传入数据为:用户当前点播电影信息,从数据库中获取的是该用户之前的一些点播电影信息统计,例如点播最多的电影类型、最近点播 的电影类型,及其社交关系中点播信息,结合本次点击及从数据库中获取的信息,生成推荐数据,推荐给该用户。并且该次点击记录将会更新其数据库中的参考信 息,这样就是实现了简单的智能推荐。
- 分布式RPC:Storm有对RPC进行专门的设计,分布式RPC用于对Storm上大量的函数进行并行计算,最后将结果返回给客户端。
- 批处理:所谓批处理就是数据积攒到一定触发条件,就批量输出,所谓的触发条件类似事件窗口到了,统计数量够了即检测到某种数据传入等等。
- 热度统计:热度统计实现依赖于Storm提供的TimeCacheMap数据结构,现在可能推荐用RotatingMap,关于这两个数据结构的源码分析,移步Storm TimeCacheMap RotatingMap源码分析,该结构能够在内存中保存近期活跃的对象。我们可以使用它来实现例如论坛中热帖排行计算等。
Storm组件
在Storm集群中,节点被一个主控节点管理,并持续运行。
在Storm集群中有两类节点:主控节点和工作节点。主控节点跑一个后台进程Nimbus,它负责在集群中分发代码,把任务安排给工作节点,监控任 务是否失败。工作节点跑后台进程叫Supervisor来执行拓扑的部分功能。Storm的拓扑会在不同机器的工作节点上运行。
因为Storm把集群的状态存在Zookeeper或者本地磁盘,所以后台进程都是无状态的(不需要保存自己的状态,都在zookeeper上),可以在不影响系统健康运行的同时失败或重启。(见图1-2)
在底层Storm使用了zeromq(0mq,zeromq(http://www.zeromq.org)),一个先进的嵌入式的网络通讯库,提供了很棒的功能使得Storm成为可能。以下是zeromq的特点:
- 支持高并发框架的Socket库
- 比TCP更快,适用于集群产品和超级计算
- 通过进程内通信,进程间通信,TCP和多播的形式传递消息
- 异步的I/O,服务于可扩展的多核消息传输应用
- 通过扇出(fanout),发布订阅,管道,请求应答实现多对多连接
Storm用了push/pull套接字api
(补充:Storm组件的命名方式)
Storm暴风雨:其组件大多也以气象名词命名
spout龙卷:形象的理解是把原始数据卷进Storm流式计算中
bolt雷电:从spout或者其他bolt中接收数据进行处理或者输出
nimbus雨云:主控节点,存在单点问题,不过可以用watchdog来保证其可用性,fast-fail后马上就启动
topology拓扑:Storm的任务单元,形象的理解拓扑的点是spout或者bolt,之间的数据流是线,整个构成一个拓扑
Storm的特性
所有的设计概念和决策,使得Storm拥有诸多美好的特性,Storm变得独一无二。
- 编程简单:如果你曾经尝试实时处理抓取的内容,就知道这个过程有多痛苦。但是Storm显著的降低了编码复杂度。
- 支持多种编程语言:用基于JVM的语言会比较简单,但是Storm也支持任意其他语言,只要使用或者实现一个很小的中间件。(第七章有一个php的例子)
- 容错性:Storm可以处理工作节点的宕机,在适当的时候重新安排任务。
- 可扩展性:为了扩展,你需要做的就是往集群里加更多的机器。Storm会往可用的新机器上分配任务。
- 可靠性:所有的消息保证至少都能处理一次。如果发生错误,这些消息会被处理多次,但从不会丢失数据。
- 高效:速度是驱动Storm设计的一个重要指标。
- 事务性:对于绝大部分运算来说,你可以得到消息一次消费的语义。
《Getting started with Storm》译文HomePage 译文索引