资源限制

在Linux 系统中,有一个非常古老的资源限制功能——limits

RH442 - 性能调优学习笔记(四)_资源限制

在系统中,有一个模块叫做limits.so,这个模块有一个配置文件:

vim /etc/security/limits.conf

这个模块也是PAM 认证模块里面的一个机制。

如果你早期有安装过类似于oracle 这种大型数据库,通常会接触到limits 这个功能,它能帮助你限制一个用户最多打开多少个文件、最多使用多大的磁盘空间、最多打开多少进程、最多使用多少内存...等等,不过这个功能已经属于非常古老的一种资源限制方式了,大概在红帽3、红帽4 的时代就已经实现了,不过在今天进行一些简单的设置依然还是可行有效的。

RH442 - 性能调优学习笔记(四)_资源限制_02

这里面有介绍到该文件做资源限制的写法。

下面我们来新建一个用户:

useradd user1

然后在配置文件中写入这么一行:

RH442 - 性能调优学习笔记(四)_资源限制_03

nofile 表示限制的资源类型是打开的文件数,最多只能打开4 个文件。

RH442 - 性能调优学习笔记(四)_资源限制_04

结果连登录都报错,因为用户登录的时候已经不止要打开4 个文件了。

RH442 - 性能调优学习笔记(四)_资源限制_05

限制user1 最多打开40 个文件,最多使用10M 的虚拟内存。

RH442 - 性能调优学习笔记(四)_资源限制_06

同样无法登录,分配不到内存去读取一些必要的文件导致的。

改为限制分配100M 虚拟内存,登录成功了

RH442 - 性能调优学习笔记(四)_资源限制_07

所以limits.conf 修改完成以后,无需重启什么服务,只需要让用户重新登录一遍,限制就生效了。

那么如果用户登录以后,想要查看系统对它有哪些限制,使用:

ulimit -a

RH442 - 性能调优学习笔记(四)_资源限制_08

ulimit -n
ulimit -v

RH442 - 性能调优学习笔记(四)_资源限制_09

那么,软限制与硬限制有什么区别呢?

RH442 - 性能调优学习笔记(四)_资源限制_10

RH442 - 性能调优学习笔记(四)_资源限制_11

现在最多能打开30 个文件。

ulimit -n 35

RH442 - 性能调优学习笔记(四)_资源限制_12

现在设置了最多可以打开35 个文件。

RH442 - 性能调优学习笔记(四)_资源限制_13

如果你要打开45 个文件,不可以。

所以,超出软限制,用户可以进行微调,但还是不能超过硬限制。

从RHEL 6.2 开始,引入了一个新的功能——cgroup

RH442 - 性能调优学习笔记(四)_资源限制_14

cgroup 已经成为了现在的主流。

今天很多的虚拟机,容器背后用来资源限制的功能用的就是cgroup

docker 容器其中两个核心技术,一个是namespace(命名空间),用来做资源隔离,另一个就是cgroup,用来做资源限制。

RH442 - 性能调优学习笔记(四)_资源限制_15

cgroup 从RHEL 6 开始,在RHEL 7 上又经历了迭代,下面来演示当年在RHEL 6 上是怎么做的:

RH442 - 性能调优学习笔记(四)_资源限制_16

这个包在RHEL 7 上是默认安装的,RHEL 6 可能要手动安装。

RH442 - 性能调优学习笔记(四)_资源限制_17

那么,像/proc、/sys 这样的目录,系统中也有一个/cgroup 的文件系统

cd /cgroup/blkio

RH442 - 性能调优学习笔记(四)_资源限制_18

RH442 - 性能调优学习笔记(四)_资源限制_19

这里面有很多的调优选项。

vim /etc/cgconfig.conf

RH442 - 性能调优学习笔记(四)_资源限制_20

如果你要做资源限制,那么这一段有相应的配置文件。

假如说在RHEL 6 系统中现在有一个需求:

要求执行读写操作时,限速读写1MB/s,如何做?

你可以:

man cgconfig.conf

模仿示例来写:

vim /etc/cgconfig.conf

RH442 - 性能调优学习笔记(四)_资源限制_21

这是一个全局配置,第一个名称bigdata 可以自定义, 第二个名称是你要针对什么资源做限制,必须与调优参数对应。

重启一下服务:

/etc/init.d/cgconfig restart

RH442 - 性能调优学习笔记(四)_资源限制_22

cd /cgroup/blkio/bigdata/
cat blkio.throttle.read_bps_device

RH442 - 性能调优学习笔记(四)_资源限制_23

接下来将这个全局配置应用到具体某一个用户执行某一个动作上:

vim /etc/cgrules.conf

RH442 - 性能调优学习笔记(四)_资源限制_24

这表示:任何用户执行cp 这个命令的时候,会受到全局配置bigdata 里面的blkio 规则的限制。

/etc/init.d/cgconfig restart

RH442 - 性能调优学习笔记(四)_资源限制_25

现在来测试一下是不是这样的:

RH442 - 性能调优学习笔记(四)_资源限制_26

/etc 目录36M大小,新开一个窗口,观察:

rm -rf /tmp/*
watch -n 1 -x du -sh /tmp

回到原来的窗口,拷贝文件:

cp /etc/ /tmp/

RH442 - 性能调优学习笔记(四)_资源限制_27

会发现这个文件夹的大小几乎是一兆一兆在增长的,说明限制生效了。

bigmem 是一个专门用来做内存测试的工具,不是系统自带的,先来看一下当前这台机器的内存使用情况:

RH442 - 性能调优学习笔记(四)_资源限制_28

现在我要申请512M 内存:

RH442 - 性能调优学习笔记(四)_资源限制_29

申请到了。

RH442 - 性能调优学习笔记(四)_资源限制_30

现在来做资源限制,限制bigmem 可以申请到的内存最多为256M

cd /cgroup/memory

RH442 - 性能调优学习笔记(四)_资源限制_31

内存限制应该是操作这个参数。

vim /etc/cgconfig.conf

RH442 - 性能调优学习笔记(四)_资源限制_32

一个组里面可以有多个选项,也可以单独再写到一个组里面。

vim /etc/cgrules.conf

RH442 - 性能调优学习笔记(四)_资源限制_33

/etc/init.d/cgconfig restart

RH442 - 性能调优学习笔记(四)_资源限制_34

/etc/init.d/cgred restart

RH442 - 性能调优学习笔记(四)_资源限制_35

下面测试一下:

新开一个窗口观察

watch -n 1 -x free -m

RH442 - 性能调优学习笔记(四)_资源限制_36

RH442 - 性能调优学习笔记(四)_资源限制_37

RH442 - 性能调优学习笔记(四)_资源限制_38

RH442 - 性能调优学习笔记(四)_资源限制_39

内存限制生效了。

在RHEL 5、RHEL 6 时代,系统服务是怎么管理的呢?

比如说重启vsftpd 服务:

RH442 - 性能调优学习笔记(四)_资源限制_40

这条命令本质上是执行了下面这条命令:

RH442 - 性能调优学习笔记(四)_资源限制_41

/etc/init.d/vsftpd 这个文件其实是一个脚本。

vim /etc/init.d/vsftpd

RH442 - 性能调优学习笔记(四)_资源限制_42

RH442 - 性能调优学习笔记(四)_资源限制_43

RH442 - 性能调优学习笔记(四)_资源限制_44

在当时,你想要管理一个服务,就需要写一个这样的脚本放在/etc/init.d 目录,用来控制服务的启动、停止、重启等等...

从RHEL 7 开始,服务由systemd 管理,重启一个服务用这样的命令来执行:

RH442 - 性能调优学习笔记(四)_资源限制_45

当然它也支持使用以前的语法:

RH442 - 性能调优学习笔记(四)_资源限制_46

实际上还是调用的systemd 服务。

cd /usr/lib/systemd/system

RH442 - 性能调优学习笔记(四)_资源限制_47

这里面有很多的服务,其中就有一个是叫vsftpd.service,所以当你启服务的时候,会读到这个脚本。

vim vsftpd.service

RH442 - 性能调优学习笔记(四)_资源限制_48

Description 是对这个服务的描述,After 表示这个服务在network.target 服务启动后运行,type 是这个服务的类型,ExecStart 表示这个服务启动时执行的脚本,其实你启服务的时候,本质上就是在执行下面这条命令:

RH442 - 性能调优学习笔记(四)_资源限制_49

RH442 - 性能调优学习笔记(四)_资源限制_50

WanteBy=multi-user.target 表示在多用户模式(级别3)运行。

所以使用systemd 来管理服务相比于RHEL 6及以前的版本,大大简化了服务脚本编写的难度。

下面我们自己来写一个服务:

vim realtime

RH442 - 性能调优学习笔记(四)_资源限制_51

RH442 - 性能调优学习笔记(四)_资源限制_52

RH442 - 性能调优学习笔记(四)_资源限制_53

这个脚本会持续运行。

cd /usr/lib/systemd/system
cp -p vsftpd.service realtime.service
vim realtime.service

RH442 - 性能调优学习笔记(四)_资源限制_54

systemctl daemon-reload
systemctl enable --now realtime.service
systemctl status realtime.service

RH442 - 性能调优学习笔记(四)_资源限制_55

ps aux | grep realtime

RH442 - 性能调优学习笔记(四)_资源限制_56


如果我想限制一些吃内存的应用,怎么通过systemd 的方式来管理呢?

man -k systemd |grep resource

RH442 - 性能调优学习笔记(四)_资源限制_57

man 5 systemd.resource-control

RH442 - 性能调优学习笔记(四)_资源限制_58

可以对CPU、内存、IO 资源做限制。

RH442 - 性能调优学习笔记(四)_资源限制_59

就CPU 而言,可以对CPUAccounting,权重、配额等等做限制。

我们可以直接写/usr/lib/systemd/system/realtime.service 文件来控制,但是不建议直接改这个文件,推荐下面的做法:

cd /etc/systemd/system/
mkdir realtime.service.d
cd realtime.service.d/

在这个文件夹下新建一个配置文件,名称无所谓,但必须以.conf 结尾:

vim 01-time.conf

但是这个文件里面该写些什么内容呢?可以参照其他服务来写:

RH442 - 性能调优学习笔记(四)_资源限制_60

systemctl daemon-reload
systemctl restart realtime.service
systemctl status realtime.service

RH442 - 性能调优学习笔记(四)_资源限制_61

除此以外,怎么验证是否生效呢?

df -h

RH442 - 性能调优学习笔记(四)_资源限制_62

在RHEL 7 以前,这个目录是在根下的/cgroup,现在是在/sys/fs/cgroup

cd /sys/fs/cgroup
cd memory

RH442 - 性能调优学习笔记(四)_资源限制_63

cd /system.slice
cd realtime.service

RH442 - 性能调优学习笔记(四)_资源限制_64

RH442 - 性能调优学习笔记(四)_资源限制_65

上一级目录里是全局配置,里面一级是单独配置的。

RH442 - 性能调优学习笔记(四)_资源限制_66

这两个进程会受到单独配置的影响,其他进程则是受全局配置的影响。

RH442 - 性能调优学习笔记(四)_资源限制_67

cd /sys/cgroup/memory/system.slice/realtime.service
cat memory.limit_in_bytes

RH442 - 性能调优学习笔记(四)_资源限制_68

RH442 - 性能调优学习笔记(四)_资源限制_69

这里看到系统把内存的一半容量分配给了/sys/fs/cgroup

cd /sys/fs/cgroup/memory/
cat tasks

RH442 - 性能调优学习笔记(四)_资源限制_70

这里面显示的都是PID,如果没有单独限制,那么读取的就是全局的配置。

RH442 - 性能调优学习笔记(四)_资源限制_71

如果没有单独做限制,那么默认的这个全局配置,是7EB,几乎等同于无上限。


持续更新中...