集群容错:
1.Nimbus挂掉
如果失去了Nimbus节点,Worker也会继续执行;如果workerye消亡,Supervisor会重启worker。
但是如果没有Nimbus,worker不会被安排到其他主机节点,客户端也无法提交新的任务。
2.zookeeper挂掉
zookeeper有主从结构,挂掉无影响。
3.Supervisor失败
真正执行进程的是worker,所以Supervisor失败不会影响但前运行的任务,且所有状态都保存在zookeeper或磁盘上,Nimbus及时通过zookeeper重启Supervisor即可
4.worker失败
worker是真正的执行节点,每个worker包含数个spout/bolt任务。supervisor负责监控这些任务,当Supervisor重启worker超过了一定的失败重启次数,无法发送心跳到Nimbus,Nimbus将在另一台主机上重新分配worker。
数据容错:
容错机制 :
一般来说,分布式数据集的容错性有两种方式:数据检查点和记录数据的更新。
面向大规模数据分析,数据检查点操作成本很高,需要通过数据中心的网络连接在机器之间复制庞大的数据集,
而网络带宽往往比内存带宽低的多,同事还需要消耗更多的存储资源。
storm:数据检查
ack机制即,spout发送的每一条消息:
1)在规定时间内,spout收到acker的ack响应,即认为该tuple被后续bolt成功处理
2)在规定时间内,没有收到acker的ack响应tuple,就触发fail动作,即认为该tuple处理失败
3)收到acker发送的fail响应tuple,认为失败,触发fail动作
限流作用:为了避免spout发送数据太快,而bolt处理太慢 ,二选一即可
1)需要设置pending数,当spout有等于或超过peding数的tuple没有收到ack或fail响应时,跳过执行nextTuple,从而限制spout发送数据
2)设置最大超时时间
通过 Config.TOPOLOGY_MESSAGE_TIMEOUT_SECS来指定
通过conf.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, pending);设置spout pend数。
关闭Ack机制
1)spout发送数据时不带上msgid
collector.emit(new Values(“value1”,“value2”), msgId);
2)设置acker数等于0
将参数Config.TOPOLOGY_ACKERS设置为0,通过此方法,当Spout发送一个消息的时候,它的ack方法将立刻被调用
ack应答机制可以帮助识别消息是否成功消费,but也仅仅是通过messageId标识,消费失败的数据需要我们自己来做缓存,然后在重新发射出去。
保证消息的可靠性前提: emit发射数据一定要发射messageId
代码实现概要思路:
1)成员变量定义一个ConcurrentHashMap (ConcurrentHashMap是线程安全的,分段锁,效率高),且该map只能初始化不能创建对象,创建对象会有运行异常,需要重写open初始化方法中创建对象
2)这个messageId可以是上游中获取的,也可以是在当前定义的
3)nextTuple() 中通过map缓存tuple与messageId,其中key=messageId,value=tuple;发射数据
4)处理成功,调用ack(messageId)。从缓存中删除该数据
5)处理失败,调用fail(messageId)。重新发射根据messageId从缓存中获取的tuple及messageId。
说明:
1)数据处理成功/失败,是指当前的spout/bolt。如果需要下游的数据处理成功上游才删除数据,那么需要缓存数据库缓存数据,内存集合不行。
2)storm是分布式多线程并发操作,跨jvm。此例中的map近对当前spout/bolt的当前线程起作用。横跨上下游的/集群的需要用缓存数据库操作。
3)框架不包含事物操作,更不包含对数据库的事务操作。比如入库操作,需要记录消息的入口状态,再次入库时查询状态判定是否给予执行。