1、集群节点宕机
Nimbus服务器
  单点故障,大部分时间是闲置的,在supervisor挂掉时会影响,所以宕机影响不大,重启即可
非Nimbus服务器
  故障时,该节点上所有Task任务都会超时,Nimbus会将这些Task任务重新分配到其他服务器上运行

2、进程挂掉
Worker
  挂掉时,Supervisor会重新启动这个进程。如果启动过程中仍然一直失败,并且无法向Nimbus发送心跳,Nimbus会将该Worker重新分配到其他服务器上
Supervisor
  无状态(所有的状态信息都存放在Zookeeper中来管理)
  快速失败(每当遇到任何异常情况,都会自动毁灭)
Nimbus
  无状态(所有的状态信息都存放在Zookeeper中来管理)
  快速失败(每当遇到任何异常情况,都会自动毁灭)

3、消息的完整性
从Spout中发出的Tuple,以及基于他所产生Tuple,由这些消息就构成了一棵tuple树,当这棵tuple树发送完成,并且树当中每一条消息都被正确处理,就表明spout发送消息被“完整处理”,即消息的完整性,storm使用Acker确保消息完整性,Acker是拓扑当中特殊的一些任务,负责跟踪每个Spout发出的Tuple的DAG(有向无环图)
Acker分为ack确认机制和fail失败处理机制,Spout作为数据源,当拓扑中bolt处理失败时该怎么办?Acker机制可以重发数据到bolt进行重新处理。

看下面的例子:

MessageSpout  ---->   split-bolt  ---->    write-bolt

MessageTopology
package bhz.topology;

import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.topology.TopologyBuilder;
import bhz.bolt.SpliterBolt;
import bhz.bolt.WriterBolt;
import bhz.spout.MessageSpout; public class MessageTopology { public static void main(String[] args) throws Exception {
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("spout", new MessageSpout());
builder.setBolt("split-bolt", new SpliterBolt()).shuffleGrouping("spout");
builder.setBolt("write-bolt", new WriterBolt()).shuffleGrouping("split-bolt");
//本地配置
Config config = new Config();
config.setDebug(false);
LocalCluster cluster = new LocalCluster();
System.out.println(cluster);
cluster.submitTopology("message", config, builder.createTopology());
Thread.sleep(10000);
cluster.killTopology("message");
cluster.shutdown();
}
}

MessageSpout

package bhz.spout;

import java.util.Map;

import backtype.storm.spout.SpoutOutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichSpout;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Values; public class MessageSpout implements IRichSpout { private static final long serialVersionUID = 1L; private int index = 0; private String[] subjects = new String[]{
"groovy,oeacnbase",
"openfire,restful",
"flume,activiti",
"hadoop,hbase",
"spark,sqoop"
}; private SpoutOutputCollector collector; @Override
public void open(Map conf, TopologyContext context, SpoutOutputCollector collector) {
this.collector = collector;
} @Override
public void nextTuple() {
if(index < subjects.length){
String sub = subjects[index];
//发送信息参数1 为数值, 参数2为msgId
collector.emit(new Values(sub), index);
index++;
}
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("subjects"));
}
//当bolt 处理成功 ack确认 spout执行ack方法
@Override
public void ack(Object msgId) {
System.out.println("【消息发送成功!!!】 (msgId = " + msgId +")");
}
//当bolt处理失败时,spout调用fail方法,进行重发处理
@Override
public void fail(Object msgId) {
System.out.println("【消息发送失败!!!】 (msgId = " + msgId +")");
System.out.println("【重发进行中...】");
collector.emit(new Values(subjects[(Integer) msgId]), msgId);
System.out.println("【重发成功!!!】");
} @Override
public void close() { } @Override
public void activate() { } @Override
public void deactivate() { } @Override
public Map<String, Object> getComponentConfiguration() {
return null;
} }

SpliterBolt

package bhz.bolt;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Fields;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values; public class SpliterBolt implements IRichBolt { private static final long serialVersionUID = 1L; private OutputCollector collector; @Override
public void prepare(Map config, TopologyContext context, OutputCollector collector) {
this.collector = collector;
} private boolean flag = false; @Override
public void execute(Tuple tuple) {
try {
String subjects = tuple.getStringByField("subjects"); if(!flag && subjects.equals("flume,activiti")){
flag = true;
int a = 1/0;
} String[] words = subjects.split(",");
//List<String> list = new ArrayList<String>();
//int index = 0;
for (String word : words) {
//注意这里循环发送消息,要携带tuple对象,用于处理异常时重发策略
collector.emit(tuple, new Values(word));
//list.add(word);
//index ++;
}
//collector.emit(tuple, new Values(list));
collector.ack(tuple);//通知spout处理成功
} catch (Exception e) {
e.printStackTrace();
collector.fail(tuple);//通知spout 处理失败
}
} @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
declarer.declare(new Fields("word"));
} @Override
public void cleanup() { } @Override
public Map<String, Object> getComponentConfiguration() {
return null;
} }

WriterBolt

package bhz.bolt;

import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map; import backtype.storm.task.OutputCollector;
import backtype.storm.task.TopologyContext;
import backtype.storm.topology.IRichBolt;
import backtype.storm.topology.OutputFieldsDeclarer;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values; public class WriterBolt implements IRichBolt { private static final long serialVersionUID = 1L; private FileWriter writer; private OutputCollector collector; @Override
public void prepare(Map config, TopologyContext context, OutputCollector collector) {
this.collector = collector;
try {
writer = new FileWriter("d://message.txt");
} catch (IOException e) {
e.printStackTrace();
}
} private boolean flag = false; @Override
public void execute(Tuple tuple) {
String word = tuple.getString(0);
// List<String> list = (List<String>)tuple.getValueByField("word");
// System.out.println("======================" + list);
try {
if(!flag && word.equals("hadoop")){
flag = true;
int a = 1/0;
}
writer.write(word);
writer.write("\r\n");
writer.flush();
} catch (Exception e) {
e.printStackTrace();
collector.fail(tuple);//通知spout处理失败
}
collector.emit(tuple, new Values(word));
collector.ack(tuple);//通知spout处理成功
} @Override
public void cleanup() { } @Override
public void declareOutputFields(OutputFieldsDeclarer declarer) { } @Override
public Map<String, Object> getComponentConfiguration() {
return null;
} }

spout重发机制会带来一个问题:数据重复消费,看上面的例子当WriterBolt执行失败的时候,spout 将hadoop,hbase重发,那么hbase会被WriterBolt再执行一次,目前storm对此没有保障机制,按照业务设计的通用做法就是使用幂等性(比如使用唯一性ID),防止重复消费数据。

大数据处理框架之Strom:容错机制的更多相关文章

  1. 大数据处理框架之Strom: Storm----helloword

    大数据处理框架之Strom: Storm----helloword Storm按照设计好的拓扑流程运转,所以写代码之前要先设计好拓扑图.这里写一个简单的拓扑: 第一步:创建一个拓扑类含有main方法的 ...

  2. 大数据处理框架之Strom:认识storm

    Storm是分布式实时计算系统,用于数据的实时分析.持续计算,分布式RPC等. (备注:5种常见的大数据处理框架:· 仅批处理框架:Apache Hadoop:· 仅流处理框架:Apache Stor ...

  3. 大数据处理框架之Strom: Storm拓扑的并行机制和通信机制

    一.并行机制 Storm的并行度 ,通过提高并行度可以提高storm程序的计算能力. 1.组件关系:Supervisor node物理节点,可以运行1到多个worker,不能超过supervisor. ...

  4. 大数据处理框架之Strom:Flume+Kafka+Storm整合

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 storm-0.9 apache-flume-1.6.0 ...

  5. 大数据处理框架之Strom:DRPC

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 storm-0.9 一.DRPC DRPC:Distri ...

  6. 大数据处理框架之Strom:Storm集群环境搭建

    搭建环境 Red Hat Enterprise Linux Server release 7.3 (Maipo)      zookeeper-3.4.11 jdk1.7.0_80      Pyth ...

  7. 大数据处理框架之Strom:事务

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk1.8 storm-0.9 apache-flume-1.6.0 ...

  8. 大数据处理框架之Strom:redis storm 整合

    storm 引入redis ,主要是使用redis缓存库暂存storm的计算结果,然后redis供其他应用调用取出数据. 新建maven工程 pom.xml <project xmlns=&qu ...

  9. 大数据处理框架之Strom:kafka storm 整合

    storm 使用kafka做数据源,还可以使用文件.redis.jdbc.hive.HDFS.hbase.netty做数据源. 新建一个maven 工程: pom.xml <project xm ...

随机推荐

  1. Qt::带返回值的信号发射方式

    一般来说,我们发出信号使用emit这个关键字来操作,但是会发现,emit并不算一个调用,所以它没有返回值.那么如果我们发出这个信号想获取一个返回值怎么办呢? 两个办法:1.通过出参形式返回,引用或者指 ...

  2. redis设置bind

    1>注释掉bind #bind 127.0.0.1 2>默认不是守护进程方式运行,这里可以修改 daemonize no 3>禁用保护模式 protected-mode no 启动R ...

  3. 集合求交集 & 去除列表中重复的元素

    集合求交集: set1 = {1,2,3,4,5} set2 = {4,5,6,7,8} 交集:set3 = set1 & set2 print(ste3) #结果为{4,5} 或者ste1. ...

  4. linux 修改centos7的网卡ens33修改为eth0

    Linux 操作系统的网卡设备的传统命名方式是 eth0.eth1.eth2等,而 CentOS7 提供了不同的命名规则,默认是基于固件.拓扑.位置信息来分配.这样做的优点是命名全自动的.可预知的,缺 ...

  5. 005-优化web请求一-gzip压缩、http缓存控制和缓存校验[Pragma、Expires、Cache-Control、max-age、Last-Modified、用户刷新访问、避免过度304]

    优化Web应用的典型技术:缓存控制头信息.Gzip.应用缓存.ETag.反应型技术[异步方法调用和WebSocket] 一.模板缓存 spring.thymeleaf.cache=true sprin ...

  6. docker知识点

    1  安装 http://www.runoob.com/docker/centos-docker-install.html 2  dockerhub官网找到 emqttd 执行 docker pull ...

  7. Django 模板中 变量 过滤器的使用方法

    一.变量       1.变量的形式是:{{variable}}, 当模板引擎碰到变量的时候,引擎使用变量的值代替变量.    2.使用dot(.)能够访问变量的属性    3.当模板引擎碰到dot的 ...

  8. MySQL更新

    1.两表更新(用一个表更新另一个表) UPDATE t_i_borrower a, t_supplier s SET a.type = s.type WHERE a.cust_id = s.cust_ ...

  9. shell 脚本中如何添加多行注释

    shell中有时会用到多行注释,一种时vim的快捷方式,我不太熟悉,一种是如下 :<<!   ......! 使用: :<< !.......! 比如: :<< ! ...

  10. react 嵌套组件的通信

    在react中经常会用到的组件嵌套,如下: 图中 parent本身是一个自定义的组件,然后内部又加入了 child的自定义组件,那么这种情况,父子之间如何通信 react中在父组件里面有一个 this ...