为什么需要对storm中的拓扑进行资源隔离

从部署结构来看,storm集群上的业务拓扑是混跑的,不可避免会出现资源争夺进而相互影响,主要有以下几种情况:

  • 由于程序bug导致资源占用异常
  • 由于消息量突增,而拓扑Bolt的并行度设置太小,导致消息在storm内部队列(disruptor queue)堆积,最终导致CPU使用率增高
  • 由于Bolt依赖的资源变慢,导致处理能力不足,导致消息堆积,CPU使用增高

storm拓扑部署结构

cgroup简介

概念

cgroups(control groups)是Linux内核提供的一项用来限制及分离一组进程资源使用(CPU,内存,磁盘IO,网络等)的特性,从内核版本2.6.24开始支持。

cgroups中的基本概念如下:

  • 任务(task):系统中的线程
  • 控制组(cgroup):资源控制的最小单位
  • 子系统(subsystem):不同子系统代表不同类型的资源,如cpu子系统,memory子系统,目前支持的子系统如下:
    • cpu:基于时间片的CPU限制
    • cpuset:基于CPU核心的CPU限制
    • cpuact:生成CPU使用报告
    • memory:内存限制、内存使用报告
    • blkio:块设备输入输出限制,如磁盘IO
    • devices、freezer、net_cls、hugetlb、perf_event
  • 层级(hierachy):控制组的组织形式,关联了一个或多个subsystem的cgroups目录树

以上概念之间的关系可以通过一张图来概括:其中一个控制组关联了一组控制参数和线程pid,用于对特定线程组进行控制
cgroups组织结构

配置项

下面对storm中可能使用到的cgroups配置项进行介绍:

  1. 通用配置项

    • tasks & cgroup.procs:这两个参数的区别是,将一个线程pid加入tasks仅这个线程会受到相应控制组的控制,而将一个线程pid加入cgroup.procs,会将这个线程所属的线程组pid都加进来,这个线程组都会受到相应的控制组的控制
    • notify_on_release & release_agent:两个参数配合使用,可以指定当一个控制组中的tasks全部退出时是否(由notify_on_release控制)触发指定的操作(由release_agent指定)
  2. CPU子系统配置项:

    • cpu.cfs_period_us & cpu.cfs_quota_us:CPU使用时间绝对上限
    • cpu.stat:数据统计,nr_periods、nr_throttled、throttled_time
    • cpu.shares:CPU使用时间权重相对值

详细参考资料

对cgroup有兴趣的同学可以参考如下资料,概念和例子应有尽有,就不在赘述

  1. https://www.kernel.org/doc/Documentation/cgroups/
  2. https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/index.html
  3. http://coolshell.cn/articles/17049.html
  4. http://tiewei.github.io/devops/howto-use-cgroup/
  5. http://www.infoq.com/cn/articles/docker-kernel-knowledge-cgroups-resource-isolation

storm 0.9.x版本使用cgroup

0.9.x版本的storm并未提供cgroup的资源控制机制,因此需要使用外挂程序的方式(如定时执行脚本的方式)来对拓扑的资源使用进行限制, 以下为对每个worker的最大cpu使用时间进行限制的简单实现。

  • CPU守护:每台supervisor上执行crontab定时任务,将worker进程定时加入CPU控制组,限制worker进程最大CPU使用时间
1
2
3
4
5
6
7
8
9
10
控制组结构:
[liyan@xxxxx]$ lscgroup
cpu:/ # CPU根控制组
cpu:/weibo_storm # CPU根控制组下由脚本自动建立weibo_storm控制组
cpu:/weibo_storm/local-worker-pid-22341 # weibo_storm控制组下为每个worker进程自动建立一个控制组,限制相应的worker进程CPU资源
cpu:/weibo_storm/local-worker-pid-18547
cpu:/weibo_storm/local-worker-pid-12848
cpu:/weibo_storm/local-worker-pid-12063
cpu:/weibo_storm/local-worker-pid-9842
cpu:/weibo_storm/local-worker-pid-7559
  • cgroup清理:woker进程死掉后(一般由kill拓扑或者rebalance触发),自动清理无用的CPU控制组可以通过设置参数notify_on_release=1 & release_agent=/path/storm-cpu-cgroup-remove.sh来实现
  • 阈值报警:当cgroup到达最大限制值时,需报警通知业务人员进行干预。可以通过cpu.stat中的统计值来实现,如
1
alarm=(nr_throttled_t2-nr_throttled_t1)/(nr_periods_t2-nr_periods_t1)

脚本参考:
https://github.com/lostk1ng/storm-cgroups

storm 1.0.x版本使用cgroup

1.0.x版本的storm官方文档已经声称支持cgroups, 但是发现相关PR只merge到了master分支,并没有merge到1.0.x-branch,因此目前最新版本的storm仍然不支持cgroups。