核心答案是利用linux的控制组(cgroups)机制有效管理和限制资源。1. 通过cgroups将进程组织成组并设置资源限制;2. 使用cpu和cpuacct子系统限制和统计cpu使用,如设置周期和配额控制cpu时间;3. 利用memory子系统限制内存及交换空间,需同时配置物理内存与交换内存;4. 生产环境中推荐结合systemd简化管理,逐步实施监控并优化资源分配;5. cgroups还支持blkio限制磁盘i/o、net_cls/net_prio管理网络流量、pids控制进程数量、freezer暂停进程等资源控制功能。

在Linux多用户环境下,要有效管理和限制各个用户或进程的资源使用,核心答案在于利用Linux的控制组(cgroups)机制。它提供了一套强大的、细粒度的资源隔离和优先级管理框架,确保系统稳定性和公平性,避免某个用户或应用过度消耗资源导致整体性能下降。

对我来说,cgroups不仅仅是一个技术特性,它更像是一种对系统秩序的追求。在多用户或多服务并存的环境里,如果不加以限制,资源争抢几乎是必然的。cgroups的出现,就是为了解决这种混乱。它允许你将一组进程组织起来,然后对这组进程的资源使用进行限制、审计和优先级管理。
其工作原理可以概括为:将系统资源(如CPU、内存、I/O带宽、网络带宽等)划分为不同的“子系统”,每个子系统管理一种特定类型的资源。然后,你可以创建“控制组”(cgroup),将一个或多个进程放入某个cgroup中,并为该cgroup在特定子系统下设置资源限制。这些cgroup可以形成一个层次结构,子cgroup会继承父cgroup的限制,并在此基础上进行更细致的分配。

实际操作中,我们通常通过挂载cgroup文件系统,然后直接在文件系统路径下创建目录(即cgroup),并写入相应的配置文件来设定限制。当然,更现代的方式是利用
systemd
这大概是cgroups最常用也最直观的场景了。限制CPU和内存,能直接影响一个进程或用户的工作效率和稳定性。

对于CPU,我们主要关注
cpu
cpuacct
cpu
cpuacct
CPU限制示例: 假设我想创建一个名为
limited_cpu_group
# 挂载cgroup文件系统(如果尚未挂载,通常系统默认已挂载) # mount -t cgroup -o cpu,cpuacct none /sys/fs/cgroup/cpu_and_cpuacct # 创建cgroup目录 sudo mkdir /sys/fs/cgroup/cpu_and_cpuacct/limited_cpu_group # 设置CPU配额:每100ms周期内,该组最多使用50ms的CPU时间 # cpu.cfs_period_us: 周期长度 (微秒) # cpu.cfs_quota_us: 周期内允许使用的CPU时间 (微秒) echo 100000 | sudo tee /sys/fs/cgroup/cpu_and_cpuacct/limited_cpu_group/cpu.cfs_period_us echo 50000 | sudo tee /sys/fs/cgroup/cpu_and_cpuacct/limited_cpu_group/cpu.cfs_quota_us # 将当前shell进程添加到这个cgroup # 注意:实际应用中,你会将目标进程的PID写入tasks文件 echo $$ | sudo tee /sys/fs/cgroup/cpu_and_cpuacct/limited_cpu_group/tasks # 验证(在一个新的终端中运行一个CPU密集型任务,观察其CPU使用率) # 例如:yes > /dev/null
对于内存,
memory
内存限制示例: 创建一个名为
limited_memory_group
# 挂载cgroup文件系统 # mount -t cgroup -o memory none /sys/fs/cgroup/memory # 创建cgroup目录 sudo mkdir /sys/fs/cgroup/memory/limited_memory_group # 设置内存限制 (单位:字节) # memory.limit_in_bytes: 物理内存限制 # memory.memsw.limit_in_bytes: 物理内存 + 交换空间总限制 echo 268435456 | sudo tee /sys/fs/cgroup/memory/limited_memory_group/memory.limit_in_bytes echo 536870912 | sudo tee /sys/fs/cgroup/memory/limited_memory_group/memory.memsw.limit_in_bytes # 将进程添加到cgroup # echo <PID> | sudo tee /sys/fs/cgroup/memory/limited_memory_group/tasks
我发现,在设置这些限制时,一个常见的误区是只设置
memory.limit_in_bytes
memory.memsw.limit_in_bytes
memsw
memory
在生产环境中落地cgroups,绝不是简单地敲几个命令那么直接。我个人在实践中遇到过不少坑,也总结了一些经验。
挑战:
最佳实践:
利用systemd
systemd
Slice
Scope
Service
systemd
# /etc/systemd/system/my_app.service [Unit] Description=My Application [Service] ExecStart=/usr/local/bin/my_app # CPU限制:使用CPU配额,等同于cfs_quota_us/cfs_period_us CPUQuota=50% # 内存限制:256MB MemoryLimit=256M [Install] WantedBy=multi-user.target
逐步实施与监控: 不要一次性对所有服务或用户应用严格的限制。从宽松的限制开始,或者先只进行资源统计(
cpuacct
memory.usage_in_bytes
结合监控工具: 使用Prometheus、Grafana等监控工具,结合
node_exporter
OOM Killer的考量: 当cgroup的内存限制被触及时,系统可能会触发OOM killer。了解cgroup的OOM行为,并通过
memory.oom_control
oom_kill_disable
合理规划层次结构: 例如,可以按照部门(
department.slice
web_servers.slice
nginx@.service
cgroups的能力远不止CPU和内存,它支持多种子系统,涵盖了系统资源的方方面面。
blkio
blkio.weight
blkio.throttle.read_bps_device
blkio.throttle.write_bps_device
# 挂载blkio子系统 # mount -t cgroup -o blkio none /sys/fs/cgroup/blkio # 创建cgroup sudo mkdir /sys/fs/cgroup/blkio/limited_io_group # 限制设备/dev/sda的写入速度为10MB/s # 格式:<major>:<minor> <bytes_per_second> echo "8:0 10485760" | sudo tee /sys/fs/cgroup/blkio/limited_io_group/blkio.throttle.write_bps_device
这里
8:0
/dev/sda
ls -l /dev/sda
net_cls
net_prio
net_cls
tc
net_prio
net_cls
net_cls.classid
tc
net_prio
net_prio.prioidx
net_prio.ifpriomap
pids
pids.max
# 挂载pids子系统 # mount -t cgroup -o pids none /sys/fs/cgroup/pids # 创建cgroup sudo mkdir /sys/fs/cgroup/pids/limited_pids_group # 限制最多只能有10个进程 echo 10 | sudo tee /sys/fs/cgroup/pids/limited_pids_group/pids.max
freezer
freezer.state
FROZEN
THAWED
这些子系统提供了非常全面的资源管理能力,但实际使用中,我发现需要对Linux内核和系统管理有较深的理解。特别是像
net_cls
tc
以上就是Linux多用户环境下的资源管理_Linux cgroups与限制策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号