【原】storm源码之一个class解决nimbus单点问题
2013-09-14 17:05
309 查看
一、storm nimbus 单节点问题概述
1、storm集群在生产环境部署之后,通常会是如下的结构:
![](http://images.cnitblog.com/blog/555086/201309/14163602-784d32eaba26405d8a34db01742c8cc4.jpg)
从图中可以看出zookeeper和supervisor都是多节点,任意1个zookeeper节点宕机或supervisor节点宕机均不会对系统整体运行造成影响,但nimbus和ui都是单节点。ui的单节点对系统的稳定运行没有影响,仅提供storm-ui页面展示统计信息。但nimbus承载了集群的许多工作,如果nimbus单节点宕机,将会使系统整体的稳定运行造成极大风险。因此解决nimbus的单点问题,将会更加完善storm集群的稳定性。
2、storm nimbus单节点的风险
(1)功能上,nimbus进程退出后,如果再同时发生worker进程宕机,宕机的worker将无法重启,集群将会有部分消息始终无法得到处理。
(2)监控上,nimbus进程不可用时,storm ui将无法访问。
(3)几率上,机房由于演练或故障不可用时即会出现nimbus与worker进程同时故障的情形,面对风险的几率较大。
二、storm与解决nimbus单点相关的概念
1、【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)若进程退出后,立即在本机重启,则不影响集群运行。
2、【supervisor进程】storm集群的资源管理者,按需启动worker进程。
(1)定时从zookeeper检查是否有代码未下载到本地的新topology,定时删除旧topology代码
(2)根据nimbus的任务分配结果,在本机按需启动1个或多个worker进程,监控守护所有的worker进程。
(3)若进程退出,立即在本机重启,则不影响集群运行。
3、【worker进程】storm集群的任务构造者,构造spout或bolt的task实例,启动executor线程。
(1)根据zookeeper上分配的task,在本进程中启动1个或多个executor线程,将构造好的task实例交给executor去运行(死循环调用spout.nextTuple()或bolt.execute()方法)。
(2)向zookeeper写入心跳
(3)维持传输队列,发送tuple到其他的worker
(4)若进程退出,立即在本机重启,则不影响集群运行。
4、【executor线程】storm集群的任务执行者,循环执行task代码。
(1)执行1个或多个task(每个task对应spout或bolt的1个并行度),将输出加入到worker里的tuple队列
(2)执行storm内部线程acker,负责发送消息处理状态给对应spoult所在的worker
【注1】Worker、Executor、Task关系可以参考 /article/5416815.html
三、nimbus目前无法做到多节点的原因
1、nimbus节点的ip地址在配置文件中storm.yaml,更换机器后ip地址变化,需要更新集群所有节点的配置文件后重启集群。
2、客户端submitTopology时也需要取得nimbus ip上传代码。nimbus更换机器后,client也需要修改配置文件。
3、nimbus机器的本地硬盘存放了topology的代码,更换机器后代码全部丢失,新启动的supervisor将无法下载正在运行的topology代码。
4、storm ui是从nimbus读取集群统计信息的,nimbus更换机器后ui也需要修改配置文件后重启。
5、同时启动多个nimbus节点,会面临多个nimbus并发计算topology的任务分配,并发写入zookeeper,并发清理zookeeper等诸多不可预料的问题。即使存在多个nimbus节点,storm-ui、supervisor、client等也只会使用配置文件指定的ip的节点。
![](http://images.cnitblog.com/blog/555086/201309/14163719-845253aaf72349de80c0b561073a3154.jpg)
【注】storm在设计之初就做到了节点进程间通过zookeeper松散耦合,进程相对独立,单个进程的退出不会影响集群运行,因此nimbus做到多节点并不存在十分巨大的困难。但作者@Nathanmarz认为nimbus单节点问题并不是storm最紧急和严重的问题,因此在0.8.2版本之前nimbus ip地址依旧是在配置文件。
四、解决nimbus单点问题的关键
1、supervisor、client、ui对nimbus节点ip动态获取,而非由配置文件指定。
2、在nimbus更换机器后,supervisor仍然可随时下载到topology的代码。
五、业界对nimbus单点问题的努力
1、storm作者Nathanmarz对高可用的nimbus提出了这样的规划:
nimbus目前的本地存储topology代码方式需要更加灵活,比如既支持本地存储,也支持分布式存储
nimbus节点之间需要实现基于zookeeper的自选举机制
客户端能够通过zookeeper找到nimbus leader的ip地址来submit topology
2、来自俄罗斯的@Frostmanfork了storm-0.8.2,并在此版本基础上着手实现Nathanmarz对nimbus-ha的规划。Frostman抽象出了INimbusStorage.java存储接口:
【注1】INimbusStorage为topology代码的分布式存储与本地存储预留了接口,Forstman同时提供了本地存储实现类storage.clj。
【注2】Nathanmarz因此在0.8.2版本的基础上,新开了storm-0.8.2-ha分支,专门用来解决nimbus单点问题,并将Frostman已完成的nimbus-storage代码合并到该分支。
3、Frostman在nimbus-storage基础上继续增加了nimbus多节点选举机制,(目前尚未被Nathanmarz合并入storm-ha分支)。
nimbus多节点选举机制真正实现了nimbus的多节点启动。nimbus进程启动后即通过抢占zookeeper的InterProcessMutex锁成为leader,非leader的nimbus进程一直处于block状态,不进行后续工作,当leader宕机时,抢占到锁的下1个节点成为新leader。由此解决了多nimbus进程会并发读写zookeeper的问题。
Frostman同时将所有配置文件中的nimbus ip地址转移到了zookeeper中存储leader ip地址,并在storm-ui中增加了nimbus多节点leader状态的展示。
![](http://images.cnitblog.com/blog/555086/201309/14163808-ee0f5ae0ba5c49c7b57a9175ea07c7be.png)
但由于本地存储是不支持分布式的,即无法同时启动多个nimbus节点(非leader节点无topology代码),因此其选举功能也仅限于演示,无法实际运用。
4、来自yahoo的@anfeng (twitter @Andy Feng)试图将nimbus及ui使用的端口号由配置文件指定改为自动查找可用端口,但作者建议其在Frostman的nimbus-ha基础上增加此feature,这样storm-ha将更加趋于智能化。
六、nimbus单点问题的解决思路
1、Frostman的工作已为彻底解决nimbus单点问题奠定了重要基础:
nimbus ip地址动态获取
topology代码存储方案可定制
nimbus多节点选举,宕机自动切换
nimbus leader状态ui展示
在Frostman工作的基础上继续深入,将极大减少工作量。
2、Frostman并未解决topology代码如何在多个nimbus节点或集群所有节点间共享的问题。Nathamarz的理想规划是:实现storm集群中所有nimbus、supervisor机器之间通过P2P协议共享topology代码,但目前限于BitTorrent未完成的工作,目前暂停了nimbus-ha分支的开发。
3、最终选定的解决方案:实现定制的nimbus-storage插件NimbusCloudStorage,使得所有nimbus节点在启动后均从leader 轮询下载本地不存在的topology代码。依次满足supervisor在nimbus节点切换后下载代码的需求。
七、NimbusCloudStorage的实现
![](http://images.cnitblog.com/blog/555086/201309/14164051-d65e4b86b7844148b2703d0c5ee516b3.png)
1、 工作机制
在nimbus进程启动后,NimbusCloudStorage会启动1个新的线程,定时轮询zookeeper上正在运行的topology id,并依此比对本地存储的代码中是否有未下载的,一旦发现代码未下载,则从zookeeper获取nimbus leader节点的ip,并向其请求下载topology的代码。
2、 使用方法
在storm/conf/storm/yaml配置文件中增加【nimbus.storage: "backtype.storm.nimbus.NimbusCloudStorage"】即可
【注】Frostman已经2个月没看github了,⊙﹏⊙b汗,导致NimbusCloudStorage的pull request一直处于open状态。目前新的工作一直在fork出来的storm-ha分支commit,本地编译release版本storm-0.8.2-tb。
总结:
基于开源社区对storm-nimbus-ha的推进,通过实现新的storage插件既解决了nimbus-ha方案中重要的topology代码共享问题,又避免了对storm源码的过度侵入,实现了1个class解决nimbus-ha问题,为实现nimbus-ha提供了一种思路。其中,NimbusCloudStorage实现源码参见GitHub。
1、storm集群在生产环境部署之后,通常会是如下的结构:
![](http://images.cnitblog.com/blog/555086/201309/14163602-784d32eaba26405d8a34db01742c8cc4.jpg)
从图中可以看出zookeeper和supervisor都是多节点,任意1个zookeeper节点宕机或supervisor节点宕机均不会对系统整体运行造成影响,但nimbus和ui都是单节点。ui的单节点对系统的稳定运行没有影响,仅提供storm-ui页面展示统计信息。但nimbus承载了集群的许多工作,如果nimbus单节点宕机,将会使系统整体的稳定运行造成极大风险。因此解决nimbus的单点问题,将会更加完善storm集群的稳定性。
2、storm nimbus单节点的风险
(1)功能上,nimbus进程退出后,如果再同时发生worker进程宕机,宕机的worker将无法重启,集群将会有部分消息始终无法得到处理。
(2)监控上,nimbus进程不可用时,storm ui将无法访问。
(3)几率上,机房由于演练或故障不可用时即会出现nimbus与worker进程同时故障的情形,面对风险的几率较大。
二、storm与解决nimbus单点相关的概念
1、【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)若进程退出后,立即在本机重启,则不影响集群运行。
2、【supervisor进程】storm集群的资源管理者,按需启动worker进程。
(1)定时从zookeeper检查是否有代码未下载到本地的新topology,定时删除旧topology代码
(2)根据nimbus的任务分配结果,在本机按需启动1个或多个worker进程,监控守护所有的worker进程。
(3)若进程退出,立即在本机重启,则不影响集群运行。
3、【worker进程】storm集群的任务构造者,构造spout或bolt的task实例,启动executor线程。
(1)根据zookeeper上分配的task,在本进程中启动1个或多个executor线程,将构造好的task实例交给executor去运行(死循环调用spout.nextTuple()或bolt.execute()方法)。
(2)向zookeeper写入心跳
(3)维持传输队列,发送tuple到其他的worker
(4)若进程退出,立即在本机重启,则不影响集群运行。
4、【executor线程】storm集群的任务执行者,循环执行task代码。
(1)执行1个或多个task(每个task对应spout或bolt的1个并行度),将输出加入到worker里的tuple队列
(2)执行storm内部线程acker,负责发送消息处理状态给对应spoult所在的worker
【注1】Worker、Executor、Task关系可以参考 /article/5416815.html
三、nimbus目前无法做到多节点的原因
1、nimbus节点的ip地址在配置文件中storm.yaml,更换机器后ip地址变化,需要更新集群所有节点的配置文件后重启集群。
2、客户端submitTopology时也需要取得nimbus ip上传代码。nimbus更换机器后,client也需要修改配置文件。
3、nimbus机器的本地硬盘存放了topology的代码,更换机器后代码全部丢失,新启动的supervisor将无法下载正在运行的topology代码。
4、storm ui是从nimbus读取集群统计信息的,nimbus更换机器后ui也需要修改配置文件后重启。
5、同时启动多个nimbus节点,会面临多个nimbus并发计算topology的任务分配,并发写入zookeeper,并发清理zookeeper等诸多不可预料的问题。即使存在多个nimbus节点,storm-ui、supervisor、client等也只会使用配置文件指定的ip的节点。
![](http://images.cnitblog.com/blog/555086/201309/14163719-845253aaf72349de80c0b561073a3154.jpg)
【注】storm在设计之初就做到了节点进程间通过zookeeper松散耦合,进程相对独立,单个进程的退出不会影响集群运行,因此nimbus做到多节点并不存在十分巨大的困难。但作者@Nathanmarz认为nimbus单节点问题并不是storm最紧急和严重的问题,因此在0.8.2版本之前nimbus ip地址依旧是在配置文件。
四、解决nimbus单点问题的关键
1、supervisor、client、ui对nimbus节点ip动态获取,而非由配置文件指定。
2、在nimbus更换机器后,supervisor仍然可随时下载到topology的代码。
五、业界对nimbus单点问题的努力
1、storm作者Nathanmarz对高可用的nimbus提出了这样的规划:
nimbus目前的本地存储topology代码方式需要更加灵活,比如既支持本地存储,也支持分布式存储
nimbus节点之间需要实现基于zookeeper的自选举机制
客户端能够通过zookeeper找到nimbus leader的ip地址来submit topology
2、来自俄罗斯的@Frostmanfork了storm-0.8.2,并在此版本基础上着手实现Nathanmarz对nimbus-ha的规划。Frostman抽象出了INimbusStorage.java存储接口:
public interface INimbusStorage { void init(Map conf); InputStream open(String path); OutputStream create(String path); List<String> list(String path); void delete(String path); void mkdirs(String path); boolean isSupportDistributed(); }
【注1】INimbusStorage为topology代码的分布式存储与本地存储预留了接口,Forstman同时提供了本地存储实现类storage.clj。
【注2】Nathanmarz因此在0.8.2版本的基础上,新开了storm-0.8.2-ha分支,专门用来解决nimbus单点问题,并将Frostman已完成的nimbus-storage代码合并到该分支。
3、Frostman在nimbus-storage基础上继续增加了nimbus多节点选举机制,(目前尚未被Nathanmarz合并入storm-ha分支)。
nimbus多节点选举机制真正实现了nimbus的多节点启动。nimbus进程启动后即通过抢占zookeeper的InterProcessMutex锁成为leader,非leader的nimbus进程一直处于block状态,不进行后续工作,当leader宕机时,抢占到锁的下1个节点成为新leader。由此解决了多nimbus进程会并发读写zookeeper的问题。
Frostman同时将所有配置文件中的nimbus ip地址转移到了zookeeper中存储leader ip地址,并在storm-ui中增加了nimbus多节点leader状态的展示。
![](http://images.cnitblog.com/blog/555086/201309/14163808-ee0f5ae0ba5c49c7b57a9175ea07c7be.png)
但由于本地存储是不支持分布式的,即无法同时启动多个nimbus节点(非leader节点无topology代码),因此其选举功能也仅限于演示,无法实际运用。
4、来自yahoo的@anfeng (twitter @Andy Feng)试图将nimbus及ui使用的端口号由配置文件指定改为自动查找可用端口,但作者建议其在Frostman的nimbus-ha基础上增加此feature,这样storm-ha将更加趋于智能化。
六、nimbus单点问题的解决思路
1、Frostman的工作已为彻底解决nimbus单点问题奠定了重要基础:
nimbus ip地址动态获取
topology代码存储方案可定制
nimbus多节点选举,宕机自动切换
nimbus leader状态ui展示
在Frostman工作的基础上继续深入,将极大减少工作量。
2、Frostman并未解决topology代码如何在多个nimbus节点或集群所有节点间共享的问题。Nathamarz的理想规划是:实现storm集群中所有nimbus、supervisor机器之间通过P2P协议共享topology代码,但目前限于BitTorrent未完成的工作,目前暂停了nimbus-ha分支的开发。
3、最终选定的解决方案:实现定制的nimbus-storage插件NimbusCloudStorage,使得所有nimbus节点在启动后均从leader 轮询下载本地不存在的topology代码。依次满足supervisor在nimbus节点切换后下载代码的需求。
七、NimbusCloudStorage的实现
![](http://images.cnitblog.com/blog/555086/201309/14164051-d65e4b86b7844148b2703d0c5ee516b3.png)
1、 工作机制
在nimbus进程启动后,NimbusCloudStorage会启动1个新的线程,定时轮询zookeeper上正在运行的topology id,并依此比对本地存储的代码中是否有未下载的,一旦发现代码未下载,则从zookeeper获取nimbus leader节点的ip,并向其请求下载topology的代码。
2、 使用方法
在storm/conf/storm/yaml配置文件中增加【nimbus.storage: "backtype.storm.nimbus.NimbusCloudStorage"】即可
【注】Frostman已经2个月没看github了,⊙﹏⊙b汗,导致NimbusCloudStorage的pull request一直处于open状态。目前新的工作一直在fork出来的storm-ha分支commit,本地编译release版本storm-0.8.2-tb。
总结:
基于开源社区对storm-nimbus-ha的推进,通过实现新的storage插件既解决了nimbus-ha方案中重要的topology代码共享问题,又避免了对storm源码的过度侵入,实现了1个class解决nimbus-ha问题,为实现nimbus-ha提供了一种思路。其中,NimbusCloudStorage实现源码参见GitHub。
相关文章推荐
- storm源码之一个class解决nimbus单点问题【转】
- storm源码之一个class解决nimbus单点问题
- 使用网上流传的一个数据库连接池在Proxy.newProxyInstance处引起 java.lang.ClassCastException 问题的解决方法
- C#读写EXCEL源码提示“office检测到此文件存在一个问题。为帮助保护您的计算机,不能打开此文件。 ”的解决
- 解决一个小问题:git下载Kernel源码时只有.git\objects\pack目录下的.pack文件,而没有自动提取
- C#技巧【调用线程无法访问此对象,因为另一个线程拥有该对象的问题的解决办法】【C#读写EXCEL源码提示“office检测到此文件存在一个问题。为帮助保护您的计算机,不能打开此文件”的解决】
- java eclipse不更新class的一个小问题与解决
- (testng多个class文件执行时混乱,不是等一个class内的所有methods执行完再去执行下一个class内的内容)问题的解决
- 第91课:SparkStreaming基于Kafka Direct案例实战和内幕源码解密 java.lang.ClassNotFoundException 踩坑解决问题详细内幕版本
- 关于在myeclipse中用jsp访问实体bean的一个问题的解决(Exception sending context initialized event to listener instance of class)
- 一个Struts的莫名问题解决方法:Attribute class invalid for tag present according to TLD - 巴士飞扬-专注编程,网站,专业技术
- 使用网上流传的一个数据库连接池在Proxy.newProxyInstance处引起 java.lang.ClassCastException 问题的解决方法
- java后端解决跨域问题 新建一个filter 复制代码 public class SimpleCORSFilter implements Filter{ @Override
- 访问Storm ui界面,出现org.apache.storm.utils.NimbusLeaderNotFoundException: Could not find leader nimbus from seed hosts ["master" "slave1"]. Did you specify a valid list of nimbus hosts for confi的问题解决(图文详解)
- 一个实际问题分析及解决之七:理解websphere的classloader
- 一个java.lang.IncompatibleClassChangeError的问题解决
- 访问Storm ui界面,出现org.apache.storm.utils.NimbusLeaderNotFoundException: Could not find leader nimbus from seed hosts ["master"]. Did you specify a valid list of nimbus hosts for confi的问题解决(图文详解)
- 使用网上流传的一个数据库连接池在Proxy.newProxyInstance处引起 java.lang.ClassCastException 问题的解决方法
- cc -MM 解决:如果makefile和源码不在同一个目录下,更新头文件却不能重建目标的问题
- 使用网上流传的一个数据库连接池在Proxy.newProxyInstance处引起 java.lang.ClassCastException 问题的解决方法