zoukankan      html  css  js  c++  java
  • 关于storm的Spout、Bolt、及其可靠性

    本文导读:

    Component全家谱结构图
    Spout分析
      ——类图
      ——分析(接口实现)、结论
      ——可靠的与不可靠的消息(推荐
    Bolt分析 
      ——类图
      ——分析(接口实现)、结论
      ——可靠的与不可靠的Bolt(推荐

     
     

    Component:

      Storm中,Spout和Bolt都是其Component,所以,Storm定义了一个名叫IComponent的总接口。

    其全家谱结构图如下: 


      绿色部分是我们最常用、比较简单的部分。红色部分是与事务相关的,在以后的文章会具体讲解。
     
      BaseComponent 是Storm提供的“偷懒”的类。为什么这么说呢,它及其子类,都或多或少实现了其接口定义的部分方法。这样我们在用的时候,可以直接继承该类,而不是自己每次都写所有的方法。但值得一提的是,BaseXXX这种定义的类,它所实现的方法,都是空的,直接返回null
     

    Spout:

      假设我们实现一个extendsBaseRichSpout的RandomSpout类,随机发射数据,那么它的类图如下所示:
    分析:
      Spout的最顶层抽象是ISpout接口。
    • open方法是初始化动作。允许你在该spout初始化时做一些动作,传入了上下文,方便取上下文的一些数据。
    • close方法在该spout关闭前执行,但是并不能得到保证其一定被执行。spout是作为task运行在worker内,在cluster模式下,supervisor会直接kill -9 woker的进程,这样它就无法执行了。而在本地模式下,只要不是kill -9, 如果是发送停止命令,是可以保证close的执行的。
    • activatedeactivate :一个spout可以被暂时激活和关闭,这两个方法分别在对应的时刻被调用。
    • nextTuple 用来发射数据。
    • ack(Object)传入的Object其实是一个id,唯一表示一个tuple。该方法是这个id所对应的tuple被成功处理后执行。
    • fail(Object)同ack,只不过是tuple处理失败时执行。
      我们的RandomSpout 由于继承了BaseRichSpout,所以不用实现close、activate、deactivate、ack、fail和getComponentConfiguration方法,只关心最基本核心的部分。
    结论:
      通常情况下(Shell和事务型的除外),实现一个Spout,可以直接实现接口IRichSpout,如果不想写多余的代码,可以直接继承BaseRichSpout
     
    附注Storm可靠的与不可靠的消息 (分析+实例

     

    Bolt:

      假设我们实现一个extendsBaseBasicBolt的ExclaimBasicSpout类,处理数据,那么它的类图如下所示:
    疑问:为什么IBasicBolt没有继承IBolt呢?我们先往下看......
    分析:
      IBolt定义了三个方法:
    • IBolt继承了java.io.Serializable,我们在nimbus上提交了topology以后,创建出来的bolt会序列化后发送到具体执行的worker上去。worker在执行该Bolt时,会先调用prepare方法传入当前执行的上下文
    • execute接受一个tuple进行处理,并用prepare方法传入的OutputCollector的ack方法(表示成功)或fail(表示失败)来反馈处理结果。
    • cleanup 同ISpout的close方法,在关闭前调用。同样不保证其一定执行。
    备注:
      红色部分是Bolt实现需要注意的地方。Storm提供了IBasicBolt接口,其目的就是实现该接口的Bolt不用在代码中提供反馈结果了,Storm内部会自动反馈成功。如果确实需要反馈失败,可以抛出FailedException
    结论:
      通常情况下,实现一个Bolt,可以实现IRichBolt接口或继承BaseRichBolt;如果不想自己处理结果反馈,可以实现IBasicBolt接口或继承BaseBasicBolt,它实际上相当于自动做掉了prepare方法和collector.emit.ack(inputTuple)。
     
    附注:Storm可靠的与不可靠的Bolt (分析+实例

     
     

    补充——RichBolt vs BasicBolt

    直接用BasicBolt,会在execute()后自动ack/fail Tuple,而RichBolt则需要自行调用ack/fail。

    那什么时候使用RichBolt? Bolt不是在每次execute()时立刻产生新消息,需要异步的发送新消息(比如聚合一段时间的数据再发送)时,又或者想异步的ack/fail原消息时就需要。

    BasicBolt的prepare()里并没有collector参数,只在每次execute()时传入collector。而RichBolt刚好相反,你可以在初始化时就把collector保存起来,用它在任意时候发送消息。

    另外,如果用RichBolt的collector,还要考虑在发送消息时是否带上传入的Tuple,如果不带,则下游的处理节点出错也不会回溯到Spout重发。用BasicBolt则已默认带上。

  • 相关阅读:
    小木虫等论坛自动签到程序发布
    第一篇随笔
    工作和兴趣哪个更重要?
    weblogic 启动时 报错
    C#动态调用webservice (转载)
    U盘加载,卸载,拔出,插入(转载)
    Simple zip archive unzipper(转载)
    Best C# Blogs(强烈推荐)
    数据无法导入ArcSDE
    Oracle10.2.0.1.0升级Oracle10.2.0.2.0补丁安装指南(转载)
  • 原文地址:https://www.cnblogs.com/xymqx/p/4425098.html
Copyright © 2011-2022 走看看