0. 引言
在同一套物理主机环境中,如果部署多套数据库软件,常常面临资源隔离/限制需求,按照Linux
用户来隔离资源是一种常见的解决方案。然而,我们发现网上搜索到的资料绝大部分过于陈旧,仅适用于Redhat/CentOS Linux 7
等比较旧的操作系统,当我们在Redhat/CentOS Linux 8
系统上部署时,方法根本不可用。本文试图探索其中的原因,给出多种解决方法。虽然本文以SeaboxSQL
数据库为例探讨多套应用程序的资源隔离问题,但是,其方法是普适性的。方法在Redhat 8.5
上验证通过,同样适用于CentOS 8
。
1. 需求
在Redhat Linux 8
系统上,使用cgroup
限制指定用户的资源使用量。
例如,假设有这样一个需求,在一台物理服务器上,安装多套SeaboxSQL
数据库,因为业务优先级不同,期望不同数据库允许使用的资源数量不同,譬如,高优先级的SeaboxSQL
数据库允许使用更多的CPU
资源,而低优先级的SeaboxSQL
数据库仅允许使用很少量的CPU
资源。
通常,我们可能会想到使用Docker
或其它虚拟化技术进行资源隔离,但是虚拟化或多或少都有一些性能损失[1]。因此,更明智的方法是使用多个用户安装SeaboxSQL
数据库,按用户来隔离资源。通过搜索,有很多关于使用cgroup
限制Linux
用户资源的文章,笔者为此整理成参考文献[2]。
本文假定您已经了解:
cgroup
基础libcgroup
和libcgroup-tools
工具使用方法Redhat/CentOS Linux 7
使用cgroup
限制用户资源的方法
本文所需的物料可从以下项目获取[3]:
https://github.com/fairyfar/cgroup-cn
2. 问题
不幸的是,当你在Redhat Linux 8
或者其它更新的Linux
发行版(例如统信UOS V20
)上使用该方法时,却遇到了致命问题:关键服务cgred
(对应cgrulesengd
应用)已经被踢出libcgroup-tools
包了。例如,在Redhat Linux 8.5
上,即使已经安装了libcgroup
和libcgroup-tools
包的情况下,cgred
服务仍然不存在:
[root@bogon ~]# yum list installed | grep libcgroup
libcgroup.x86_64 0.41-19.el8 @base
libcgroup-tools.x86_64 0.41-19.el8 @base
[root@bogon ~]# systemctl status cgred
Unit cgred.service could not be found.
查阅libcgroup
的变更日志,有以下记录:
[root@bogon ~]# rpm -q --changelog libcgroup
* Tue Jan 14 2014 Peter Schiffer <[email protected]> 0.41-1
- resolves: #966008
updated to 0.41
- removed deprecated cgred service
please use Control Group Interface in Systemd instead
关于cgred
被移除的讨论,详见参考文献[4]。
3. 解决方法
本文提供三种方法,但是每种方法都有其局限性,请权衡使用。
3.1 使用systemd控制用户资源
Redhat Linux 8
从libcgroup
包移除cgred
服务,变更日志提到:
please use Control Group Interface in Systemd instead
看来官方是希望用systemd
来替代cgred
,因此,首先想到使用systemd
提供的接口来控制用户资源。以下通过一个具体例子来演示如何用systemd
控制用户资源。
3.1.1 实例
假设,欲限制Linux
用户seabox
的CPU使用上限为30%
(即,单个CPU核的30%
)。步骤如下:
(1). 获取用户UID
[root@bogon ~]# id seabox
uid=1002(seabox) gid=1002(fairyfar) groups=1002(seabox)
(2). 设置配额
[root@bogon ~]# systemctl set-property user-1002.slice CPUQuota=30%
如果命令报以下错误:
[root@bogon ~]# systemctl set-property user-1002.slice CPUQuota=30%
Failed to set unit properties on user-1002.slice: Unit user-1000.slice is not loaded.
则,需要在set-property
之前先执行start
命令:
[root@bogon ~]# systemctl start user-1002.slice
(3). 查看配置情况
[root@bogon ~]# systemctl cat user-