概念理清
Nimbus: 负责资源分配和任务调度,运行在master环境中,是无状态的,负责全局的资源分配、任务调度、状态监控和故障检测:一方面,主节点Nimbus接收客 户端提交来的任务,验证后分配任务到从节点Supervisor上,同时把该任务的元信息写入Zookeeper目录中;另一方面,主节点Nimbus需 要通过Zookeeper实时监控任务的执行情况,当出现故障时进行故障检测,并重启失败的从节点Supervisor和工作进程Worker;
Supervisor: 负责接受nimbus分配的任务,启动和停止属于自己管理的worker进程。运行在slaves环境中,也是无状态的,负责监听并接受来自于主节点 Nimbus所分配的任务,并启动或停止自己所管理的工作进程Worker,其中,工作进程Worker负责具体任务的执行.一个完整的任务拓扑往往由分 布在多个从节点Supervisor上的Worker进程来协调执行,每个Worker都执行且仅执行任务拓扑中的一个子集.在每个Worker内部,会 有多个Executor,每个Executor对应一个线程.Task负责具体数据的计算,即,用户所实现的Spout/Blot实例.每个 Executor会对应一个或多个Task,因此,系统中Executor的数量总是小于等于Task的数量.
Topology: storm中运行的一个实时应用程序,因为各个组件间的消息流动形成逻辑上的一个拓扑结构
Spout: 在一个topology中产生源数据流的组件。通常情况下spout会从外部数据源中读取数据,然后转换为topology内部的源数据。Spout是一 个主动的角色,其接口中有个nextTuple函数,storm框架会不停的调用此函数,用户只要在其中生成源数据即可。
Bolt: 在一个topology中接受数据然后执行处理的组件,Bolt可以执行过滤,函数操作、合并、写数据库等任何操作。Bolt是一个被动角色,其接口中有 个execute(Tuple input)函数,在接收到消息后调用此函数,用户可以在其中执行自己想要的操作。
Tuple:一次消息传递的基本单元。本来应该是一个key-value的map,但是由于各个组件间传递的tuple的字段名称已经实现定义好,所以tuple只要按序填入各个value就行了,所以就是一个value list。
Stream: 源源不断传递的tuple就组成了stream。
Stream grouping: 即消息的分流方法。Storm中提供若干种实用的grouping方式,包括shuffle(随机), fields hash(按字段分组), all, global, none, direct和localOrShuffle等,下面会作详细讲解。
Storm使用场景
如实时分析,在线机器学习,持续计算,分布式RPC,ETL等等
Storm支持水平扩展,具有高容错性,保证每个消息都会得到处理,而且处理速度很快(在一个小集群中,每个结点每秒可以处理数以 百万计的消息)。 Storm的部署和运维都很便捷,而且更为重要的是可以使用任意编程语言来开发应用。
客户端命令行(storm)
(1) jar: 部署打包后的topology到storm集群
(2) kill: 结束指定的topology
(3) active: 激活topology,在代码层实现就是重新调用spout的nextTuple方法
(4) deactive: 停止topology, 在代码层实现就是停止调用spout的nextTuple方法
(5) rebalance: 将是将topology的所有任务,在整个storm集群上进行重新分布。
(6) nimbus: 启动nimbus节点
(7) supervisor: 启动supervisor 节点
(8) ui: 启动ui节点
(9) drpc: 启动drpc服务器。
流分组(Stream grouping)
在计算系统topology中,每个任务节点都可以接收消息处理然后发出消息,那么该如何分发这些消息呢,storm提供了一下一些消息分组的方式:
(1) shuffle grouping: 随机分发给下一步接收的任务
(2) fileds grouping: 根据消息流字段分发,指定字段内容相同的消息都会被发送到同一个处理任务上。例如当我们要实现计算单词个数的任务时,一般将相同的单词分发到统一个任务上计数。
(3) Partialkey grouping: 根据消息流字段分发,同时提供负载均衡功能
(4) All grouping: 消息流会流向所有的可接收任务上去。
(5)Global grouping: 所有的消息流都会流向同一个任务。
(6)None grouping: 目前功能类似shuffle grouping
(7) Direct grouping: 是通过消息流生产者指定直接的消息流消费者。使用emitDirect方法
(8) Local or shuffle grouping: 如果可接收的处理任务在同一个工作进程中则,分发到这些任务中进行处理,否则功能效果类似shuffle grouping.
Storm配置信息
storm有丰富的配置信息,并且提供多级配置。
(1) 默认配置信息都在defaults.yaml中
(2) 如果需要修改配置信息,可在storm.yaml中修改
每个storm topology也都有配置信息,可随着topology一起发布到集群,那些以TOPOLOGY开头的属性都是与topology相关配置属性。Java API提供了两种配置topology属性的方法:
(1)Internally:在spout/bolt重写getComponentConfiguration 方法,返回map配置对象
(2)Externally: 通过setSpout/ setBolt,addConfiguration/addConfigurations来配置。
整体配置信息的优先级:
配置信息的优先级是:defaults.yaml < storm.yaml < topology specific configuration < internal component specific configuration < external component specfic configuration.
Storm中的钩子(Hooks)
可以通过hook来关注捕获storm系统本身的一些时间。可通过两种方式注册使用钩子:
(1)在spout的open方法或者bolt的prepare方法中使用TopologyContext#addTaskHook方法。
(2)通过使用配置文件中配置属性”topology.auto.task.hooks”,这些hooks都会被注册到所有的spout和bolt中去。例如:要继承一个自定义监控系统的时候,很有效
Storm 需要关注的内容
(1) Spout以及Bolt都可以发出不同的数据流,通过使用OutputFieldsDeclarer的declareStream可以定义多条数据流(在实际使用storm过程中遇到过这样的疑问,现在知道怎么处理了)。
(2) It is imperative that nextTuple does not block for any spout implementation, because Storm calls all the spout methods on the same thread. 这句话的意思是在spout的实现中,不能让nextTuple方法阻塞,因为storm在同一个线程中调用spout所有的 方法(应该很好理解,注意一下就行)。
(3) Its perfectly fine to launch new threads in bolts that do processing asynchronously. OutputCollector is thread-safe and can be called at any time. : 这句话的意思是在Bolt中,使用新的线程进行异步处理是比较好的。我平时使用的时候就是这么做的,有这句话作为论证就可以放心使用了。
(4) Storm中还有一个比较广泛的应用场景就是DRPC,分布式远程过程调用,举个简单应用场景:就是将一个复杂的计算过程用storm topology来实现,其中spout负责接收参数和方法,最后一个Bolt负责发出计算结果,将其部署到服务器上,当需要计算的时候只需要通过远程调用的方式来获取结果就可以了。 目前还没有进行测试,也没有实际可使用场景,但是确实是个好东西。
暂时这么多,持续更新中..