Depth understanding of Linux Cgroup series (two): Fun CPU

Original link: in-depth understanding of Linux Cgroup series (two): Fun CPU

The article introduces some basic concepts cgroup, including its  CentOS default settings and system control tool, and the CPU example to explain how cgroup resource control. This article will demonstrate how to cgroup be limited by the specific examples of  CPU the impact of using different cgroup and set on performance.

1. Review current information cgroup


There are two ways to view the system's current cgroup information. The first method is through  systemd-cgls to view the command, it will return to the system as a whole cgroup hierarchy tree from the top cgroup  slice composed as follows:

$ systemd-cgls --no-page
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 22
├─user.slice
│ ├─user-1000.slice
│ │ └─session-11.scope
│ │   ├─9507 sshd: tom [priv]
│ │   ├─9509 sshd: tom@pts/3
│ │   └─9510 -bash
│ └─user-0.slice
│   └─session-1.scope
│     ├─ 6239 sshd: root@pts/0
│     ├─ 6241 -zsh
│     └─11537 systemd-cgls --no-page
└─system.slice
  ├─rsyslog.service
  │ └─5831 /usr/sbin/rsyslogd -n
  ├─sshd.service
  │ └─5828 /usr/sbin/sshd -D
  ├─tuned.service
  │ └─5827 /usr/bin/python2 -Es /usr/sbin/tuned -l -P
  ├─crond.service
  │ └─5546 /usr/sbin/crond -n

Cgroup can see the system level by the highest level  user.slice and  system.slice composition. Because the system does not run virtual machines and containers, so there is no  machine.slice, so when the CPU is busy, user.slice and  system.slice will each receive  50% CPU usage time.

user.slice following two sub-slice: user-1000.slice and  user-0.slice, each sub-slice ID are used the User ( UID) to name, so it is easy to recognize which slice belongs to which user. For example: From the above it can be seen in the output information  user-1000.slice belongs to the user tom, user-0.slice belonging to the users root.

systemd-cgls Command provides only a static snapshot of information cgroup hierarchy, in order to view the cgroup hierarchy of dynamic information, you can  systemd-cgtop view the command:

$ systemd-cgtop
Path                                                                                                                                       Tasks   %CPU   Memory  Input/s Output/s

/                                                                                                                                            161    1.2   161.0M        -        -
/system.slice                                                                                                                                  -    0.1        -        -        -
/system.slice/vmtoolsd.service                                                                                                                 1    0.1        -        -        -
/system.slice/tuned.service                                                                                                                    1    0.0        -        -        -
/system.slice/rsyslog.service                                                                                                                  1    0.0        -        -        -
/system.slice/auditd.service                                                                                                                   1      -        -        -        -
/system.slice/chronyd.service                                                                                                                  1      -        -        -        -
/system.slice/crond.service                                                                                                                    1      -        -        -        -
/system.slice/dbus.service                                                                                                                     1      -        -        -        -
/system.slice/gssproxy.service                                                                                                                 1      -        -        -        -
/system.slice/lvm2-lvmetad.service                                                                                                             1      -        -        -        -
/system.slice/network.service                                                                                                                  1      -        -        -        -
/system.slice/polkit.service                                                                                                                   1      -        -        -        -
/system.slice/rpcbind.service                                                                                                                  1      -        -        -        -
/system.slice/sshd.service                                                                                                                     1      -        -        -        -
/system.slice/system-getty.slice/[email protected]                                                                                            1      -        -        -        -
/system.slice/systemd-journald.service                                                                                                         1      -        -        -        -
/system.slice/systemd-logind.service                                                                                                           1      -        -        -        -
/system.slice/systemd-udevd.service                                                                                                            1      -        -        -        -
/system.slice/vgauthd.service                                                                                                                  1      -        -        -        -
/user.slice                                                                                                                                    3      -        -        -        -
/user.slice/user-0.slice/session-1.scope                                                                                                       3      -        -        -        -
/user.slice/user-1000.slice                                                                                                                    3      -        -        -        -
/user.slice/user-1000.slice/session-11.scope                                                                                                   3      -        -        -        -
/user.slice/user-1001.slice/session-8.scope                                                                                                    3      -        -        -        -

Statistics provided by systemd-cgtop and control options with the  top command but the command displays only those resources slice open the service and statistical functions. For example: If you want to open the  sshd.service resource statistics function, you can do the following:

$ systemctl set-property sshd.service CPUAccounting=true MemoryAccounting=true

This command will  /etc/systemd/system/sshd.service.d/ create the appropriate configuration file directory:

$ ll /etc/systemd/system/sshd.service.d/
总用量 8
4 -rw-r--r-- 1 root root 28 5月  31 02:24 50-CPUAccounting.conf
4 -rw-r--r-- 1 root root 31 5月  31 02:24 50-MemoryAccounting.conf

$ cat /etc/systemd/system/sshd.service.d/50-CPUAccounting.conf
[Service]
CPUAccounting=yes

$ cat /etc/systemd/system/sshd.service.d/50-MemoryAccounting.conf
[Service]
MemoryAccounting=yes

After configuration is complete, and then restart the  sshd service:

$ systemctl daemon-reload
$ systemctl restart sshd

Then re-run systemd-cgtop command, you can see sshd resource usage statistics:

Open resource usage statistics may increase the load on the system, because the resources have to consume CPU and memory statistics, in most cases the use of  top command to see enough. Of course, this is the Linux system Well, all the control is in your own hands, you want to do on how to do it.

2. CPU allocation time relative


Through the study of the article we know the CPU  shares can be used to set the relative CPU usage time, then we have to verify it through practice.

The following experiments conducted are carried out on a single-core CPU system, where multi-core single-core is completely different, the end of the text will be discussed separately.

The test object is a service and two ordinary user, where the user  tom 's UID is 1000, you can view the following command:

$ cat /etc/passwd|grep tom
tom:x:1000:1000::/home/tom:/bin/bash

Create a  foo.service:

$ cat /etc/systemd/system/foo.service
[Unit]
Description=The foo service that does nothing useful
After=remote-fs.target nss-lookup.target

[Service]
ExecStart=/usr/bin/sha1sum /dev/zero
ExecStop=/bin/kill -WINCH ${MAINPID}

[Install]
WantedBy=multi-user.target

/dev/zero It is a special device file in linux system, when you read it, it will provide unlimited space characters, so foo.service will continue to consume CPU resources. Now we will foo.service of CPU shares changed  2048:

$ mkdir /etc/systemd/system/foo.service.d
$ cat << EOF > /etc/systemd/system/foo.service.d/50-CPUShares.conf
[Service]
CPUShares=2048
EOF

由于系统默认的 CPU shares 值为 1024,所以设置成 2048 后,在 CPU 繁忙的情况下,foo.service 会尽可能获取 system.slice 的所有 CPU 使用时间。

现在通过 systemctl start foo.service 启动 foo 服务,并使用 top 命令查看 CPU 使用情况:

目前没有其他进程在消耗 CPU,所以 foo.service 可以使用几乎 100% 的 CPU。

现在我们让用户 tom 也参与进来,先将 user-1000.slice 的 CPU shares 设置为 256

$ systemctl set-property user-1000.slice CPUShares=256

使用用户 tom 登录该系统,然后执行命令 sha1sum /dev/zero,再次查看 CPU 使用情况:

现在是不是感到有点迷惑了?foo.service 的 CPU shares 是 2048,而用户 tom 的 CPU shares 只有 256,难道用户 tom 不是应该只能使用 10% 的 CPU 吗?回忆一下我在上一节提到的,当 CPU 繁忙时,user.slice 和 system.slice 会各获得 50% 的 CPU 使用时间。而这里恰好就是这种场景,同时 user.slice 下面只有 sha1sum 进程比较繁忙,所以会获得 50% 的 CPU 使用时间。

最后让用户 jack 也参与进来,他的 CPU shares 是默认值 1024。使用用户 jack 登录该系统,然后执行命令 sha1sum /dev/zero,再次查看 CPU 使用情况:

上面我们已经提到,这种场景下 user.slice 和 system.slice 会各获得 50% 的 CPU 使用时间。用户 tom 的 CPU shares 是 256,而用户 jack 的 CPU shares 是 1024,因此用户 jack 获得的 CPU 使用时间是用户 tom 的 4倍。

3. 分配 CPU 绝对使用时间


上篇文章已经提到,如果想严格控制 CPU 资源,设置 CPU 资源的使用上限,即不管 CPU 是否繁忙,对 CPU 资源的使用都不能超过这个上限,可以通过 CPUQuota 参数来设置。下面我们将用户 tom 的 CPUQuota 设置为 5%

$ systemctl set-property user-1000.slice CPUQuota=5%

这时你会看到用户 tom 的 sha1sum 进程只能获得 5% 左右的 CPU 使用时间。

如果此时停止 foo.service,关闭用户 jack 的 sha1sum 进程,你会看到用户 tom 的 sha1sum 进程仍然只能获得 5%左右的 CPU 使用时间。

如果某个非核心服务很消耗 CPU 资源,你可以通过这种方法来严格限制它对 CPU 资源的使用,防止对系统中其他重要的服务产生影响。

4. 动态设置 cgroup


cgroup 相关的所有操作都是基于内核中的 cgroup virtual filesystem,使用 cgroup 很简单,挂载这个文件系统就可以了。系统默认情况下都是挂载到 /sys/fs/cgroup 目录下,当 service 启动时,会将自己的 cgroup 挂载到这个目录下的子目录。以 foo.service 为例:

先进入 system.slice 的 CPU 子系统:

cd /sys/fs/cgroup/cpu,cpuacct/system.slice

查看 foo.service 的 cgroup 目录:

$ ls foo.*
zsh: no matches found: foo.*

因为 foo.service 没有启动,所以没有挂载 cgroup 目录,现在启动 foo.service,再次查看它的 cgroup 目录:

$ ls foo.serice
cgroup.clone_children  cgroup.procs  cpuacct.usage         cpu.cfs_period_us  cpu.rt_period_us   cpu.shares  notify_on_release
cgroup.event_control   cpuacct.stat  cpuacct.usage_percpu  cpu.cfs_quota_us   cpu.rt_runtime_us  cpu.stat    tasks

也可以查看它的 PID 和 CPU shares:

$ cat foo.service/tasks
20225

$ cat foo.service/cpu.shares
2048

理论上我们可以在 /sys/fs/cgroup 目录中动态改变 cgroup 的配置,但我不建议你在生产环境中这么做。如果你想通过实验来深入理解 cgroup,可以多折腾折腾这个目录。

5. 如果是多核 CPU 呢?


上面的所有实验都是在单核 CPU 上进行的,下面我们简单讨论一下多核的场景,以 2 个 CPU 为例。

首先来说一下 CPU shares,shares 只能针对单核 CPU 进行设置,也就是说,无论你的 shares 值有多大,该 cgroup 最多只能获得 100% 的 CPU 使用时间(即 1 核 CPU)。还是用本文第 2 节的例子,将 foo.service 的 CPU shares 设置为 2048,启动 foo.service,这时你会看到 foo.service 仅仅获得了 100% 的 CPU 使用时间,并没有完全使用两个 CPU 核:

再使用用户 tom 登录系统,执行命令 sha1sum /dev/zero,你会发现用户 tom 的 sha1sum 进程和 foo.service 各使用 1 个 CPU 核:

再来说说 CPUQuota,这个上篇文章结尾已经提过了,如要让一个 cgroup 完全使用两个 CPU 核,可以通过 CPUQuota 参数来设置。例如:

$ systemctl set-property foo.service CPUQuota=200%

至于进程最后能不能完全使用两个 CPU 核,就要看它自身的设计支持不支持了。

6. 总结


本文通过具体的示例来观察不同的 cgroup 设置对性能的影响,下面一篇文章将会演示如何通过 cgroup 来限制内存的使用。


 

Guess you like

Origin www.cnblogs.com/ryanyangcs/p/11198161.html