本文介绍了PolarDB PostgreSQL版的多租户资源配置功能。
概念
租户:在多租户中,租户是一个逻辑实体,它代表一个特定的数据和资源分配单元。租户的层级定位在集群之下,用户和数据库之上,它们之间的对应关系是多对一的,多个账户或数据库对应一个租户。租户与用户或数据库不是等同的概念。租户分为两大类:
系统租户:这是一个特殊的管理实体,通常只有一个。系统租户拥有对资源的优先访问权,能够占用普通租户的资源。当通过系统租户的用户连接到数据库时,如果该用户具备相应的集群访问权限,他们将能够访问所有租户下的集群。
普通租户:每个普通租户的资源是完全隔离的,租户之间无法相互访问。普通租户必须在系统租户的上下文中创建。
资源配置:资源配置涉及为特定的租户分配确定的资源(如CPU和内存)。这种配置方式允许高权限账户根据业务需求,为每个租户指定资源限制。
租户资源配置功能旨在限制单个或多个进程所使用的资源量。在PolarDB PostgreSQL版中,一个会话对应一个进程,且一个会话只能由一个用户登录到一个数据库。因此,进程、用户和数据库构成了进程的基本元素。系统允许将任意进程、用户、数据库映射到指定的租户,但一个进程只能属于一个租户,从而避免了资源使用量的重复统计。后台并行查询的子进程属于发起查询的进程所属的租户。因此基于进程的属性可以将资源限制分为三个维度:
进程:指用户主动发起的账户连接进程(会话进程),包括与进程相关的并行查询进程,但不包括系统辅助进程。
用户:指由同一用户发起的所有用户连接进程(会话进程),包括与进程相关的并行查询进程,但不包括系统辅助进程。
数据库:指访问同一数据库的所有用户连接进程(会话进程),包括与进程相关的并行查询进程,但不包括系统辅助进程。
由于系统进程特定的功能作用,默认情况下不对其资源使用进行限制。
前提条件
支持的PolarDB PostgreSQL版的版本如下:
PostgreSQL 14(内核小版本14.12.24.0及以上)。
您可通过如下语句查看PolarDB PostgreSQL版的内核小版本的版本号:
SELECT version();
参数说明
参数 | 描述 | 生效方式 |
polar_max_tenants | 最大租户数量,取值范围为0~65536,默认值为32。 | 重启生效。 |
polar_resource_manager.enable_resource_manager | 是否打开Resource Manager进程,进行内存限制和OOM预防,默认值为on。 | 重启生效。 |
polar_resource_manager.database_name | 存放租户元数据的数据库名称,默认值为 | 重启生效。 |
polar_resource_manager.stat_interval | 数据采集间隔时间,单位为毫秒,取值范围为10~10000。默认值为500 ms。 | RELOAD加载生效。
|
polar_resource_manager.total_mem_request_rate | 主动淘汰阈值,取值范围为50%~100%,默认值为80%。 | RELOAD加载生效。
|
polar_resource_manager.total_mem_limit_rate | 强制淘汰阈值,取值范围为50%~100%,默认值为95%。 | RELOAD加载生效。
|
polar_resource_manager.total_mem_limit_remain_size | 内存预留大小,取值范围为131072~INT_MAX(整型数据类型最大值),单位为KB,默认值为256000 KB。 | RELOAD加载生效。
|
polar_resource_manager.enable_log | 是否开启日志记录,取值范围如下:
| RELOAD加载生效。
|
使用说明
在使用多租户时,需要在polar_resource_manager.database_name
参数设置的数据库中安装插件polar_resource_manager
。
修改polar_resource_manager.database_name
设置的存放租户元数据的数据库名称,前期设定的多租户信息会失效。
CREATE EXTENSION polar_resource_manager;
创建资源配置
使用函数polar_create_resource_config
创建资源配置。
SELECT polar_resource_manager.polar_create_resource_config('resource_config_name');
其中,参数resource_config_name
需要符合数据库对象名限制,只支持64字节以内的名称,超过64字节后会自动截断。
删除资源配置
使用函数polar_drop_resource_config
删除资源配置。
SELECT polar_resource_manager.polar_drop_resource_config('resource_config_name');
修改资源配置
使用函数polar_alter_resource_config
修改资源配置的资源设置。
SELECT polar_resource_manager.polar_alter_resource_config('resource_config_name', 'config_name', value);
其中,支持的config_name
类型为:
cpu_rate_limit
,CPU限制值,单位为核心数。mem_limit
,内存限制值,单位是字节数。
创建租户
使用函数polar_create_tenant
创建租户。
SELECT polar_resource_manager.polar_create_tenant('tenant_name', 'resource_config_name');
其中:
tenant_name
参数需要符合数据库对象名限制,只支持64字节以内的名称,超过64字节后会自动截断。resource_config_name
资源配置需要优先建立,否则无法成功建立租户。
删除租户
使用函数polar_drop_tenant
删除租户。删除租户不会删除资源配置。
SELECT polar_resource_manager.polar_drop_tenant('tenant_name');
修改租户
使用函数polar_alter_tenant
修改租户。
SELECT polar_resource_manager.polar_alter_tenant('tenant_name', 'config_name', 'value');
其中,支持的config_name
类型为:
name
:租户名称。resource_config
:资源配置。
数据库归属租户
使用函数polar_tenant_add_database
将数据库归属到租户下。数据库只能归属到一个租户,否则无法归属成功。
SELECT polar_resource_manager.polar_tenant_add_database('tenant_name', 'database_name');
查看数据库和租户
使用polar_tenants_dbs
视图可以查看数据库及其所属的租户。
SELECT dbsname, tenantname FROM polar_resource_manager.polar_tenants_dbs;
用户归属租户
使用函数polar_tenant_add_user
将用户归属到租户下。用户只能归属到一个租户,否则无法归属成功。
SELECT polar_resource_manager.polar_tenant_add_user('tenant_name', 'user_name');
查看用户和租户
使用polar_tenants_users
视图可以查看用户及其所属的租户。
SELECT username, tenantname FROM polar_resource_manager.polar_tenants_users;
进程归属租户
使用函数polar_tenant_add_process
将进程归属到租户下。进程只能归属到一个租户,归属多个租户时,以最后一次为准。
SELECT polar_resource_manager.polar_tenant_add_process('tenant_name', pid);
查看租户资源情况
使用polar_all_resource_configs_detail
视图可以查看租户资源情况。
SELECT * FROM polar_resource_manager.polar_all_resource_configs_detail;
视图信息如下:
列名称 | 列类型 | 描述 |
tenantname | NAME | 租户名称。 |
resource_config_name | NAME | 资源配置名称。 |
num_processes | INTEGER | 进程数量。 |
num_idle_processes | INTEGER | idle进程数量。 |
num_active_processes | INTEGER | 活跃进程数量。 |
cpu_rate_limit | DOUBLE PRESISION | 租户CPU资源限制值。 |
per_process_cpu_rate_limit | DOUBLE PRESISION | 进程CPU限制值。 |
mem_limit | DOUBLE PRESISION | 内存限制值。 |
mem_usage | DOUBLE PRESISION | 内存使用量。 |
idle_processes_mem_usage | DOUBLE PRESISION | 空闲进程内存使用量。 |
active_processes_mem_usage | DOUBLE PRESISION | 活跃进程内存使用量。 |
cpu_usage_rate | DOUBLE PRESISION | CPU 使用率。 |
CPU资源管理
将进程、用户或者数据库添加到对应租户后,可以设置租户资源配置的CPU相关限制值。如果有可分配的后端子进程,则将后端子进程加入到发出并行查询的会话连接的租户中,让后端子进程和会话进程共享租户限制的资源。而当会话的并行查询执行完后,将后端子进程从租户中移除。此过程是一个动态增加和移除资源限制的过程。
CPU使用率限制
用于限制租户内对象的CPU使用率的最大值。当租户内的对象CPU使用率过大时,集群会进行限制,将CPU使用率降低,使其小于限制值。
通过polar_resource_manager.polar_alter_resource_config
设置cpu_rate_limit
,参数值为float类型。
参数值表示CPU的使用率(一段时间内的CPU使用时间比率)。例如,0.3表示使用一个核的30%,2表示使用2个核的能力。由于限制的是最大使用率,因此所有租户资源配置的cpu_limit和可以大于规格额T,即cpu_limit_A + cpu_limit_B + cpu_limit_C + ... >= T
。
内存资源管理
由于内存资源是刚性资源(swap off),无法像CPU可以动态限制,如果内存资源超过硬性限制,一般是通过中止进程来释放资源。租户的内存管理类似操作系统的OOM处理策略,相比于系统的整个数据库级别的OOM处理,这里只是一个租户级别的OOM处理。
内存使用量限制
通过polar_resource_manager.polar_alter_resource_config
来设置mem_limit
,参数值为float类型。与CPU使用率限制类似,用于限制内存使用的最大值,总的限制值可以大于等于规格额。包含以下两种策略:
主动资源超限管理:当总内存使用量大于主动淘汰阈值(
total_mem_request_rate
,默认值为80%)时,如果租户内存使用量大于此租户资源配置的内存limit量,则释放相应会话释放资源,并返回给用户内存超限的错误。直到内存使用量小于主动淘汰阈值。强制资源超限管理:为了避免集群内存过量使用,引起集群OOM,当总内存使用量大于强制淘汰阈值(
total_mem_limit_rate
,默认值为95%)时,遍历所有进程,释放相应会话的资源,并返回给用户内存超限的错误。
内存限制进行淘汰时,会中止用户会话并释放进程资源,可以通过发送SIGUSR2实现,向用户返回指定的OOM错误。如果存在并行查询的后台进程内存超限,会中止对应的用户进程。目前只对用户进程进行限制,系统后台进程目前属于系统租户,不会主动中止释放资源。