前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PostgreSQL使用Linux cgroup2控制资源消耗

PostgreSQL使用Linux cgroup2控制资源消耗

作者头像
yzsDBA
发布2024-06-14 20:28:00
600
发布2024-06-14 20:28:00
举报

PostgreSQL使用Linux cgroup2控制资源消耗

多租户和共host是一个挑战性问题。运行多个PG实例可以帮助减少内部竞争点(可伸缩性问题)。然而,一个租户的load可能会影响其他tenets,即所谓的“Noisy Neighbor”效应。幸运的是Linux允许用户通过每个程序使用cgroups来控制资源消耗。Cgroup2替代了cgroup1,处理了版本1几乎所有的限制。

Linux的5.2.0及其之后版本的内核可以使用cgroup2。实际上,2022年及其之后的Linxu分支的及其很可能已经准备好了cgroup2。

检查Linux是cgroup1还是cgroup2,可以通过cgroup mount的个数进行检查:

代码语言:javascript
复制
$ grep -c cgroup /proc/mounts
1

如果count值是1,那么就是cgroup2。因为cgroup2有一个统一单层次结构。如果是cgroup1,那么会看到多个mounts值。

如果Linux内核比较新并且仍旧使用cgroup1,那么可以使用boot参数:“systemd.unified_cgroup_hierarchy=1”。Redhat/OEL系统中,可以执行下面命令添加这个参数:

代码语言:javascript
复制
sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"

通常情况下将这个作为引导选项添加到内核参数中:

代码语言:javascript
复制
$ cat /etc/default/grub
…
GRUB_CMDLINE_LINUX="xxxxxx systemd.unified_cgroup_hierarchy=1"
…

需要重启机器生效。重启后可以验证:

代码语言:javascript
复制
$ sudo mount -l | grep cgroup
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,seclabel,nsdelegate)

请确保是cgroup2。现在我们检查这个虚拟文件系统,以便很好地理解:

代码语言:javascript
复制
[jobinaugustine@localhost ~]$ ls -l /sys/fs/cgroup/
total 0
-r--r--r--. 1 root root 0 May 27 02:10 cgroup.controllers
-rw-r--r--. 1 root root 0 May 27 02:10 cgroup.max.depth
-rw-r--r--. 1 root root 0 May 27 02:10 cgroup.max.descendants
-rw-r--r--. 1 root root 0 May 27 02:10 cgroup.procs
-r--r--r--. 1 root root 0 May 27 02:10 cgroup.stat
-rw-r--r--. 1 root root 0 May 27 02:10 cgroup.subtree_control
-rw-r--r--. 1 root root 0 May 27 02:10 cgroup.threads
-rw-r--r--. 1 root root 0 May 27 02:10 cpu.pressure
-r--r--r--. 1 root root 0 May 27 02:10 cpuset.cpus.effective
-r--r--r--. 1 root root 0 May 27 02:10 cpuset.mems.effective
-r--r--r--. 1 root root 0 May 27 02:10 cpu.stat
drwxr-xr-x. 2 root root 0 May 27 02:10 init.scope
-rw-r--r--. 1 root root 0 May 27 02:10 io.pressure
-r--r--r--. 1 root root 0 May 27 02:10 io.stat
drwxr-xr-x. 2 root root 0 May 27 02:10 machine.slice
-r--r--r--. 1 root root 0 May 27 02:10 memory.numa_stat
-rw-r--r--. 1 root root 0 May 27 02:10 memory.pressure
-r--r--r--. 1 root root 0 May 27 02:10 memory.stat
-r--r--r--. 1 root root 0 May 27 02:10 misc.capacity
drwxr-xr-x. 107 root root 0 May 27 02:10 system.slice
drwxr-xr-x. 3 root root 0 May 27 02:16 user.slice

这个是root control group。所有的slices都在这个下面。可以看到“system.slice”和“user.slice”,他们都是作为一个目录,因为他们是下一层级。

可以检查下哪些是可用的cgroup controller:

代码语言:javascript
复制
[jobinaugustine@localhost ~]$ cat /sys/fs/cgroup/cgroup.controllers
cpuset cpu io memory hugetlb pids rdma misc

1、实践

创建一个slice

当有多个实例时,为每个PG实例都创建一个独立的slice是一个不错的主意。允许我们从高级别控制资源的整个消耗。

假设想要限制所有PG服务使用不超过机器CPU的25%:

1)创建一个slice

代码语言:javascript
复制
sudo systemctl edit --force postgres.slice

2)为了演示,添加下面配置

代码语言:javascript
复制
[Unit]
Description=PostgreSQL Slice
Before=slices.target
[Slice]
MemoryAccounting=true
MemoryLimit=2048M
CPUAccounting=true
CPUQuota=25%
TasksMax=4096

3)保存后重新加载

代码语言:javascript
复制
sudo systemctl daemon-reload

4)检查slice的状态

sudo systemctl status postgres.slice

更改PG服务

1)我们可以使用PG服务中创建的slice,编辑:

代码语言:javascript
复制
$ sudo systemctl edit --full postgresql-16

2)添加slice配置,例如Slice=postgres.slice:

代码语言:javascript
复制
...
[Service]
Type=notify
User=postgres
Group=postgres
Slice=postgres.slice
...

3)保存并退出编辑。需要重启PG服务。重启时,PG会在新的slice下运行:

代码语言:javascript
复制
$ systemd-cgls | grep post
├─postgres.slice
│ └─postgresql-16.service
│ ├─3760 /usr/pgsql-16/bin/postgres -D /var/lib/pgsql/16/data/
│ ├─3761 postgres: logger
│ ├─3762 postgres: checkpointer
│ ├─3763 postgres: background writer
│ ├─3765 postgres: walwriter
│ ├─3766 postgres: autovacuum launcher
│ └─3767 postgres: logical replication launcher
│   └─3770 grep --color=auto post

4)服务状态中也会看到同样的信息

验证

尝试在一个CPU机器上并行多个会话,运行一个benchmark执行一个厚重的负载。不管我尝试了什么,Linux都限制了PG不超过slice指定的限制:

如果我们将PG的所有进程的CPU利用率都加起来,我们会看到2.3*4+2*7+1.7 = 24.9

同样的负载下不进行任何cgroup限制,会带来100%的利用率(0% idle):

Cgroup slice限制了负载,这符合预期。我们可以在一个slice中弄多个服务,这是下一个层级。systemd-cgtop可以展示slice-wise和单独的service-wise利用率:

系统级别的控制

Cgroup2非常有用,可选项更多。例如,你可能不想为PG服务创建单独的slice,特别当该机器上仅有一个PG实例时。默认情况下,PG和所有服务都作为“system.slice”的一部分。这种场景下,最简单的方式是在service级别指定cgroup限制,而不是slice级别:

代码语言:javascript
复制
sudo systemctl edit --full postgresql-16

添加:

代码语言:javascript
复制
...
[Service]
User=postgres
Group=postgres
CPUAccounting=true
CPUQuota=25%
...

重启后生效。

2、总结

Control group在docker和kubernetes中广泛使用。它们是限制机器上资源消耗的有效方法之一。Cgroup2使得使用更加便捷。使用场景:

1)更好的多租户环境

可以通过防止租户争夺同一套资源来防止“Noisy Neighbor”效应。

2)同一台机器上部署数据库服务和应用服务

绝大多数应用都是CPU密集型,数据库服务大多是内存/IO密集型。因此某些场景可以将他们部署在同台机器上。实际上我们看到许多情况下网络是潜在威胁,另一个优势是我们不必向网络公开数据库服务端口。

3)保护系统不受滥用、服务拒绝攻击

当系统重负载时,可能造成机器上运行的所有程序失去响应。这种情况往往会导致HA框架异常。对资源的良好控制可以防止这种情况发生。

3、原文

https://www.percona.com/blog/controlling-resource-consumption-on-a-postgresql-server-using-linux-cgroup2/

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 yanzongshuaiDBA 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1、实践
    • 创建一个slice
      • 更改PG服务
        • 验证
          • 系统级别的控制
          • 2、总结
          • 3、原文
          相关产品与服务
          数据库专家服务
          数据库专家服务(Database Expert Service,DBexpert)为您提供专业化的数据库服务。仅需提交您的具体问题和需求,即可获得腾讯云数据库专家的专业支持,助您解决各类专业化问题。腾讯云数据库专家服务团队均有10年以上的 DBA 经验,拥有亿级用户产品的数据库管理经验,以及丰富的服务经验。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档