1、storm组件web
Storm在集群上运行一个Topology时,主要经过如下3个实体来完成Topology的执行工做:
1. Worker(进程)
2. Executor(线程)
3. Task
下图简要描述了这3者之间的关系:并发
1个worker进程执行的是1个topology的子集(注:不会出现1个worker为多个topology服务)。1个worker进程会启动1个或多个executor线程来执行1个topology的component(spout或bolt)。所以,1个运行中的topology就是由集群中多台物理机上的多个worker进程组成的。
executor是1个被worker进程启动的单独线程。每一个executor只会运行1个topology的1个component(spout或bolt)的task(注:task能够是1个或多个,storm默认是1个component只生成1个task,executor线程里会在每次循环里顺序调用全部task实例)。
task是最终运行spout或bolt中代码的单元(注:1个task即为spout或bolt的1个实例,executor线程在执行期间会调用该task的nextTuple或execute方法)。topology启动后,1个component(spout或bolt)的task数目是固定不变的,但该component使用的executor线程数能够动态调整(例如:1个executor线程能够执行该component的1个或多个task实例)。这意味着,对于1个component存在这样的条件:#threads<=#tasks(即:线程数小于等于task数目)。默认状况下task的数目等于executor线程数目,即1个executor线程只运行1个task。分布式
2、Storm nimbus单点问题ui
一、storm集群在生产环境部署以后,一般会是以下的结构:
spa
从图中能够看出zookeeper和supervisor都是多节点,任意1个zookeeper节点宕机或supervisor节点宕机均不会对系统总体运行形成影响,但nimbus和ui都是单节点。ui的单节点对系统的稳定运行没有影响,仅提供storm-ui页面展现统计信息。但nimbus承载了集群的许多工做,若是nimbus单节点宕机,将会使系统总体的稳定运行形成极大风险。所以解决nimbus的单点问题,将会更加完善storm集群的稳定性。
二、storm nimbus单节点的风险
(1)功能上,nimbus进程退出后,若是再同时发生worker进程宕机,宕机的worker将没法重启,集群将会有部分消息始终没法获得处理。
(2)监控上,nimbus进程不可用时,storm ui将没法访问。
(3)概率上,机房因为演练或故障不可用时即会出现nimbus与worker进程同时故障的情形,面对风险的概率较大。
三、storm与解决nimbus单点相关的概念线程
【nimbus进程】storm集群工做的全局指挥官。
(1)经过thrift接口,监听并接收client对topology的submit,将topology代码保存到本地目录/nimbus/stormdist/下
(2)为client提交的topology计算任务分配,根据集群worker资源状况,计算出topology的spout和bolt的task应该如何在worker间分配,任务分配结果写入zookeeper
(3)经过thrift接口,监听supervisor的下载topology代码的请求,并提供下载
(4)经过thrift接口,监听ui对统计信息的读取,从zookeeper上读取统计信息,返回给ui
(5)若进程退出后,当即在本机重启,则不影响集群运行。
【supervisor进程】storm集群的资源管理者,按需启动worker进程。
(1)定时从zookeeper检查是否有代码未下载到本地的新topology,定时删除旧topology代码
(2)根据nimbus的任务分配结果,在本机按需启动1个或多个worker进程,监控守护全部的worker进程。
(3)若进程退出,当即在本机重启,则不影响集群运行。
【worker进程】storm集群的任务构造者,构造spout或bolt的task实例,启动executor线程。
(1)根据zookeeper上分配的task,在本进程中启动1个或多个executor线程,将构造好的task实例交给executor去运行(死循环调用spout.nextTuple()或bolt.execute()方法)。
(2)向zookeeper写入心跳
(3)维持传输队列,发送tuple到其余的worker
(4)若进程退出,当即在本机重启,则不影响集群运行。
【executor线程】storm集群的任务执行者,循环执行task代码。
(1)执行1个或多个task(每一个task对应spout或bolt的1个并行度),将输出加入到worker里的tuple队列
(2)执行storm内部线程acker,负责发送消息处理状态给对应spoult所在的workercomponent
nimbus目前没法作到多节点的缘由orm
一、nimbus节点的ip地址在配置文件中storm.yaml,更换机器后ip地址变化,须要更新集群全部节点的配置文件后重启集群。
二、客户端submitTopology时也须要取得nimbus ip上传代码。nimbus更换机器后,client也须要修改配置文件。
三、nimbus机器的本地硬盘存放了topology的代码,更换机器后代码所有丢失,新启动的supervisor将没法下载正在运行的topology代码。
四、storm ui是从nimbus读取集群统计信息的,nimbus更换机器后ui也须要修改配置文件后重启。
五、同时启动多个nimbus节点,会面临多个nimbus并发计算topology的任务分配,并发写入zookeeper,并发清理zookeeper等诸多不可预料的问题。即便存在多个nimbus节点,storm-ui、supervisor、client等也只会使用配置文件指定的ip的节点。接口
3、nimbus HA 的解决方案队列
目前topology的jar包保存在nimbus节点的本地存储上,为了解决ha的问题,须要提供一种存储在分布式而且可靠的方式。DFS是一种完美的解决方案,可是,这不该该是一种强制的使用方式,应该提供可选的可插拔的(默认为本地文件系统,可是界面应该支持DFS)。若是你选择本地存储的方式且尝试运行多个nimbus,那么其中一个nimbus应该睡启动失败。
Nimbus应该在zookeeper中进行注册,而后使用leader election protocol来决定哪一个nimbus负责启动和监控topology。
StormSubmitter应该经过zookeeper找到须要链接的nimbus,若是在提交任务期间,leader发生改变,他应该使用retry protocol去尝试链接新的leader并再次尝试提交任务。
下图展现了nimbus ha topology做业提交序列图
leader选举没必要多说,基于Zookeeper curator recipes。咱们主要关注下代码分发,基本流程:
leader nimbus经过CodeDistributor上传代码并得到MetaFile,而后在Zookeeper建立标记;
非leader nimbus watch到Zookeeper上的变化,从leader得到MetaFile,而后根据MetaFile的描述从CodeDistributor下载代码。
目前storm1.0.0版本已经将nimbus ha加入。