本文档介绍了如何使用资源组管理 YMatrix 中事务并发、CPU和内存的资源分配。定义资源组后,可以将资源组分配给一个或多个数据库角色以控制角色所能使用的资源。
YMatrix 使用基于 Linux 的控制组来管理数据库资源,并使用 Runaway 来进行内存的统计、跟踪和管理。
下表列出了可配置的资源组参数
参数 | 描述 | 取值范围 | 默认参数 |
---|---|---|---|
CONCURRENCY | 资源组中允许的最大并发事务数,包括活动事务和空闲事务。 | [0 - 最大连接数] | 20 |
CPU_MAX_PERCENT | 配置资源组可以使用的CPU资源的最大百分比。 | [1 - 100] | -1 (未启用) |
CPU_WEIGHT | 配置资源组的调度优先级。 | [1 - 500] | 100 |
CPUSET | 为该资源组保留的特定CPU逻辑核心(或超线程中的逻辑线程)。 | 依赖系统核心配置 | -1 |
MEMORY_QUOTA | 为资源组指定内存限制值。 | 整数(MB) | -1 (未启用,使用 statement_mem 作为单次查询的内存限制) |
MIN_COST | 一个查询计划被包含在资源组中的最小成本。 | 整数 | 0 |
注意!
针对SET
/RESET
/SHOW
命令,资源组不会生效
当用户运行查询时,YMatrix 会根据为资源组定义的一组限制来评估查询状态。
CONCURRENCY
控制资源组允许的最大并发事务数。默认限制值为 20,值为 0 时表示此资源组不允许运行查询。
如果资源限制尚未达到且查询不会导致超出资源组的并发事务限制,YMatrix 会立即运行查询。如果已达到资源组的最大并发事务数,YMatrix 会将资源组达到其 CONCURRENCY
限制后提交的任何事务排队,并且等到其他查询完成后进行运行。
gp_resource_group_queuing_timeout
可以用来指定队列中事务取消前的等待时间。默认为 0,意味着事务无限期排队。
绕过资源组分配限制
gp_resource_group_bypass
用于启用或禁用资源组的并发事务限制,使查询可以立即执行。设为 true
,查询就会跳过资源组的并发限制。此时查询的内存配额按照 statement_mem
进行分配,如果内存不足,查询就会失败。此参数只能在单个会话中设置,不能在事务或函数内设置。gp_resource_group_bypass_catalog_query
用于系统表查询是否跳过资源组的资源限制。默认为 true
。适用于类似数据库的图形用户界面(GUI)客户端运行目录查询以获取元数据的情况。其资源分配在资源组之外,内存配额为每个查询的 statement_mem
。gp_resource_group_bypass_direct_dispatch
用于控制直接分发查询(direct dispatch queries)是否跳过资源组的限制。将其设为 true
,查询时将不再受其所属资源组分配的 CPU 或内存限制的约束,从而可以立即执行。此时查询的内存配额按照 statement_mem
进行分配,如果内存不足,查询就会失败。此参数只能在单个会话中设置,不能在事务或函数内设置。YMatrix 通过以下两种方式分配 CPU 资源:
在同一群集上可以为不同的资源组配置不同的 CPU 资源分配模式,同一资源组只能使用一种 CPU 资源分配模式。 运行时也可更改资源组的 CPU 资源分配模式。
可通过 gp_resource_group_cpu_limit
来确定要分配给每个 segment 节点的资源组的系统 CPU 资源的最大百分比。
通过核心(Core)分配 CPU 资源
CPUSET
用于设置要为资源组保留的 CPU 核心。当为资源组配置 CPUSET
时,YMatrix 会停用该组的 CPU_MAX_PERCENT
和 CPU_WEIGHT
,并将其值设置为 -1
。
使用注意:
'1;1,3-4'
在主节点上使用 core1,在 segment 上使用core 1、core 3 和 core 4。通过百分比分配 CPU 资源
CPU_MAX_PERCENT
用于设置 segment 可以使用的 CPU 资源上线,比如设置为 40,表明最多可以使用可用 CPU 资源的 40%。当资源组中的任务处于空闲状态且未使用任何 CPU 时间时,剩余时间将被收集到未使用 CPU 周期的全局池中,其他资源组可以从此池中借用 CPU 周期。
CPU_WEIGHT
用于分配当前组的调度优先级。默认值是 100,取值范围是 1 到 500。该值指定了资源组中任务可获得的相对份额的 CPU 时间。
使用注意:
CPU_MAX_PERCENT
值都设置为 100)时,第一个资源组将获得 50% 的总 CPU 时间,另外两个组各获得 25%。CPU_MAX_PERCENT
设置为 100)的组,则第一个组只能使用 33% 的 CPU,剩下的组分别获得 16.5%、16.5% 和 33%。配置说明
Group Name | CONCURRENCY | CPU_MAX_PERCENT | CPU_WEIGHT |
---|---|---|---|
default_group | 20 | 50 | 10 |
admin_group 10 | 70 | 30 | |
system_group | 10 | 30 | 10 |
test | 10 | 10 | 10 |
default_group
)中角色根据 CPU_WEIGHT
参数所确定的可用 CPU 百分比为 10/(10+30+10+10)=16%
。这意味着在系统负载较高时,它们至少可以使用 16%
的CPU资源。当系统存在空闲 CPU 资源时,它们可以使用更多资源,因为硬限制(由 CPU_MAX_PERCENT
设置)为50%。admin_group
)中角色在系统负载较高时的可用 CPU 百分比为 30/(10+30+10+10)=50%
。当系统有空闲 CPU 资源时,它们可以使用的资源上限由硬限制 70%
决定。test
)中角色的可用 CPU 百分比为 10/(10+30+10+10)=16%
。然而,由于硬限制(由CPU_MAX_PERCENT
确定)为 10%。因此即使在系统空闲时,它们也只能使用最多 10% 的资源。MEMORY_QUOTA
表示 Segment 上为该资源组保留的最大内存量。这是查询执行期间 Segment 上所有查询的工作进程可以消耗的总内存量。分配给某个查询的内存量是该组内存限制除以该组并发限制:MEMORY_QUOTA
/ CONCURRENCY
。
如果一个查询需要更大内存,可以使用 gp_resgroup_memory_query_fixed_mem
在会话级别为查询设置所需内存量,该配置可覆盖并超过资源组分配的内存。
使用注意
gp_resgroup_memory_query_fixed_mem
,会使用设置值来绕过资源组设置。gp_resgroup_memory_query_fixed_mem
,会使用 MEMORY_QUOTA
/ CONCURRENCY
作为查询分配的内存量。MEMORY_QUOTA
,则查询内存分配的值默认为 statement_mem
。gp_workfile_limit_files_per_query
时,YMatrix 会生成内存不足 (OOM) 错误。配置示例
考虑一个名为 adhoc 的资源组,MEMORY_QUOTA
设置为 1.5 GB,CONCURRENCY
设置为 3。默认情况下,提交给该组的每个语句都分配 500MB 的内存。现在考虑以下一系列事件:
ADHOC_1
提交查询 Q1
,覆盖 gp_resgroup_memory_query_fixed_mem
到800MB。Q1
语句被允许进入系统。ADHOC_2
提交查询 Q2
,使用默认的 500MB。Q1
和 Q2
仍在运行的情况下,用户 ADHOC_3
提交查询 `Q3,使用默认的 500MB 。Q1
和 Q2
已经使用了该资源组 1500MB 中的 1300MB。但是,如果某些时段系统有足够的可用内存用于查询 Q3
,Q3
则可以正常运行。ADHOC_4
提交查询 Q4
,使用 gp_resgroup_memory_query_fixed_mem
设置为 700MB。
由于查询 Q4
绕过资源组限制,他会立即运行。特殊使用注意事项
gp_resource_group_bypass
或 gp_resource_group_bypass_catalog_query
设置配置参数以绕过资源组限制,则查询的内存限制值为 statement_mem
。MEMORY_QUOTA
/ CONCURRENCY
)< statement_mem
时,则使用 statement_mem
作为查询分配的固定内存量。statement_mem
的最大值上限为 max_statement_mem
。MIN_COST
的查询语句,使用 statement_mem
作为内存配额。0.通过检查系统启动期间默认挂载的文件系统来验证您的环境中配置的 cgroup
版本:
stat -fc %T /sys/fs/cgroup/
对于 cgroup v1
,输出是 tmpfs
。对于 cgroup v2
,输出是 cgroup2fs
。
如果不需要更改 cgroup 的版本,只需跳到配置 cgroup v1 或配置cgroup v2 完成配置操作。
如果需要从 cgroup v1 切换到 v2,请以 root 身份运行以下命令:
grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=1"
vim /etc/default/grub
# add or modify: GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"
update-grub
如果需要从 cgroup v2 切换到 v1,请以 root 身份运行以下命令:
grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller"
vim /etc/default/grub
# add or modify: GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"
update-grub
如果您想继续使用 cgroup v1,请确保 /sys/fs/cgroup/memory/gpdb
下的每个 memory.limit_in_bytes
文件(包括 /sys/fs/cgroup/memory/gpdb/memory.limit_in_bytes
和 /sys/fs/cgroup/memory/gpdb/[OID]/memory.limit_in_bytes
)没有极限值。如果是,请运行:
echo -1 >> memory.limit_in_bytes
之后,重新启动主机以使更改生效。
1.在集群中的每个节点上操作:
注意!
需使用超级用户或具有sudo
访问权限的用户才能编辑此文件。
vi /etc/cgconfig.conf
在配置文件中添加以下信息。
group gpdb {
perm {
task {
uid = mxadmin;
gid = mxadmin;
}
admin {
uid = mxadmin;
gid = mxadmin;
}
}
cpu {
}
cpuacct {
}
cpuset {
}
memory {
}
}
此内容配置了由 mxadmin
用户管理的 CPU、CPU 核算、CPU 核心集以及内存控制组。
2.为 YMatrix 集群每一个节点开启 cgroup
服务。
cgconfigparser -l /etc/cgconfig.conf
systemctl enable cgconfig.service
systemctl start cgconfig.service
3.确定节点的 cgroup
目录挂载点
grep cgroup /proc/mounts
cgroup
目录挂载点 /sys/fs/cgroup
。tmpfs /sys/fs/cgroup tmpfs ro,nosuid,nodev,noexec,mode=755 0 0
cgroup /sys/fs/cgroup/systemd cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd 0 0
cgroup /sys/fs/cgroup/devices cgroup rw,nosuid,nodev,noexec,relatime,devices 0 0
cgroup /sys/fs/cgroup/net_cls,net_prio cgroup rw,nosuid,nodev,noexec,relatime,net_prio,net_cls 0 0
cgroup /sys/fs/cgroup/pids cgroup rw,nosuid,nodev,noexec,relatime,pids 0 0
cgroup /sys/fs/cgroup/freezer cgroup rw,nosuid,nodev,noexec,relatime,freezer 0 0
cgroup /sys/fs/cgroup/cpu,cpuacct cgroup rw,nosuid,nodev,noexec,relatime,cpuacct,cpu 0 0
cgroup /sys/fs/cgroup/perf_event cgroup rw,nosuid,nodev,noexec,relatime,perf_event 0 0
cgroup /sys/fs/cgroup/hugetlb cgroup rw,nosuid,nodev,noexec,relatime,hugetlb 0 0
cgroup /sys/fs/cgroup/memory cgroup rw,nosuid,nodev,noexec,relatime,memory 0 0
cgroup /sys/fs/cgroup/cpuset cgroup rw,nosuid,nodev,noexec,relatime,cpuset 0 0
cgroup /sys/fs/cgroup/blkio cgroup rw,nosuid,nodev,noexec,relatime,blkio 0 0
4.检验是否正确配置
ls -l <cgroup_mount_point>/cpu/gpdb
ls -l <cgroup_mount_point>/cpuset/gpdb
ls -l <cgroup_mount_point>/memory/gpdb
如果目录存在,并且属主是 mxadmin:mxadmin
,说明成功配置 cgroup
对 YMatrix 数据库的资源管理。
1.将系统配置为在系统启动时默认挂载 cgroups-v2,通过 systemd 系统和服务管理器以 root 用户身份实现。
grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"
2.重新启动系统,使更改生效。
reboot now
3.创建目录 /sys/fs/cgroup/matrixdb6.service
,添加所有必要的控制器,并确保 mxadmin
用户对其具有读写权限。
mkdir -p /sys/fs/cgroup/matrixdb6.service
echo "+cpuset +io +cpu +memory" | tee -a /sys/fs/cgroup/cgroup.subtree_control
chown -R mxadmin:mxadmin /sys/fs/cgroup/matrixdb6.service
运行上述命令后,您可能会遇到错误无效参数。这是因为 cgroup v2 不支持控制实时进程,只有当所有实时进程都在根 cgroup 中时才能启用 cpu 控制器。在这种情况下,请找到所有实时进程并将它们移动到 root cgroup,然后再重新启用控制器。
1.确保 mxadmin
对 /sys/fs/cgroup/cgroup.procs
具有写入权限。这是在集群启动后将 YMatrix 进程从用户移动到 /sys/fs/cgroup/matrixdb6.service/
以管理 postmaster 服务及其所有必需的辅助进程。
chmod a+w /sys/fs/cgroup/cgroup.procs
由于资源组手动管理 cgroup
文件,系统重启后上述设置将失效。为 systemd
添加以下 bash
脚本,使其在系统启动期间自动运行。以 root 用户身份执行以下步骤:
1.创建 matrixdb6.service
vim /etc/systemd/system/matrixdb6.service
2.将以下内容写入 matrixdb6.service
,如果用户不是 mxadmin
,则替换为相应的用户。
[Unit]
Description=Greenplum Cgroup v2 Configuration Service
[Service]
Type=simple
WorkingDirectory=/sys/fs/cgroup/matrixdb6.service
Delegate=yes
Slice=-.slice
# set hierarchies only if cgroup v2 mounted
ExecCondition=bash -c '[ xcgroup2fs = x$(stat -fc "%%T" /sys/fs/cgroup) ] || exit 1'
ExecStartPre=bash -ec " \
chown -R mxadmin:mxadmin .; \
chmod a+w ../cgroup.procs; \
mkdir -p helper.scope"
ExecStart=sleep infinity
ExecStartPost=bash -ec "echo $MAINPID > /sys/fs/cgroup/cgroup.procs;"
[Install]
WantedBy=basic.target
3.重新加载 systemd
守护程序并启用服务:
systemctl daemon-reload
systemctl enable gpdb.service
1.将 gp_resource_manager
服务器配置参数设置为值 "group"
gpconfig -c gp_resource_manager -v "group"
2.重启 YMatrix 数据库集群
mxstop -arf
启用后,角色提交的任何事务都将定向到分配给该角色的资源组,并受该资源组的并发、内存、CPU限制的约束。
YMatrix 默认创建名为 admin_group
、default_group
和 system_group
的角色资源组。启用资源组时,任何未显式分配资源组的角色都将分配至该角色功能的默认组。SUPERUSER
角色分配至 admin_group
,非管理员角色分配至 default_group
,系统进程的资源分配至 system_group
。其中,不能手动将任何角色分配给 system_group
。
各角色资源组配置如下.
参数 | admin_group | default_group | system_group |
---|---|---|---|
CONCURRENCY | 10 | 5 | 0 |
CPU_MAX_PERCENT | 10 | 20 | 10 |
CPU_WEIGHT | 100 | 100 | 100 |
CPUSET | -1 | -1 | -1 |
IO_LIMIT | -1 | -1 | -1 |
MEMORY_LIMIT | -1 | -1 | -1 |
MIN_COST | 0 | 0 | 0 |
CREATE RESOURCE GROUP
命令创建新的资源组。为角色创建资源组时,提供名称和 CPU 资源分配模式(核心或百分比)。必须提供 CPU_MAX_PERCENT
或 CPUSET
限制值。
使用示例
创建一个名为 rgroup1
的资源组,其 CPU 限制为 20,内存限制为 250,CPU 优先级为 500,最小开销为 50:
CREATE RESOURCE GROUP rgroup1 WITH (CONCURRENCY=20, CPU_MAX_PERCENT=20, MEMORY_QUOTA=250, CPU_WEIGHT=500, MIN_COST=50);
其中,CPU 和内存限制由分配给 rgroup1
的每个角色共享。
ALTER RESOURCE GROUP
命令更新资源组的限制。
ALTER RESOURCE GROUP rg_role_light SET CONCURRENCY 7;
ALTER RESOURCE GROUP exec SET MEMORY_QUOTA 30;
ALTER RESOURCE GROUP rgroup1 SET CPUSET '1;2,4';
注意!
不能将admin_group
的CONCURRENCY
值设置或更改为 0。
DROP RESOURCE GROUP
命令删除资源组。要删除角色的资源组,该组不能分配给任何角色,资源组中也不能有任何活动或等待的事务。
DROP RESOURCE GROUP exec;
YMatrix 支持 Runaway 检测。对于由资源组管理的查询,可以根据查询所使用的内存量自动终止查询。 相关的配置参数如下:
gp_vmem_protect_limit
:设置活动 segment 实例中所有 postgres 进程可以消耗的内存量。如果一个查询导致这个限制被超过,将不会分配内存,查询将失败。runaway_detector_activation_percent
:当启用资源组时,如果使用的内存量超过了指定值 gp_vmem_protect_limit
* runaway_detector_activation_percent
,YMatrix 将根据内存使用量来终止由资源组(不包括 system_group
资源组中的查询)管理的查询。查询终止将从消耗内存量最大的查询开始,直到内存使用量低于指定的百分比终止。使用 CREATE ROLE
或 ALTER ROLE
命令的 RESOURCE GROUP
子句将资源组分配给数据库角色。
ALTER ROLE bill RESOURCE GROUP rg_light;
CREATE ROLE mary RESOURCE GROUP exec;
可以将资源组分配给一个或多个角色。如果已定义角色的层次结构,分配给父角色的资源组不会向下传播到该角色组的成员。
如果需要从角色中删除资源组分配并为角色分配默认组,可将角色的组名分配更改为 NONE
。
ALTER ROLE mary RESOURCE GROUP NONE;
SELECT * FROM gp_toolkit.gp_resgroup_config;
SELECT * FROM gp_toolkit.gp_resgroup_status;
SELECT * FROM gp_toolkit.gp_resgroup_status_per_host;
SELECT rolname, rsgname FROM pg_roles, pg_resgroup
WHERE pg_roles.rolresgroup=pg_resgroup.oid;
SELECT query, rsgname,wait_event_type, wait_event
FROM pg_stat_activity;
pg_cancel_backend()
来结束该进程。
具体步骤如下:SELECT rolname, g.rsgname, pid, waiting, state, query, datname
FROM pg_roles, gp_toolkit.gp_resgroup_status g, pg_stat_activity
WHERE pg_roles.rolresgroup=g.groupid
AND pg_stat_activity.usename=pg_roles.rolname;
rolname | rsgname | pid | waiting | state | query | datname
---------+----------+---------+---------+--------+------------------------ -+---------
sammy | rg_light | 31861 | f | idle | SELECT * FROM mytesttbl; | testdb
billy | rg_light | 31905 | t | active | SELECT * FROM topten; | testdb
SELECT pg_cancel_backend(31905);
注意!
不要使用操作系统KILL
命令取消任何 YMatrix 数据库进程。
具有超级用户权限的用户可以运行 gp_toolkit.pg_resgroup_move_query()
函数将正在运行的查询从一个资源组移动到另一个资源组,而不会停止该查询。使用此函数可以通过将长时间运行的查询移动到资源分配或可用性更高的资源组来加快查询速度。
pg_resgroup_move_query()
仅将指定的查询移动到目标资源组,后续提交的查询仍分配至原资源组。
注意!
只能将活动或正在运行的查询移动到新资源组。由于并发或内存限制,不能移动处于空闲状态的排队或挂起的查询。
pg_resgroup_move_query()
需要正在运行的查询的进程 id 或 pid,以及要将查询移动到的资源组的名称。
pg_resgroup_move_query( pid int4, group_name text );
如取消资源组中正在运行或排队的事务中所述,可以使用 gp_toolkit.gp_resgroup_status
视图列出每个资源组的名称、id 和状态。
当调用 pg_resgroup_move_query()
函数时,正在运行的查询会受到目标资源组配置的限制,这些限制包括并发任务限制、内存限制等。
gp_resource_group_queuing_timeout
,则会排队等待指定的毫秒数。pg_resgroup_move_query()
会尝试将槽位控制权交给目标进程,最多尝试 gp_resource_group_move_timeout
指定的毫秒数。如果目标进程在 gp_resource_group_queuing_timeout
时间内无法处理移动请求,数据库会返回错误信息。pg_resgroup_move_query()
被取消,但目标进程已经获得了所有插槽空之前,segment 进程将不会移动到新组,目标进程将保留插槽。这种不一致的状态将在事务结束时或目标进程在同一事务中调度的任何下一个命令中修复。移动查询后,无法保证目标资源组中当前运行的查询不会超过该组内存配额。在这种情况下,目标资源组中一个或多个正在运行的查询可能会失败,包括移动的查询。可通过预留足够的资源组全局共享内存,以尽量减少这种情况发生的可能性。