本节书摘来异步社区《Storm技术内幕与大数据实践》一书中的第1章,第1.1节,作者: 陈敏敏 , 黄奉线 , 王新春
责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.1 Storm的基本组件
1.1.1 集群组成
Storm的集群表面上看和Hadoop的集群非常像。但是在Hadoop上运行的是MapReduce的作业(job),而在Storm上运行的是Topology。Storm和Hadoop一个非常关键的区别是Hadoop的MapReduce作业最终会结束,而Storm的Topology会一直运行(除非显式地杀掉它)。
如果说批处理的Hadoop需要一桶桶地搬走水,那么Storm就好比自来水水管,只要预先接好水管,然后打开水龙头,水就源源不断地流出来了,即消息就会被实时地处理。
在Storm的集群中有两种节点:主节点(Master Node)Nimbus和工作节点(Worker Node)Supervisor。Nimbus的作用类似于Hadoop中的JobTracker,Nimbus负责在集群中分发代码,分配工作给机器,并且监控状态。每个工作节点上运行一个Supervisor进程(类似于TaskTracker)。Supervisor会监听Nimbus分配给那台机器的工作,根据需要启动/关闭具体的Worker进程。每个Worker进程执行一个具体的Topology,Worker进程中的执行线程称为Executor,可以有一个或者多个。每个Executor中又可以包含一个或者多个Task。Task为Storm中最小的处理单元。一个运行的Topology由运行在一台或者多台工作节点上的Worker进程来完成具体的业务执行。Storm组件和Hadoop组件的对比参见表1-1。
Nimbus和Supervisor之间的通信依靠ZooKeeper完成,并且Nimbus进程和Supervisor都是快速失败(fail-fast)和无状态的,所有的状态要么在ZooKeeper里面,要么在本地磁盘上。这也就意味着你可以用kill -9来杀死Nimbus和Supervisor进程,然后再重启它们,它们可以继续工作,就好像什么都没有发生过似的。这个设计使得Storm具有非常高的稳定性。Storm的基本体系架构参见图1-2。
1.1.2 核心概念
在Storm中有一些核心基本概念,包括Topology、Nimbus、Supervisor、Worker、Executor、Task、Spout、Bolt、Tuple、Stream、Stream分组(grouping)等,如表1-2所示。
在Storm中有7种内置的分组方式,也可以通过实现CustomStreamGrouping接口来定义自己的分组。
(1)Shuffle分组:Task中的数据随机分配,可以保证同一级Bolt上的每个Task处理的Tuple数量一致,如图1-5所示。
(2)Fields分组:根据Tuple中的某一个Filed或者多个Filed的值来划分。比如Stream根据user-id的值来分组,具有相同user-id值的Tuple会被分发到相同的Task中,如图1-6所示。(具有不同user-id值的Tuple可能会被分发到其他Task中。比如user-id为1的Tuple都会分发给Task1,user-id为2的Tuple可能在Task1上也可能在Task2上,但是同时只能在一个Task上。)
(3)All分组:所有的Tuple都会到分发到所有的Task上,如图1-7所示。
(4)Global分组:整个Stream会选择一个Task作为分发的目的地,通常是具有最新ID的Task,如图1-8所示。
(5)None分组:也就是你不关心如何在Task中做Stream的分发,目前等同于Shuffle分组。
(6)Direct分组:这是一种特殊的分组方式,也就是产生数据的Spout/Bolt自己明确决定这个Tuple被Bolt的哪些Task所消费。如果使用Direct分组,需要使用OutputCollector的emitDirect方法来实现。
(7)Local or shuffle分组:如果目标Bolt中的一个或者多个Task和当前产生数据的Task在同一个Worker进程中,那么就走内部的线程间通信,将Tuple直接发给在当前Worker进程中的目的Task。否则,同Shuffle分组。
1.1.3 Storm的可靠性
Storm允许用户在Spout中发射一个新的Tuple时为其指定一个MessageId,这个MessageId可以是任意的Object对象。多个Stream Tuple可以共用同一个MessageId,表示这多个Stream Tuple对用户来说是同一个消息单元。Storm的可靠性是指Storm会告知用户每一个消息单元是否在一个指定的时间内被完全处理。完全处理的意思是该MessageId绑定的Stream Tuple以及由该Stream Tuple衍生的所有Tuple都经过了Topology中每一个应该到达的Bolt的处理。在Storm中,使用Acker来解决Tuple消息处理的可靠性问题。
1.1.4 Storm的特性
总结起来,Storm具有如下优点。
易用性:开发非常迅速,容易上手。只要遵守Topology、Spout和Bolt的编程规范即可开发出扩展性极好的应用。对于底层RPC、Worker之间冗余以及数据分流之类的操作,开发者完全不用考虑。
容错性:Storm的守护进程(Nimbus、Supervisor等)都是无状态的,状态保存在ZooKeeper中,可以随意重启。当Worker失效或机器出现故障时,Storm自动分配新的Worker替换失效的Worker。
扩展性:当某一级处理单元速度不够,可以直接配置并发数,即可线性地扩展性能。
完整性:采用Acker机制,保证数据不丢失;采用事务机制,保证数据准确性。
由于Storm具有诸多优点,使用的业务领域和场景也越来越广泛。