背景##

前期收到的问题:

1、在Topology中我们可以指定spout、bolt的并行度,在提交Topology时Storm如何将spout、bolt自动发布到每个服务器并且控制服务的CPU、磁盘等资源的?


2、Storm处理消息时会根据Topology生成一棵消息树,Storm如何跟踪每个消息、如何保证消息不丢失以及如何实现重发消息机制?

上篇:storm是如何保证at least once语义的

回答了第2个问题。

本篇来建立一个基本的背景,来大概看下构成storm流式计算能力的一些基础框架,并部分回答第一个问题。

worker、executor、task的关系##

  1. worker是一个进程.
  2. executor是一个线程,是运行tasks的物理容器.
  3. task是对spout/bolt/acker等任务的逻辑抽象.

supervisor会定时从zookeeper获取拓补信息topologies、任务分配信息assignments及各类心跳信息,以此为依据进行任务分配。

在supervisor同步时,会根据新的任务分配情况来启动新的worker或者关闭旧的worker并进行负载均衡。

worker通过定期的更新connections信息,来获知其应该通讯的其它worker。

worker启动时,会根据其分配到的任务启动一个或多个executor线程。这些线程仅会处理唯一的topology。

如果有新的tolopogy被提交到集群,nimbus会重新分配任务,这个后面会说到。

executor线程负责处理多个spouts或者多个bolts的逻辑,这些spouts或者bolts,也称为tasks。

具体有多少个worker,多少个executor,每个executor负责多少个task,是由配置和指定的parallelism-hint共同决定的,但这个值并不一定等于实际运行中的数目。

如果计算出的总的executors超过了nimbus的限制,此topology将不会得到执行。

并行度的作用:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 计算所有tolopogy的topology-id到executors的映射
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- compute-topology->executors [nimbus storm-ids]
"compute a topology-id -> executors map"
(into {} (for [tid storm-ids]
{tid (set (compute-executors nimbus tid))})))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 计算topology-id到executors的映射
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn- compute-executors [nimbus storm-id]
(let [conf (:conf nimbus)
storm-base (.storm-base (:storm-cluster-state nimbus) storm-id nil)
component->executors (:component->executors storm-base)
storm-conf (read-storm-conf conf storm-id)
topology (read-storm-topology conf storm-id)
task->component (storm-task-info topology storm-conf)]
(->> (storm-task-info topology storm-conf)
reverse-map
(map-val sort)
(join-maps component->executors)
(map-val (partial apply partition-fixed))
(mapcat second)
(map to-executor-id)
)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 计算topology的task-info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defn storm-task-info
"Returns map from task -> component id"
[^StormTopology user-topology storm-conf]
(->> (system-topology! storm-conf user-topology)
all-components
;; 获取每个组件的并行数
(map-val (comp #(get % TOPOLOGY-TASKS) component-conf))
(sort-by first)
(mapcat (fn [[c num-tasks]] (repeat num-tasks c)))
(map (fn [id comp] [id comp]) (iterate (comp int inc) (int 1)))
(into {})
))

上述代码会在nimbus进行任务分配时调用:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; nimbus进行任务分配
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
mk-assignments
->compute-new-topology->executor->node+port
->compute-topology->executors
-> ...

线程模型及消息系统##

基本关系如下所示:

  1. worker启动时,除了启动多个executor线程,还会启动多个工作线程来负责消息传递。

  2. worker会订阅到transfer-queue来消费消息,同时也会发布消息到transfer-queue,比如需要进行远程发布时(某个bolt在另一个进程或者节点上)。

  3. executor会发布消息到executor-send-queue比如emit tuple,同时会从executor-receive-queue消费消息,比如执行ack或者fail。

  4. batch-transfer-worker-handler线程订阅到executor-send-queue消费消息,并将消息发布到transfer-queue供worker消费。

  5. transfer-thread会订阅到transfer-queue消费消息,并负责将消息通过socket发送到远程节点的端口上。

  6. worker通过receive-thread线程来收取远程消息,并将消息以本地方式发布到消息中指定的executor对应的executor-receive-queue。executor按第3点来消费消息。

  7. 以上所有的消息队列都是Disruptor Queue,非常高效的线程间通讯框架。

所谓本地发布,是指在worker进程内及executor线程间进行消息发布。

所谓远程发布,是指在worker进程间、不同的机器间进行消息发布。

任务调度及负载均衡##

任务调度的主要角色###

  1. nimbus将可以工作的worker称为worker-slot.

  2. nimbus是整个集群的控管核心,总体负责了topology的提交、运行状态监控、负载均衡及任务重新分配,等等工作。

    nimbus分配的任务包含了topology代码所在的路径(在nimbus本地)、tasks、executors及workers信息。

    worker由node + port唯一确定。

  3. supervisor负责实际的同步worker的操作。一个supervisor称为一个node。所谓同步worker,是指响应nimbus的任务调度和分配,进行worker的建立、调度与销毁。

    其通过将topology的代码从nimbus下载到本地以进行任务调度。

  4. 任务分配信息中包含task到worker的映射信息task -> node + host,所以worker节点可据此信息判断跟哪些远程机器通讯。

集群的状态机:

集群状态管理###

集群的状态是通过一个storm-cluster-state的对象来描述的。

其提供了许多功能接口,比如:

  1. zookeeper相关的基本操作,如create-node、set-data、remove-node、get-children等.
  2. 心跳接口,如supervisor-heartbeat!、worker-heatbeat!等.
  3. 心跳信息,如executors-beats等.
  4. 启动、更新、停止storm,如update-storm!等.

如下图所示:

任务调度的依据###

  1. zookeeper是整个集群状态同步、协调的核心组件。

  2. supervisor、worker、executor等组件会定期向zookeeper写心跳信息。

  3. 当topology出现错误、或者有新的topology提交到集群时,topologies信息会同步到zookeeper。

  4. nimbus会定期监视zookeeper上的任务分配信息assignments,并将重新分配的计划同步到zookeeper。

所以,nimbus会根据心跳、topologies信息及已分配的任务信息为依据,来重新分配任务,如下图所示:

任务调度的时机###

  1. 如上文的状态机图所示,rebalance和do-reblalance(比如来自web调用)会触发mk-assignments即任务(重新)分配。

  2. 同时,nimbus进程启动后,会周期性地进行mk-assignments调用,以进行负载均衡和任务分配。

  3. 客户端通过storm jar ... topology 方式提交topology,会通过thrift接口调用nimbus的提交功能,此时会启动storm,并触发mk-assignments调用。

topology提交过程##

一个topology的提交过程:

  1. 非本地模式下,客户端通过thrift调用nimbus接口,来上传代码到nimbus并触发提交操作.

  2. nimbus进行任务分配,并将信息同步到zookeeper.

  3. supervisor定期获取任务分配信息,如果topology代码缺失,会从nimbus下载代码,并根据任务分配信息,同步worker.

  4. worker根据分配的tasks信息,启动多个executor线程,同时实例化spout、bolt、acker等组件,此时,等待所有connections(worker和其它机器通讯的网络连接)启动完毕,此storm-cluster即进入工作状态。

  5. 除非显示调用kill topology,否则spout、bolt等组件会一直运行。

主要过程如下图所示:

结语##

以上,基本阐述了storm的基础框架,但未涉及trident机制,也基本回答了问题1。

终。

storm基础框架分析的更多相关文章

  1. Java并发基础框架AbstractQueuedSynchronizer初探(ReentrantLock的实现分析)

    AbstractQueuedSynchronizer是实现Java并发类库的一个基础框架,Java中的各种锁(RenentrantLock, ReentrantReadWriteLock)以及同步工具 ...

  2. linux驱动基础系列--linux spi驱动框架分析

    前言 主要是想对Linux 下spi驱动框架有一个整体的把控,因此会忽略某些细节,同时里面涉及到的一些驱动基础,比如平台驱动.设备模型等也不进行详细说明原理.如果有任何错误地方,请指出,谢谢! spi ...

  3. linux驱动基础系列--linux spi驱动框架分析(续)

    前言 这篇文章是对linux驱动基础系列--linux spi驱动框架分析的补充,主要是添加了最新的linux内核里设备树相关内容. spi设备树相关信息 如之前的文章里所述,控制器的device和s ...

  4. 源码分析:同步基础框架——AbstractQueuedSynchronizer(AQS)

    简介 AQS 全称是 AbstractQueuedSynchronizer,位于java.util.concurrent.locks 包下面,AQS 提供了一个基于FIFO的队列和维护了一个状态sta ...

  5. Storm基础概念与单词统计示例

    Storm基本概念 Storm是一个分布式的.可靠地.容错的数据流处理系统.Storm分布式计算结构称为Topology(拓扑)结构,顾名思义,与拓扑图十分类似.该拓扑图主要由数据流Stream.数据 ...

  6. 几款开源的hybird移动app框架分析

    几款开源的Hybrid移动app框架分析 Ionic Onsen UI 与 ionic 相比 jQuery Mobile Mobile Angular UI 结论 很多移动开发者喜欢使用原生代码开发, ...

  7. 一个简单的、面向对象的javascript基础框架

    如果以后公司再能让我独立做一套新的完整系统,那么我肯定会为这个系统再写一个前端框架,那么我到底该如何写这个框架呢? 在我以前的博客里我给大家展示了一个我自己写的框架,由于当时时间很紧张,做之前几乎没有 ...

  8. 准备.Net转前端开发-WPF界面框架那些事,搭建基础框架

    题外话 最近都没怎么写博客,主要是最近在看WPF方面的书<wpf-4-unleashed.pdf>,挑了比较重要的几个章节学习了下WPF基础技术.另外,也把这本书推荐给目前正在从事WPF开 ...

  9. 微服务架构的基础框架选择:Spring Cloud还是Dubbo?

    最近一段时间不论互联网还是传统行业,凡是涉及信息技术范畴的圈子几乎都在讨论微服务架构.近期也看到各大技术社区开始组织一些沙龙和论坛来分享Spring Cloud的相关实施经验,这对于最近正在整理Spr ...

随机推荐

  1. 测试mysql的sql语句预编译效果

    玩Oracle的都比较关注shared pool,特别是library cache,在使用了绑定变量(预编译sql)之后确实能得到很大的性能提升.现在在转Mysql之后特别是innodb很多东西都还能 ...

  2. 有关RDS上只读实例延时分析-同适用于自建MySQL主从延时分析判断

    个人不是很喜欢在技术上跟人互喷,尤其是不在同一个岗位上的人.一方面本人的性格如此,另一方面,我自身的口水也确实是不行,人生经历了第一次的双11洗礼,在大促的环境下,总算知道了有些东西是否应该规避,这次 ...

  3. Mongodb 主从复制与副本集实验

    1.实验主从复制,并验证复制成功,抓图实验过程  Step1:创建相应的目录 Mkdir -p ./dbs/master Mkdir -p ./dbs/slave Step2:开启主服务 ./bin/ ...

  4. 【C#】SQL数据库助手类2.0(自用)

    using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...

  5. 【实践】jdbc批量插入数据

    参考文献:http://my.oschina.net/u/1452675/blog/203670 http://superjavason.iteye.com/blog/255423 /*测试批量写入数 ...

  6. 【转】UVALive 5964 LCM Extreme --欧拉函数

    题目大意:求lcm(1,2)+lcm(1,3)+lcm(2,3)+....+lcm(1,n)+....+lcm(n-2,n)+lcm(n-1,n)解法:设sum(n)为sum(lcm(i,j))(1& ...

  7. 链表面试题Java实现【重要】

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  8. MongoDB学习(一)简介

    本篇主要简单介绍一下MongoDB数据库. 一.简介 mongoDB是一个开源的,基于分布式的,面向文档存储的非关系型数据库.是非关系型数据库当中功能最丰富.最像关系数据库的. mongoDB由C++ ...

  9. js的nextSibling,属性兼容IE和FF等浏览器

    Firefox中 空白字符,比如回车,空格等也算作一个Node 就是firstChild,nextsbiling这两个.下面给出函数吧.还是代码比较说明问题代码都是网上来的.不过要注意的是,getNe ...

  10. POJ 1141 Brackets Sequence

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29502   Accepted: 840 ...