一个资源管理系统的设计--基于cgroup机制
受控进程:ssh,sshd,httpd...
控制元素:cpu占用率,内存总量,磁盘使用...
管理组:组1,组2,组3
控制粒度:基于进程和控制元素,也就是说管理组(组x)不必控制控制元素中的所有元素,只需要控制其中一个或者几个即可,当然也可以是全部。
有了以上假设,那么几种对应关系就很显然了,指出这些对应关系之前首先定义几种角色:
主体:受控进程
客体:控制元素
管理者:管理组
总体描述:主体在管理者的管理下对客体产生动作。
以上这些都是最最基本的元素了,我认为不能比这更简单了,因此我认为它是完美的,理解了角色和总的描述,它们的关系如下:
受控进程->控制元素:这是个一对多的关系,一个进程可以接受多种元素的控制
控制元素->受控进程:这是个一对多的关系,一个控制元素可以控制多个进程
受控进程<=>控制元素:因此这是个多对多的关系
控制元素->管理组:这是个一对一的关系,即某个进程的一个受控元素只能由一个管理组控制
管理组->控制元素:这是个一对多的关系,即一个管理组可以管理一组进程的多个控制元素
管理组<=>受控进程:这是个多对多的关系,即一个管理组可以可以控制多个进程,反过来一个进程的不同控制元素也能被多个管理组控制。
有了以上的关系,我想任何关系数据库的高手都能设计出表结构来的,甚至都不需要是高手,只要会一些数据库的知识应该就不成问题,这个关系结构很显然,表结构也很简单可是在不允许查询数据库或者没有数据库环境的情况下,如何实现这个方案呢?比如在一个嵌入式的小内存的设备上,如何仅仅通过c语言或者别的轻量级语言编程实现它呢?要知道数据库的查询操作实际上仅仅给外部提供一个接口,而其实现是由查询引擎完成的,在这个意义上,我们要实现的就是一个小型的查询引擎了,因此首先我们需要先设计一下数据结构,最基本的就是主体,客体,管理者的设计了:
主体:
struct task {
void *other;
List *targets;
}Task;
客体:
struct target {
void *other;
List *tasks;
Manager *man;
}Target;
管理者
struct manager {
void *other;
List *targets;
}Manager;
以上是最初步的设计,已经展现了对应关系,但是无法索引当前的客体,因此有必要将所有的客体组织成数组的形式:
Target ts[] = {cpu,memory,file,...};
主体重新设计为:
struct task {
void *other;
Target targets[N];
}Task;
但是这样的话,每一个Target的结构体中除了tasks字段之外的数据将会重复,这就浪费了内存,因此有必要将task和target进行解除耦合,于是设计一个中间结构,用于拼接这两个结构:
struct middle {
List *tasks; //所有的使用这个middle的task链表
Target targets[N]; //以上tasks这些进程的N控制元素
}Mid;
struct task {
void *other;
Mid *mid;
}Task;
struct target {
void *other;
Manager *man;
}Target;
这样,所有的被同一些控制元素控制的task就可以共享一个target了,从而节省了内存。由于task和target是多对多的关系,因此使用了一个middle来解除其耦合,达到了共享一方的效果,同样的道理,task和manager的关系也是多对多的关系,于是同样的措施必然带来同样的效果。于是重新设计:
struct manager {
void *other;
List *targets;
}Manager;
struct middle2 {
List *tasks; //所有的被这个管理者管理的task链表
List *managers; //一个task属于的所有的管理者
}Mid2;
struct task {
void *other;
Mid *mid;
Mid2 *mid2;
}Task;
仔细一想,这样不妥,原因有二,第一个原因是一个task虽然属于很多manager,但是它是基于target的,这个信息没有体现出来,第二,信息冗余,这样在修改或者同步起来非常不便,于是必然要重新设计,由于manager和target的联系已经建立了,然而这个关系是单向的,数据查询因此也只能是单向的,我们能通过一个task得到它归于哪些manager,却无法反过来从一个manager得到它都控制了哪些task,由于管理者基于一组target来分组,因此所有这些task拥有共同的有效target[N],因此必然需要建立一个反向的关系,首先在Manager中建立一个新的List字段:
struct manager {
void *other;
List *targets;
List *tasks;
}Manager;
从基于target组进行管理的前提并且task和target已经通过middle联系得知,这个manager需要和middle用类似middile的结构体进行联系,姑且将该结构体设为middle2,这个middle2对于manager来说,它代表一个middle,也就是一组task以及对应的一组target,这个middle2对于一个middle来说,它代表一个manager,为了表现manager和middle是对对多的关系,middle2的设计和middle的设计几乎一样:
struct middle2 {
List *manager; //对于一个middle来说,该链表包含所有的targets数组的manger字段的并集,当然由于一个middle对应N个target,具体哪个target对应哪个manager,需要查阅middle的targets数组来一一确定。
List *mids; //对于一个manager来说,该链表包含它所参与管理的所有的middle
Mid *mid; //一个mid2唯一对应一个mid。这是基于targets集合意义的,而不是基于单独的target的
}Mid2;
最终的设计如下:
struct middle {
List *tasks; //所有的使用这个middle的task链表
Target targets[N]; //这里使用数组而没有使用List完全是为了代码的简洁,可以直接通过enum枚举名来直接访问
}Mid;
struct middle {
List *tasks;
List *mid2; //由于下面的N个target并不一定属于一个manager,因此一个middle可能也属于多个manager,这个关系通过mid2来耦合。
Target targets[N];
}Mid;
struct middle2 {
List *manager;
List *mids;
Mid *mid;
}Mid2;
struct task {
void *other;
Mid *mid;
}Task;
struct target {
void *other;
Manager *man;
}Target;
struct manager {
void *other;
List *targets;
List *mid2;
}Manager;
这么一个设计基本就完美了,我们试一下几个查询。首先,从一个task查询一下它的各个控制元素都受哪个管理者的控制,这个很简单,从task取出mid字段,然后遍历整个targets数组,从每一个元素中取出manager字段即可;接下来根据一个manager查询一下它都控制了哪些进程,取出manager的mid2字段,遍历其中的每一个middle2元素,对于每一个middle2,取出其mid字段,然后遍历其task字段,取出所有的task即可。着重需要说明的是middle2结构,它具有两重身份,mids是作为单独的target起作用的,毕竟一个middle结构体拥有不同的target,这些target不一定有相同的manager的,而mid字段是作为一组targets起作用的,换句话说,它针对的是一个middle而不是middle中单独的target。
本设计可以使用数据库,但是却没有使用数据库,因为本设计的精髓在于设计的实现而不是关系模型,可以看出,linux内核在设计数据结构的时候和本文的方式有些类似,实际情况是:本文就是参考linux内核的cgroups做出来的,因此我才敢说它很完美(尽管linux内核并不总是很完美)!看完了本文,再去理解linux内核代码中关于cgroups的复杂代码,我相信就清晰多了。在此给出一些对应:
task--task_struct
target--cgroup_subsys_state
manager--cgroup
middle--css_set
middle2--cg_cgroup_link
其中在find_existing_css_set函数中有下面的判断:
if (root->subsys_bits & (1UL << i))
这说明,虽然你建立了一个新的cgroup,然后这个cgroup中具体哪些subsys起作用,所依据的是你mount cgroup时的-o参数,因此虽然将一个进程放入了一个cgroup,如果这个cgroup在mount的时候没有memory参数而只有cpu参数的话,该进程的内存使用情况还将受原先cgroup的限制而不受这个新的cgroup的限制。另外需要注意的是,linux内核的cgroup使用了OO的思想,cgroup_subsys_state并不提供任何信息,如果你想提供一些信息,比如想提供内存使用方面的限制,那么建立一个结构体,让cgroup_subsys_state作为第一个元素(或者第n个元素),这样cgroup_subsys_state就是一个根类对象,让所有其它的具体类继承它即可:
struct memctrl {
cgroup_subsys_state cst;
...//其它的具体字段
};
然后用container_of取出具体的结构即可!
本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1271178
一个资源管理系统的设计--基于cgroup机制相关推荐
- java做一个客房管理系统定制_基于JAVA酒店客房管理系统的设计与实现(JSP,MySQL)(含录像)...
基于JAVA酒店客房管理系统的设计与实现(JSP,MySQL)(含录像)(毕业论文12000字,程序代码,MySQL数据库) 本酒店管理系统在功能模块主要分为两大方面,即用户功能模块和管理员功能模块. ...
- 一个缺陷管理系统数据库设计和界面设计分析
在Winform方面,基于业务的不同,我们可以利用工具的效率,快速做很多不同的业务系统,前期做了一个缺陷管理系统,想把单位的测试业务规范下,也好统计和分析每个版本的缺陷信息,本篇整理这些数据库设计和界 ...
- 怎么用Android做一个信息管理系统,从零开始设计一个管理系统
本文将以介绍一个管理系统设计实现为例,让您了解管理Excel, 并可以使用管理Excel设计出契合实际需求的管理系统. 本次设计目标是设计一个基本的采购销售管理系统: 1.采购管理 2.销售管理 3. ...
- (附源码)基于SpringBoot的在线学生请假管理系统的设计与实现 毕业设计060935
Springboot在线学生请假管理系统 摘要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们 ...
- (附源码)ssm+mysql+基于微信平台的牙科就诊信息管理系统的设计与实现 毕业设计211157
小程序SSM牙科就诊信息管理系统. 摘 要 随着现在网络的快速发展,网络的应用在各行各业当中它很快融入到了许多分类管理之中,他们利用网络来做这个牙科就诊信息管理系统.,随之就产生了"牙科就诊 ...
- ssm+mysql+基于微信平台的牙科就诊信息管理系统的设计与实现 毕业设计-附源码211157
小程序SSM牙科就诊信息管理系统. 摘 要 随着现在网络的快速发展,网络的应用在各行各业当中它很快融入到了许多分类管理之中,他们利用网络来做这个牙科就诊信息管理系统.,随之就产生了"牙科就诊 ...
- 基于SpringBoot的在线学生请假管理系统的设计与实现 毕业设计-附源码060935
Springboot在线学生请假管理系统 摘要 21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们 ...
- 基于SpringBoot的城市建设用地管理系统的设计与实现
作者主页:Designer 小郑 作者简介:Java全栈软件工程师一枚,来自浙江宁波,负责开发管理公司OA项目,专注软件前后端开发(Vue.SpringBoot和微信小程序).系统定制.远程技术指导. ...
- 基于SSM技术的oa办公管理系统的设计与实现毕业设计源码100934
oa办公室管理系统 摘 要 一个企业实现办公自动化的程度是衡量其实现现代化管理的标准.办公自动化(OA: OFFICE AUTOMATION)就是采用Internet技术,基于工作流的概念,使企业内部 ...
最新文章
- SAP HUMO VLMOVE不支持E库存发货到成本中心
- WEB+windows集群
- SQLServer异常捕获
- java输入星期几的字母_输入字母判断星期几java编程答案
- 分布式消息规范 OpenMessaging 1.0.0-preview 发布
- Django makemigration No changes detected
- 马拉松教会我_社区教会了我关于开放组织的知识
- php5.6 mysql nginx_nginx1.10.3+php5.6+mysql5.7.0
- 云原生的本质_云原生2.0的逻辑之辩,如何让每个企业都成为新云原生企业
- Linux应用总结:自动删除n天前日志
- VS2013 update4+Cocos2d-x 3.7 Win8下安装方法及配置
- 从文本中提取单词生成单词本
- matlab 中的textscan
- 人文视野中的生态学题库
- 第三章-2 MSF扫描漏洞模块
- Swift游戏实战-跑酷熊猫 02 创建熊猫类
- Spring AOP 之 Introductions
- 微命令、微操作、微指令、微程序
- 算法设计与分析课程复习笔记11——单源最短路径
- Linux磁盘分区以及多重引导简述
热门文章
- 安装linux可是c盘文件夹失败,硬盘安装linux失败,进不去以前的windows怎么处理?
- linux 大量文件 ls卡死,Linux下文件过多导致 ls 命令出现 arguments too long 的问题
- 跨年照片墙php源码,简单效果照片墙
- 字符变量赋值规则_第四章 变量
- Android的ListFragment和Fragment的使用
- 2011版计算机网络原理,2011年7月自考04741计算机网络原理真题及答案
- 20200723:198周周赛学习记录
- 2019 live tex 发行版_TeX Live 2019安装指南
- keil5函数 默认返回值_Excel等级判定,除了If函数外,还有5个易学易用易懂的技巧需要掌握!...
- uinput 用法 android 上层使用uinput 的用法来模拟 input 事件