天天看点

《Storm技术内幕与大数据实践》一1.1 Storm的基本组件

本节书摘来异步社区《storm技术内幕与大数据实践》一书中的第1章,第1.1节,作者: 陈敏敏 , 黄奉线 , 王新春

责编: 杨海玲,更多章节内容可以访问云栖社区“异步社区”公众号查看。

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。

《Storm技术内幕与大数据实践》一1.1 Storm的基本组件

nimbus和supervisor之间的通信依靠zookeeper完成,并且nimbus进程和supervisor都是快速失败(fail-fast)和无状态的,所有的状态要么在zookeeper里面,要么在本地磁盘上。这也就意味着你可以用kill -9来杀死nimbus和supervisor进程,然后再重启它们,它们可以继续工作,就好像什么都没有发生过似的。这个设计使得storm具有非常高的稳定性。storm的基本体系架构参见图1-2。

《Storm技术内幕与大数据实践》一1.1 Storm的基本组件

在storm中有一些核心基本概念,包括topology、nimbus、supervisor、worker、executor、task、spout、bolt、tuple、stream、stream分组(grouping)等,如表1-2所示。

《Storm技术内幕与大数据实践》一1.1 Storm的基本组件
《Storm技术内幕与大数据实践》一1.1 Storm的基本组件

在storm中有7种内置的分组方式,也可以通过实现customstreamgrouping接口来定义自己的分组。

(1)shuffle分组:task中的数据随机分配,可以保证同一级bolt上的每个task处理的tuple数量一致,如图1-5所示。

《Storm技术内幕与大数据实践》一1.1 Storm的基本组件

(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所示。

《Storm技术内幕与大数据实践》一1.1 Storm的基本组件

(4)global分组:整个stream会选择一个task作为分发的目的地,通常是具有最新id的task,如图1-8所示。

《Storm技术内幕与大数据实践》一1.1 Storm的基本组件

(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分组。

storm允许用户在spout中发射一个新的tuple时为其指定一个messageid,这个messageid可以是任意的object对象。多个stream tuple可以共用同一个messageid,表示这多个stream tuple对用户来说是同一个消息单元。storm的可靠性是指storm会告知用户每一个消息单元是否在一个指定的时间内被完全处理。完全处理的意思是该messageid绑定的stream tuple以及由该stream tuple衍生的所有tuple都经过了topology中每一个应该到达的bolt的处理。在storm中,使用acker来解决tuple消息处理的可靠性问题。

总结起来,storm具有如下优点。

易用性:开发非常迅速,容易上手。只要遵守topology、spout和bolt的编程规范即可开发出扩展性极好的应用。对于底层rpc、worker之间冗余以及数据分流之类的操作,开发者完全不用考虑。

容错性:storm的守护进程(nimbus、supervisor等)都是无状态的,状态保存在zookeeper中,可以随意重启。当worker失效或机器出现故障时,storm自动分配新的worker替换失效的worker。

扩展性:当某一级处理单元速度不够,可以直接配置并发数,即可线性地扩展性能。

完整性:采用acker机制,保证数据不丢失;采用事务机制,保证数据准确性。

由于storm具有诸多优点,使用的业务领域和场景也越来越广泛。

继续阅读