storm(六) 可靠性

 

集群可靠性

参考:http://storm.apache.org/releases/1.2.2/Daemon-Fault-Tolerance.html

Worker可靠性

  • worker挂掉了,supervisor会重新启动worker。
  • 如果在启动的过程中不断的失败,nimbus没有收到心跳,nimbus会将worker调度到其他supervisor上启动

部署supervisor的机器失去连接

  • 如果任务分发的时候失败,nimbus会将任务分发给其他的supervisor

nimbus或者supervisor进程挂掉

  • nimbus和supervisor挂掉后也没有太大的问题,因为他们的运行状态全部存放在zk上,所以这个时候如果用监控工具重启节点,不会有任何影响
  • nimbus和supervisor挂掉都不回影响worker的继续执行,worker是单独的进程在执行
  • nimbus挂掉后不能接收新的topo任务
  • 1.0版本后nimbus不在是单节点,是多节点容错

数据可靠性

  • best effort(最大努力), at least once(至少执行一次), and exactly once (正好执行一次)

参考:http://storm.apache.org/releases/1.2.2/Guaranteeing-message-processing.html

  • 消息处理失败的标准:在特定时间内没有将tuple的消息树处理完成

消息可靠性的处理过程

  • 整个消息可靠性由spout bolt acker共同配合完成
    • spout在发出消息的时候会给每个消息一个msg id。该id由用户自己维护
    • 每一个bolt执行完成后都需要确认collector.ack(),处理失败则调用collector.failed()。新产生的tuple需要锚点到旧tuple上:this.collector.emit(oldtuple,newtuple);
    • 如果storm识别到tuple在整个树上处理完成,将会调用spout上的ack()方法;如果超时或者失败将会调用fail()方法。超时时间可以再定义topology的时候设置,默认30秒
  • storm中提供了一个BaseBasicBolt,相比BaseRichBolt,他有tuple的自动关联,和tuple的自动确认

参考:https://blog.csdn.net/suifeng3051/article/details/41682441

spout

  • 在发送的时候带上messageId,这个id可以是数据库中的主键
  • ack() fail()中添加一些处理逻辑。fail后可以选择:1、重试处理;2、记录到日志中
public class NumSpout extends BaseRichSpout{

    private SpoutOutputCollector collector;
    private Integer number=0;
    private List<Integer> idList;

    public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
        this.collector=collector;
        this.idList=context.getComponentTasks("countNum");
    }
    public void nextTuple() {
    //发出的消息上带上msgId
        collector.emit(new Values(++number),number);
        System.out.println("number:"+number);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
        declarer.declare(new Fields("num"));
    }
    @Override
    public void ack(Object msgId) {
        System.out.println(String.format("msgId is %s. ack!",msgId));
    }
    @Override
    public void fail(Object msgId) {
        System.out.println(String.format("msgId is %s. failed!",msgId));
        collector.emit(new Values(msgId),msgId);
    }
}

bolt处理

  • 最终消息处理完后,手动确认消息处理完成
public class SumBolt extends BaseRichBolt {

    private int total=0;
    private OutputCollector collector;
    public void prepare(Map stormConf, TopologyContext context, OutputCollector collector) {
        this.collector=collector;
    }

    public void execute(Tuple input) {
        Integer num=input.getIntegerByField("num");
        total+=num;
        System.out.println("thread:"+Thread.currentThread()+",total:"+total+",receive:"+num);
			//确认处理完成
            this.collector.ack(input);
        }else{
	        //确认处理失败
            this.collector.fail(input);
        }
    }
    public void declareOutputFields(OutputFieldsDeclarer declarer) {
    }
}

acker可靠性算法

  • acker负责跟踪每一个spout发出的tuple。
  • 每一个tuple消息,无论是谁产生的(spout或者bolt),都会分配一个随机的64位id。新产生的tuple会携带有spout tuple id,处理完后向acker发消息确认(携带64位id)
  • 在有多个acker的时候,会通过hash取模的方式分配spout tuple id和acker对应关系
  • acker存储一个map:
    • key:spout tuple id(64位随机数,acker负责生成)
    • value:
      • 1、发射消息的spout的id
      • 2、ack val(在产生tuple或者确认tuple的时候都会用ack val和该tuple的id进行异或,当最终值成0后说明处理完成)

http://storm.apache.org/releases/1.2.2/Guaranteeing-message-processing.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值