cgropu实现系统资源隔离

以下是对NUMA和cgroup的初次实践分享,仅供参考。

    详细介绍请参考:https://access.redhat.com/site/documentation/zh-CN/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/

一、线上程序现象
    最近在不少os6.4的系统上发现机器负载较大,部分cpu使用率很高,但部分cpu使用率很低;物理内存很空闲,使用率很低,但swap使用了很多;某些程序因分配不到内存而报错等现象。更为严重我的发现有启动iptables都报错失败的情况,如下:
[[email protected] tmp]# /etc/init.d/iptables start
iptables: Applying firewall rules: iptables-restore: line 31 failed
[FAILED]
[[email protected] tmp]# tail /var/log/messages
Aug 14 00:21:19 abc kernel: Swap cache stats: add 386347, delete 385412, find 747707/754322
Aug 14 00:21:19 abc kernel: Free swap = 20167792kB
Aug 14 00:21:19 abc kernel: Total swap = 20971512kB
Aug 14 00:21:19 abc kernel: 4194303 pages RAM
Aug 14 00:21:19 abc kernel: 115322 pages reserved
Aug 14 00:21:19 abc kernel: 437874 pages shared
Aug 14 00:21:19 abc kernel: 3591085 pages non-shared
Aug 14 00:21:19 abc kernel: Unable to create nf_conn slab cache
Aug 14 00:21:20 abc modprobe: FATAL: Error inserting xt_state (/lib/modules/2.6.32-358.14.1.el6.x86_64/kernel/net/netfilter/xt_state.ko): Cannot allocate memory
Aug 14 00:21:47 abc kernel: nf_conntrack version 0.5.0 (16384 buckets, 65536 max)
[[email protected] tmp]# free -m
total used free shared buffers cached
Mem: 15933 15768 165 0 58 11429
-/+ buffers/cache: 4280 11652
Swap: 20479 784 19695

此时mem和swap都有空余,但还是Cannot allocate memory。经过查找资料这是NUMA导致的。

二、NUMA简单介绍
    NUMA是多核心CPU架构中的一种,其全称为Non-Uniform Memory Access(非同一内存),简单来说就是在多核心CPU中,机器的物理内存是分配给各个核的,每个核访问分配给自己的内存会比访问分配给其它核的内存要快;【 从系统架构来说,目前的主流企业服务器基本可以分为三类:SMP (Symmetric Multi Processing,对称多处理架构),NUMA (Non-Uniform Memory Access,非一致存储访问架构),和MPP (Massive Parallel Processing,海量并行处理架构)。三种架构各有特点,SMP架构:所有cpu以平等代价访问memory且共享系统总线,系统总线可能成为性能瓶颈且不易扩展;MPP架构:逻辑上划分为多个node且每个node上的cpu访问自己本地资源,扩展性好,node间数据交换难;NUMA架构介于前两者之间;详细介绍可以网上参考下】

查看是否支持numa及其numa信息:
[[email protected] tmp]# numactl --show
policy: default                    //当前numa策略为default
preferred node: current
physcpubind: 0 1 2 3 4 5 6 7
cpubind: 0 1
nodebind: 0 1
membind: 0 1                     //以上为可供绑定的cpu mem node等资源

[[email protected] tmp]# numactl --hardware
available: 2 nodes (0-1)          //表示有两个可用节点
node 0 cpus: 0 2 4 6
node 0 size: 8192 MB
node 0 free: 2904 MB               //节点0包含的cpu及其内存使用情况(本地资源情况)
node 1 cpus: 1 3 5 7
node 1 size: 8179 MB
node 1 free: 4220 MB               //节点1
node distances:
node   0   1
 0:  10  20
 1:  20  10                     //节点0访问节点0即本地资源的代价是10,节点0访问节点1的资源代价是20(访问本地资源比远程快)

在Linux上NUMA API支持四种内存分配策略:
    1. 缺省(default) - 总是在本地节点分配(分配在当前线程运行的节点上)
    2. 绑定(bind) - 分配到指定节点上
    3. 交织(interleave) - 在所有节点或者指定的节点上交织分配
    4. 优先(preferred) - 在指定节点上分配,失败则在其他节点上分配
绑定和优先的区别是,在指定节点上分配失败时(如无足够内存),绑定策略会报告分配失败,而优先策略会尝试在其他节点上进行分配。强制使用绑定有可能会导致前期的内存短缺,并引起大量换页。缺省的策略是更加普适的优先策略。

三、使用cgroup软件对资源进行分配控制与隔离
Cgroups是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组(process groups)所使用的物理资源(如:cpu,memory,IO等等);

1、安装
yum install libcgroup -y

2、配置
cat > /etc/cgconfig.conf <<END
mount {
   cpuset  = /cgroup/cpu_and_mem;          
   memory  = /cgroup/cpu_and_mem;           //cpuset memory资源子系统挂载路径
}

group chunk_server {                                   //控制族群chunk_server,可包括lssubsys -a查看到的一些系统支持的子系统
cpuset {
        cpuset.cpus = "0,2,4,6";                     //cpu使用第0,2,4,6,属于同一node
        cpuset.mems="0";                             //node 0的memory资源
     }
memory {
        memory.limit_in_bytes=4G;                //memory限制大小为4G
        memory.memsw.limit_in_bytes=4G;      //限制mem+swap的大小为4G
        memory.swappiness=0;                     //积极使用物理内存(同vm.swappiness)
       }
}

group other {
cpuset {
        cpuset.cpus = "1,3,5,7";
        cpuset.mems="1";
     }
memory {
        memory.limit_in_bytes=8G;
        memory.memsw.limit_in_bytes=8G;
        memory.swappiness=0;
       }
}

END

memory.limit_in_bytes     内存;

memory.memsw.limit_in_bytes     内存与swap的和(大于memory.limit_in_bytes);

cgconfigparser -l /etc/cgconfig.conf     测试配置是否正确;

3、启动
/etc/init.d/cgconfig restart

4、任务使用
killall -9 chunk_server
cgexec -g memory,cpuset:chunk_server /usr/local/gfs/bin/gfs_chunk_server_daemon.sh

killall -9 vip_cdn
cgexec -g memory,cpuset:other /usr/local/vip_cdn/bin/monitor.sh

以上步骤的2跟4操作方法我觉得比较适用,当然也可以使用命令对资源进行挂载、分配、使用,如:cgcreate/cgget /cgset /cgdelete/cgclear/cgclassify等;

5、某些命令
[[email protected] tmp]# lssubsys -am               //查看当前支持的子系统及其挂载情况
ns
cpu
cpuacct
devices
freezer
net_cls
blkio
perf_event
net_prio
cpuset,memory /cgroup/cpu_and_mem

[[email protected] tmp]# lscgroup                //查看当前cgroup层次结构
cpuset,memory:/
cpuset,memory:/other
cpuset,memory:/chunk_server

[[email protected] tmp]# wc -l /cgroup/cpu_and_mem/chunk_server/tasks
31 /cgroup/cpu_and_mem/chunk_server/tasks
[[email protected] tmp]# wc -l /cgroup/cpu_and_mem/other/tasks          
243 /cgroup/cpu_and_mem/other/tasks
//当前这两个资源group中的任务数,tasks中记录的是进程id(也可以手动加入某进程id到tasks文件中,则该进程及其子进程将受到该group控制)

[[email protected] tmp]# cat /proc/`pidof chunk_server`/cgroup

2:memory,cpuset:/chunk_server         //查看chunk_server程序所在group信息(此处表示层次为2,资源为memory和cpuset,group为/chunk_server)

[[email protected] tmp]# numastat                         //numa的访问统计(numa未关闭时)

node0           node1

numa_hit            124707339647     29192299625

numa_miss            13468643333      2043118290

numa_foreign          2043118290     13468643333

interleave_hit             10961           10991

local_node          124707158180     29191808808

other_node           13468824800      2043609107

[[email protected] tmp]# numastat                 //numa的访问统计(numa关闭时)

node0

numa_hit              1201229534

numa_miss                      0

numa_foreign                   0

interleave_hit             21915

local_node            1201229534

other_node                     0

6、自动配置及使用cgroup
上面的1-4是简单的安装以及使用cgroup来控制资源分配到程序,如果是批量部署,让程序启动的时候自动加入group,而不是手动cgexec呢,可以使用cgred服务配合cgroup自动控制程序及其子进程,下面是针对目前线上大多数机器的部署脚本:
cat cgroup.sh
#!/bin/bash
# bigy @ 20130916

#检查节点node个数
nodes=`/usr/bin/numactl --hardware |awk ‘/available/{print $2}‘`
if [ $nodes -lt 2 ];then
   echo "available nodes is $node,not support"
   exit 1
fi

#获取节点
node0=`/usr/bin/numactl --hardware |awk -F: ‘/node 0 cpus/{print $2}‘ |awk ‘{print $1","$2","$3","$4}‘`
node1=`/usr/bin/numactl --hardware |awk -F: ‘/node 1 cpus/{print $2}‘ |awk ‘{print $1","$2","$3","$4}‘`

#若机器numa架构,则检查并cgroup
rpm -qa |grep -q libcgroup || yum install libcgroup -y || (echo "yum install libcgroup error" && exit 1 )

#=====update /etc/cgconfig.conf =====
cat > /etc/cgconfig.conf <<END
mount {
   cpuset  = /cgroup/cpu_and_mem;
   memory  = /cgroup/cpu_and_mem;
}

group chunk_server {
cpuset {
        cpuset.cpus = "$node0";
        cpuset.mems="0";
     }
memory {
        memory.limit_in_bytes=4G;
        memory.memsw.limit_in_bytes=4G;
        memory.swappiness=0;
       }
}

group other {
cpuset {
        cpuset.cpus = "$node1";
        cpuset.mems="1";
     }
memory {
        memory.limit_in_bytes=8G;
        memory.memsw.limit_in_bytes=8G;
        memory.swappiness=0;
       }
}
END

#=====update /etc/cgrules.conf =====

#格式为:        用户:程序     子系统     逻辑挂载点

#程序:可以为程序名称、程序全路径(程序须全路径运行),或者程序的启动脚本
#挂载点:lscgroup命令查看

cat > /etc/cgrules.conf <<END
*:/usr/local/gfs/bin/chunk_server                       cpuset,memory /chunk_server
*:/usr/local/vip_cdn/bin/monitor.sh                     cpuset,memory /other
END

#===== start cgconfig and cgred =====
/etc/init.d/cgconfig restart
/sbin/chkconfig cgconfig on

/etc/init.d/cgred restart
/sbin/chkconfig cgred on

echo "===== install cgroup done! ====="

#重启程序,让其自动加入group中
echo "===== kill processes for restart ====="
killall -9 chunk_server
/usr/local/gfs/bin/gfs_chunk_server_daemon.sh
killall -9 vip_cdn
/usr/local/vip_cdn/bin/monitor.sh

说明:
*:/usr/local/gfs/bin/chunk_server       cpuset,memory /chunk_server
或者*:chunk_server       cpuset,memory /chunk_server
程序启动必须是全路径启动,否则匹配不到;
*:/usr/local/vip_cdn/bin/monitor.sh     cpuset,memory /other
由于http_down启动后是./vip_cdn,不是全路径运行,所以不能像chunk_server一样直接写chunk_server;可以写全路径的监控脚本。

7、关闭numa
    当系统跑的程序比较多而且资源使用不易控制的时候,可以考虑把numa关闭。对部分机器做了不同的测试,关闭numa的效果稍微好点,目前已经全部在os内核关闭。
关闭方法:
1.硬件层,在BIOS中设置关闭;
2.OS内核,启动时kernel后添加参数numa=off;
3.可以用numactl命令将内存分配策略修改为interleave(交叉)。

ps:

由于线上机器业务比较复杂,只是大概的分了两个组来隔离,保证最重要的服务能正常而不受影响即可。我们线上机器部署的复杂性,numa基本关闭也很少使用cgroup做资源隔离。但有个机房比较特殊几台24核64Gmem万兆网卡机器当作一个节点,这样每个机器上面的程序就更多了,这时使用cgroup对各个程序做了资源隔离,效果很好,由于程序性能问题,目前这几台机器只跑了大概15G带宽的样子。

cgropu实现系统资源隔离

时间: 2024-08-07 00:18:51

cgropu实现系统资源隔离的相关文章

为什么浏览器采用多进程模型

为什么浏览器采用多进程模型 这个问题的答案似乎是非常清楚的,可以概括为:为了安全.稳定.性能,只是要牺牲点内存作为代价.对于安全和稳定,利用系统的进程机制就可以完成.但是多进程下的进程间通讯(IPC)很慢,而分为多进程后,一些协作任务就要分开到两个进程,如何能保持良好的性能,更不说比单进程模型更高的性能了? 所以这里再次探讨浏览器选择多进程架构的原因,以及对应架构中的要点. 多进程 vs. 多线程 先了解一下背景.将工作并行处理,是提高性能的手段.这个工作涉及到硬件,操作系统和应用程序.我不性硬

Linux Namespaces机制

Linux Namespaces机制提供一种资源隔离方案.PID,IPC,Network等系统资源不再是全局性的,而是属于特定的Namespace.每个Namespace里面的资源对其他Namespace都是透明的.要创建新的Namespace,只需要在调用clone时指定相应的flag.Linux Namespaces机制为实现基于容器的虚拟化技术提供了很好的基础,LXC(Linux containers)就是利用这一特性实现了资源的隔离.不同container内的进程属于不同的Namespa

互联网技术架构给我们的启示

可以理解为自白书,知道自己太落后啦~ --中国建设银行信息技术管理部副总经理 王申科 据阿里官方公布的数据,2013年"双11"这一天,天猫.淘宝成交额共计350.19亿元,相当于10月全国日均消费额的一半,较去年的191亿元增长83%.支付宝交总交易笔数达到1.88亿笔,其中无线支付达到4518万笔,分别是去年同一天的1.77倍和5倍. 参照央行发布的2013年第二季度支付体系运行数据,二季度全国银行卡消费业务笔数约为30.6亿笔,平均每天约3400万笔,那么支付宝"双11

Cloud 2.0时代的华为云,让产业互联网跨越新摩尔定律

根据中国信通院的<互联网发展趋势报告2017-2018>:互联网已成为全球经济增长主要驱动力,中国互联网产业也正处于新的历史拐点.从互联网发展周期看,移动互联网浪潮已消退,全面进入稳定增长阶段,业务生态持续创新拓展,"智能"与"融合"演化为新时期互联网发展核心特征,全球互联网正加速迈入智能融合新时代. 所谓"智能"与"融合",更多是指云与互联网结合在一起,针对实体经济和行业应用,满足真实世界中企业.组织和个人的真实

利用内核cgroup机制轻松实现类似docker的系统资源管控

近几年,以docker为代表的容器技术异常火热,它的轻量.高效让人欣喜若狂,它被赋予了改变传统IT运维的使命.相信随着时间推移,以容器云为落地形式的产品将真正实现这一使命. 我们都知道docker能够实现资源的隔离和控制,正当打算引入docker来管理产品不同业务的资源占用时,发现它的隔离性是我们所不需要的,而我们都知道,docker底层实际上是利用了linux内核提供的namespace和cgroup机制,而前者是用于资源隔离的,后者是用于资源控制的.这时,我们想到了直接用cgroup来实现.

cgroup隔离的知识点

tasks中写入的是线程号 cgroup.procs是进程号 ===================CPU隔离===================== 主机CPU核数: cat /proc/cpuinfo  | grep -w processor | wc -l  32 一个实例最大可以占有的核数: 10 cpu百分比 10/32 = 0.3125 # cfs_period_us  = 定值 # cfs_quota_us = cfs_period_us * 所占的核数 # cpu shares

Atitit.数据库事务隔离级别 attilax 总结

Atitit.数据库事务隔离级别 1. 事务隔离级别的作用 1 2. 在的隔离级别 2 3. 常见数据库的默认管理级别 3 1. 事务隔离级别的作用 较低的隔离级别可以增强许多用户同时访问数据的能力,但也增加了用户可能遇到的并发副作用(例如脏读或丢失更新)的数量.相反,较高的隔离级别减少了用户 可能遇到的并发副作用的类型,但需要更多的系统资源,并增加了一个事务阻塞其他事务的可能性.应平衡应用程序的数据完整性要求与每个隔离级别的开销,在此 基础上选择相应的隔离级别.最高隔离级别(可序列化)保证事务

程序员必知的六种隔离技术

为了将我们的应用部署到服务器上,我们需要为其配置一个运行环境.从底层到顶层有这样的运行环境及容器: 隔离硬件:虚拟机 隔离操作系统:容器虚拟化 隔离底层:Servlet容器 隔离依赖版本:虚拟环境 隔离运行环境:语言虚拟机 隔离语言:DSL 实现上这是一个请求的处理过程,一个HTTP请求会先到达你的主机.如果你的主机上运行着多个虚拟机实例,那么请求就会来到这个虚拟机上.又或者是如果你是在Docker这一类容器里运行你的程序的话,那么也会先到达Docker.随后这个请求就会交由HTTP服务器来处理

理解Docker(3):Docker 使用 Linux namespace 隔离容器的运行环境

1. 基础知识:Linux namespace 的概念 Linux 内核从版本 2.4.19 开始陆续引入了 namespace 的概念.其目的是将某个特定的全局系统资源(global system resource)通过抽象方法使得namespace 中的进程看起来拥有它们自己的隔离的全局系统资源实例(The purpose of each namespace is to wrap a particular global system resource in an abstraction th