zoukankan      html  css  js  c++  java
  • 【原】storm源码之一个class解决nimbus单点问题

    一、storm nimbus 单节点问题概述

    1、storm集群在生产环境部署之后,通常会是如下的结构:

    从图中可以看出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关系可以参考 http://www.cnblogs.com/yufengof/p/storm-worker-executor-task.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的节点。

    【注】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 public interface INimbusStorage {
    2     void init(Map conf);
    3     InputStream open(String path);
    4     OutputStream create(String path);
    5     List<String> list(String path);
    6     void delete(String path);
    7     void mkdirs(String path);
    8     boolean isSupportDistributed();
    9 }

    【注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状态的展示。

    但由于本地存储是不支持分布式的,即无法同时启动多个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的实现


    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

  • 相关阅读:
    21.Merge Two Sorted Lists 、23. Merge k Sorted Lists
    34. Find First and Last Position of Element in Sorted Array
    leetcode 20. Valid Parentheses 、32. Longest Valid Parentheses 、301. Remove Invalid Parentheses
    31. Next Permutation
    17. Letter Combinations of a Phone Number
    android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
    oc 异常处理
    oc 类型判断
    oc Delegate
    oc 协议
  • 原文地址:https://www.cnblogs.com/yufengof/p/storm-nimbus-ha.html
Copyright © 2011-2022 走看看