一、storm 提交任务流程
1、client : 客户端运行nimbus时,会调用strom的python脚本,该脚本为每个命令编写一个方法。
2、nimbus: nimbus启动后,接受客户端提交的任务,createTopology()会将程序员编写的spout对象和bolt对象序列化,并将用户jar包上传到nimbus物理节点目录下,进行改名。
nimbus接受到任务后,会将任务分配(task总数/worker总数),分配会产生一个assignment对象,该对象会保存到zookeeper中。
3、supervisor: supervisor通过watch机制,从zookeeper上拉取任务信息,分辨出属于自己的任务。
supervisor根据自己的任务信息,启动自己的worker, 并分配一个端口。
4、worker: woker启动后,连接zookeeper,拉取任务。worker通过反序列化,得到程序员自己定义的spout和bolt对象。
worker根据任务类型,分别执行spout任务和bolt任务。
spout的生命周期: open ,nextTuple, outPutFiled;
bolt的生命周期: prepare,execute(tuple),outPutField;
二、集群架构中,各个模块如何启动
nimbus: 用户启动;
supervisor: 用户启动;
worker: supervisor启动 ;
Task: worker启动
三、集群内部如何通信
它内部使用了disruptor通信技术,特点是:没有竞争、没有锁、非常快,单线程每秒可以处理600万订单。
disruptor是一个有界队列,而队列的应用场景自然是生产者----消费者模式,disruptor是一种线程之间信息无锁的交换方式,核心组件是环形缓冲区和序号管理器,缓冲区底层是数组。
四、消息容错机制
storm为保证消息不丢失,使用ack-fail机制,即成功时调用ack方法,失败时调用fail方法。
1、需要ack-fail时,为每一个tuple生成一个messageId,这个id是用来标识你关心的tuple,当这个tuple被完全处理是,storm框架会调用spout的ack方法,否则调用fail方法,至于消息是否重发,由自己处理。
2、是spout有并发度情况下,storm会根据tuple最开始所属的spout TaskId, 通知相应的spoutTask。
3、在流式计算中,topology的bolt组件是可以配置多个的,每个环节都需要bolt组件显示告诉storm框架,自己对当前接受的这个tuple处理完成。
4、ack机制里面,发送两种类型的tuple, 一种是原始的tuple(dataTuple), 另外一种是ackTuple<RootId, TupleId>,原始的tuple会包含一个messageId对象。
5、大概源码
Myspout{
private Map buffer = new HashMap();
spout.open()
spout.nextTuple(){
collector.emit()
buffer.put(msgId.messValue)
}
spout.declareOutputFields()
spout.ack(msgId){
//消息移除
buffer.remove(msgId)
}
spout.fail(msgId){
//消息重发
String messValue= buffer.get(msgId)
collector.emit();
}
}
MyBolt{
bolt.execute(){
//需要手动的调用ack方法
collertor.ack(tuple)
}
}
更多java、大数据学习面试资料,请扫码关注我的公众号: