更新时间:2024-09-06 GMT+08:00

多租户管理与资源隔离

本文介绍了GaussDB(for MySQL)提供的多租户数据隔离以及资源隔离的相关语法和使用说明。

功能简介

GaussDB(for MySQL)提供的多租户管理功能,让数据库能够为其多个租户服务,提高数据库资源利用率。租户间实现数据隔离,不同租户能访问自己的数据。支持租户级资源隔离和用户级资源隔离,资源隔离能够避免浪费和性能扰邻。支持资源动态调整,能够及时应对不同租户或用户的业务高峰和波谷。

多租户管理功能的原理图如下:

图1 多租户管理原理图

常用概念

表1所示为租户级和用户级的相关术语。

表1 租户级和用户级相关术语

所属层级

相关术语

租户级

租户(Tenant)

租户的层级结构在数据库实例之下,在数据库与用户之上。租户是为了数据隔离、资源隔离提出的概念,实际访问数据库还是需要以用户的身份去访问。

租户分为系统租户和普通租户。

  • 系统租户(sys_tenant)

    系统租户是为了适配原有模式下用户的使用,原有数据库实例中的用户默认属于系统租户,也可以称为系统用户。当通过系统租户下的用户连接数据库时,若该用户拥有对应的数据库实例访问权限,即可访问所有租户下的数据库实例。

  • 普通租户(user_tenant)
    普通租户需要在系统租户下进行创建,普通租户下的数据库实例与用户完全隔离,无法互相访问,并且普通租户无法访问系统租户下的数据库实例。在进行CPU资源调度时,根据min_cpu是否大于0将普通租户分为独占型租户和共享型租户。
    • 独占型租户:min_cpu>0,需要保证任何时刻的CPU资源不小于min_cpu。
    • 共享型租户:min_cpu=0。系统优先保证独占租户的资源请求,然后将剩余资源配给共享租户。同时,系统保留一部分CPU份额(对应参数mt_shared_cpu_reserved)给共享租户,保证共享租户不会饿死。独占型租户和共享型租户可以通过调整min_cpu的值进行相互转换。

资源配置(resource_config)

为了实现租户级资源隔离所提出的概念,一个resource_config描述了对应租户下能够使用的资源。当前仅支持对CPU资源进行隔离以及调度。

用户级

用户的层级结构在数据库实例和租户之下,同一个租户可以拥有多个用户。

图2 用户级资源配置关系图

资源消费组(consumer_group)

同一个资源配置下的用户集合。多个用户可以归属到同1个资源消费组,同一个资源消费组下的用户共享资源配置。

资源计划指令(plan_directive)

具体的资源配置。1个资源计划指令绑定1个资源消费组,描述当前消费组的具体资源配置。

资源计划(plan)

资源配置的集合。1个资源计划绑定1个或多个资源计划指令。启用/禁用资源计划可使对应的资源计划指令生效/失效。

使用须知

  • 多租户管理与资源隔离功能支持租户级数据隔离、租户级CPU资源隔离、用户级CPU资源隔离。
  • 多租户管理与资源隔离功能需要GaussDB(for MySQL)实例内核版本为2.0.54.240600及以上。
  • 开启多租户管理与资源隔离前必须开启thread pool功能。
  • 开启多租户管理与资源隔离功能前,要求实例中的数据库名称和用户名称不能包含@字符。
  • Serverless不支持多租户管理与资源隔离功能。
  • 租户跨实例迁移:
    开启多租户管理与资源隔离功能后,DRS迁移可以迁移所有租户下的数据,但DRS不会同步多租元数据,故租户信息不会被同步到目标端。如果需要迁移某个租户到另一个实例,需要遵循以下步骤:
    1. 目标端需要使用具备多租特性的实例,首先在目标端手动创建租户。
    2. 使用DRS数据同步功能创建库级同步任务(如果源端和目标端租户名有改动,则这里需要改动目标端库名)。

    3. 进行同步。
  • Binlog:

    目前Binlog没有实现租户隔离,如果允许普通租户拉取Binlog会破坏租户间数据隔离,因此当前禁止普通租户下的用户拉取Binlog。

    本特性引入的租户和资源隔离相关接口,记录的Binlog为row格式。在binlog_format不为row的情况下,通过Binlog进行同步,将无法同步租户及资源配置信息。

  • Proxy:
    • 支持带Proxy使用,带Proxy使用时show processlist显示结果是节点级别。
    • 因HTAP标准版和轻量版不支持带@字符的数据库,普通租户下的数据库迁移到该类HTAP引擎时会更改目标端库名,但Proxy的自动行存/列存引流功能要求源端和目标端的库名一致,因此普通租户创建的数据库将无法使用Proxy的自动行存/列存引流功能。
  • 备份恢复:

    恢复已打开多租开关的多租实例数据到新实例,未开启多租开关下,新实例不支持创建带@的用户和DB。

  • 兼容性:
    • 先开启后关闭多租开关,创建DB和用户时,名称中不能包含@字符。
    • 普通租户下,数据库名称最大长度由64降低为50,用户名称最大长度由32降低为20。
    • 当前仅支持普通租户访问information_schema,其他系统库暂不开放给普通租户。
    • 普通租户不支持tablespace相关语法。

开启多租户模式

  1. 登录管理控制台
  2. 单击管理控制台左上角的,选择区域和项目。
  3. 在页面左上角单击,选择数据库 > 云数据库 GaussDB(for MySQL)
  4. 在实例管理页面,单击目标实例名称,进入基本信息页面。
  5. 在实例信息区域,单击多租户隔离右侧,在弹框中单击“确认”,开启多租户隔离功能。

    开启多租户隔离前要求存量的数据库名称和用户名称不能包含@字符,否则会开启失败。

资源管理

资源配置(resource_config)和租户是一对多的关系,当某一租户绑定此资源配置时便可限制此租户下用户使用的CPU资源。

  • 创建资源配置
    CREATE resource_config config_name MAX_CPU [=] {max_cpu_value} [MIN_CPU [=] {min_cpu_value}];
  • 更新资源配置
    ALTER resource_config config_name MAX_CPU [=] {max_cpu_value} [MIN_CPU [=] {min_cpu_value}];
  • 删除资源配置
    DROP resource_config config_name;
  • 查看资源配置
    SELECT * FROM information_schema.DBA_RSRC_TENANT_RESOURCE_CONFIGS;
  • 仅在root用户下可使用创建、更新、删除资源管理接口。
  • 参数说明:
    • config_name: 资源配置名称。最大长度为64,仅支持包含大写字母、小写字母、数字或下划线。
    • MAX_CPU:该资源配置能够使用的CPU的最大数量,最小值为0.1,最大值为mt_flavor_cpu。粒度0.1U。
    • MIN_CPU:该资源配置能够使用的CPU的最小数量,为可选项。默认等于MAX_CPU,最小值为0,最大值不超过MAX_CPU。粒度为0.1U。如果设置为0,表示该租户为共享租户,如果大于0则为独占租户。
  • 更新resource_config时,如果该resource_config已经绑定租户,且更新后MIN_CPU值大于原有的MIN_CPU值,则需要校验修改后的值是否满足资源约束,否则不做资源约束校验。
  • 删除resource_config时,若租户正在使用该资源配置,则无法进行删除操作。
  • 实际使用中,共享租户的资源分配不依赖MAX_CPU,是随机争夺资源的。
  • CPU争抢时,租户间资源分配会尽量按照租户的MIN_CPU分配资源,但存在一定的误差,误差通常在1U以内。
  • 开启租户特性后的实例性能比同等规格实例性能低,实际使用中多个租户抢占资源时,性能表现将更低。

租户管理

创建租户时,需要绑定已经创建的资源配置(resource_config),以此限制该租户下用户使用的CPU资源。

  • 创建租户
    CREATE TENANT tenant_name RESOURCE_CONFIG config_name [COMMENT [=] 'comment_string'];
  • 更改租户
    ALTER TENANT tenant_name RESOURCE_CONFIG config_name [COMMENT [=] 'comment_string'];
  • 删除租户
    DROP TENANT tenant_name;
  • 查看租户
    SELECT * FROM information_schema.DBA_RSRC_TENANT;
  • 仅在root用户下可使用创建、更改、删除租户接口。
  • 创建租户
    • tenant_name长度不超过10个字符,仅支持包含小写字母、数字或下划线_。
    • 创建租户会进行资源约束检查,需要保证所有租户的资源配置中MIN_CPU之和满足资源约束。
  • 更改租户resource_config
    • 如果新绑定的resource_config的MIN_CPU值大于等于原有resource_config的MIN_CPU值时,会进行资源约束检查,需要保证所有租户的资源配置中MIN_CPU之和满足资源约束。
    • 独占租户如果新绑定的resource_config的MIN_CPU值为0,会导致租户变为共享租户,将同时删除租户关联的用户级资源隔离相关的元数据。
  • 删除租户
    • 需要保证租户下的DB和用户已经被删除,否则,无法删除租户。
    • 同时将删除租户关联的用户级资源隔离相关的配置。

用户管理

开启多租模式后,用户分为系统租户下的用户和普通租户下的用户。存量的用户均属于系统租户,新创的用户根据接口语义属于系统租户或者普通租户。

  • 在系统租户下管理用户

    创建用户

    创建系统租户下的用户:

    CREATE user [IF NOT EXISTS] user_name@host;

    创建普通租户下的用户:

    CREATE user [IF NOT EXISTS] 'user_name@tenant_name'@host; 

    重命名用户

    重命名系统租户下的用户:

    RENAME USER user_from@host1 TO user_to@host2; 

    重命名普通租户下的用户:

    RENAME USER 'user_from@tenant_name'@host1 TO 'user_to@tenant_name'@host2; 

    删除用户

    删除系统租户下的用户:

    DROP USER [IF EXISTS] user_name@host; 

    删除普通租户下的用户:

    DROP USER [IF EXISTS] 'user_name@tenant_name'@host;

    授权用户

    为用户user1@tenant_1授予租户tenant_1下的priv_type权限:

    GRANT priv_type ON *.* to 'user_1@tenant_1'@'%' with grant option;

    查看权限:

    SHOW grants for 'user_1@tenant_1';
  • 在普通租户下管理用户

    创建用户

    创建当前租户下的用户:

    CREATE user [IF NOT EXISTS] user_name@host; 

    重命名用户

    RENAME USER user_from@host1 TO user_to@host2;

    删除用户

    DROP USER [IF EXISTS] user_name@host;

    授权用户

    为用户user1授予当前租户下的priv_type权限:

    GRANT priv_type ON *.* to 'user_1'@'%' with grant option;

    查看权限:

    SHOW grants for 'user_1';
  • 在系统租户下创建或删除普通租户下的用户时,需要以user_name@tenant_name的方式对用户进行操作。
  • 普通租户下的用户名称的长度被限制为不超过20个字符。
  • 租户内不可以创建部分特殊用户:mysql.sys, mysql.session, mysql.infoschema以及参数rds_reserved_users中保留的用户。
  • 普通租户下的用户重命名时,需要保证user_from和user_to中的tenane_name相同,如不相同,则接口返错。
  • 特性开关关闭时,无法重命名普通租户下的用户。

数据库管理

数据库分为系统租户下的数据库和普通租户下的数据库。系统租户可以访问所有数据库,普通租户只能访问属于自己的数据库。

  • 在系统租户下管理数据库

    创建数据库

    创建系统租户的数据库:

    CREATE DATABASE [IF NOT EXISTS] `db_name`;

    创建普通租户的数据库:

    CREATE DATABASE [IF NOT EXISTS] `db_name@tanent_name`; 

    删除数据库

    删除系统租户的数据库:

    DROP DATABASE [IF EXISTS] `db_name`;

    删除普通租户的数据库:

    DROP DATABASE [IF EXISTS] `db_name@tanent_name`;
  • 在普通租户下管理数据库

    创建当前租户的DB:

    CREATE DATABASE [IF NOT EXISTS] 'db_name'; 

    删除当前租户的DB:

    DROP DATABASE [IF EXISTS] 'db_name';
  • 在系统租户下创建或删除普通租户下的DB时,需要以db_name@tenant_name的方式对DB进行操作。
  • 普通租户当前只支持INFORMATION_SCHEMA系统库的访问,PERFORMANCE_SCHEMA、SYS、MYSQL等系统库暂不允许普通租户访问。
  • 租户内不可以创建部分特殊DB:INFORMATION_SCHEMA, PERFORMANCE_SCHEMA, MYSQL, SYS, __recyclebin。
  • 存量数据库分配租户

    为保证兼容性,升级或者迁移到多租实例后,存量的DB默认属于系统租户,可以通过如下语法将存量的DB分配给租户。此外,对于已经开启多租特性后,系统租户创建的且未分配给普通租户的DB,也可通过如下语法分配数据库给对应租户。

    数据库分配

    将DB分配给租户名为tenant_name的普通租户

    ALTER DATABASE db_name TENANT = `tenant_name`;

    将DB回收到系统租户下

    ALTER DATABASE db_name TENANT = ``;

    查看映射关系

    SELECT * FROM information_schema.DBA_RSRC_TENANT_DB;
    • 仅在root用户下可使用数据库分配接口。
    • 如果DB是开启多租后创建的,以db_name@tenant_name格式命名的DB不允许分配调用数据库分配接口,接口会返错。
    • 如果tenant不存在,且不为空,数据库分配接口返错。
  • 通过租户下的用户连接数据库

    在系统租户下,原有连接方式不变。

    在普通租户下,指定用户时,需要以user_name@tenant_name的形式;指定DB时,支持db_name和db_name@tenant_name两种形式。

    mysql --host=**** -u user1@tenant_1 -D db1 -p pwssword;
    mysql --host=**** -u user1@tenant_1 -D db1@tenant_1 -p pwssword;

    连接成功后,该用户将受到对应租户下的资源限制。

用户级资源配置

租户下的用户默认共享当前租户的资源,若要进行用户级资源限制,请使用本节提供的用户级资源配置接口。

  • 资源消费组(consumer_group)管理

    通过租户下的用户连接数据库,进行资源消费组管理。

    创建消费组

    dbms_resource_manager.create_consumer_group (
       consumer_group     CHAR(128),
       comment            CHAR(2000));

    绑定消费组

    consumer_group参数不为'' ,此时将用户和consumer_group绑定。

    dbms_resource_manager.set_consumer_group_mapping (
       attribute        CHAR(128), 
       value            varbinary(128), 
       consumer_group   CHAR(128));

    解绑消费组

    consumer_group参数为'' ,此时将用户和consumer_group解绑。

    dbms_resource_manager.set_consumer_group_mapping (
       attribute        CHAR(128), 
       value            varbinary(128), 
       '');

    删除消费组

    dbms_resource_manager.delete_consumer_group (
        consumer_group   CHAR(128));

    查看消费组

    视图DBA_RSRC_CONSUMER_GROUPS记录了所属租户(tenant)和消费组(consumer_group)的关联关系。

    select * from information_schema.DBA_RSRC_CONSUMER_GROUPS;

    查看消费组映射

    视图DBA_RSRC_GROUP_MAPPINGS记录所属租户(tenant),用户(user)和消费组(consumer_group)的关联关系。

    select * from information_schema.DBA_RSRC_GROUP_MAPPINGS;
    • 对于共享租户,禁止使用创建、绑定、解绑、删除消费组接口。
    • 参数说明:

      consumer_group:资源消费组名称,仅支持包含大写字母、小写字母、数字或下划线_,在解绑消费组时可设置为''。

      comment:资源消费组说明,可为''。

      attribute:要添加或修改的映射属性,当前版本仅支持USER。

      value:要添加或修改的映射属性,当前版本仅支持用户名。

    • 删除consumer_group的时候会同步删除该资源消费组对应的plan_directive以及consumer_group_mapping条目。
    • 如果特性开关打开,删除用户时,也会删除此用户关联的消费组条目。
    • 如果特性开关打开,重命名用户时,也会同步更新此用户关联的消费组条目。
    • 重新打开特性,如果发现对应的用户已经无效,则自动删除这些无效的条目。
    • 如果特性开关关闭后,删除用户,再创建同名用户,后续打开特性,该用户对应的条目会被保留。

资源计划(plan)管理

通过租户下的用户连接数据库,进行资源计划管理。

  • 创建资源计划
    dbms_resource_manager.create_plan (
       plan_name         VARCHAR(128), 
       comment           VARCHAR(2000));
  • 启用资源计划
    dbms_resource_manager.set_resource_manager_plan(
        plan_name     VARCHAR(128));
  • 禁用资源计划
    dbms_resource_manager.set_resource_manager_plan ('');
  • 删除资源计划
    dbms_resource_manager.delete_plan (
        plan_name    VARCHAR(128));
  • 查看资源计划

    视图DBA_RSRC_PLANS记录当前计划(plan)的详细信息。

    SELECT * FROM information_schema.DBA_RSRC_PLANS;
    • 对于共享租户,禁止使用创建、启用、禁用、删除资源计划接口。
    • 参数说明:

      plan_name:资源计划名称,仅支持包含大写字母、小写字母、数字或下划线。

      comment:资源计划描述信息,可为''。

    • 若删除当前启用的资源计划,则会将当前启用的资源计划设置为空,同时删除对应的资源计划指令(plan_directive)。
    • plan默认可配置的最大数量为128,由参数mt_resource_plan_num控制。

资源计划指令(plan_directive)管理

通过租户下的用户连接数据库,进行资源计划指令管理。

  • 创建资源计划指令
    dbms_resource_manager.create_plan_directive (
       plan                    CHAR(128), 
       group_or_subplan        CHAR(128), 
       comment                 VARCHAR(2000), 
       mgmt_p1                 bigint(20),
       utilization_limit       bigint(20));
  • 更新资源计划指令
    dbms_resource_manager.update_plan_directive (
       plan                    CHAR(128), 
       group_or_subplan        CHAR(128), 
       new_comment             VARCHAR(2000), 
       new_mgmt_p1             bigint(20),
       new_utilization_limit   bigint(20));
  • 删除资源计划指令
    dbms_resource_manager.delete_plan_directive (
        plan                   CHAR(128), 
        group_or_subplan       VARCHAR(128));
  • 查看资源计划指令

    DBA_RSRC_PLAN_DIRECTIVES记录计划(plan)、消费组(consumer_group)的关联关系,以及对应消费组(consumer_group)的资源配置。

    SELECT * FROM information_schema.DBA_RSRC_PLAN_DIRECTIVES;
    • 对于共享租户,禁止使用创建、更新、删除资源计划指令接口。
    • 参数说明:

      plan:plan的名称。

      group_or_subplan:consumer_group的名称。

      comment:资源计划指令的描述信息,可为''。

      mgmt_p1:在系统满负载情况下,承诺分配给本消费组的CPU占比,取值范围[0, 100],100表示使用租户100%的CPU。

      utilization_limit:指定消费组使用的CPU资源的上限,取值范围为 [1, 100]。100表示最大可使用租户全部CPU资源,如果取值为70则表示最大可使用租户 70%的CPU资源。

    • 删除正在启用的plan_directive, 将导致对应用户的资源配置失效。
    • 同一消费组下的用户使用的资源总和不超过当前消费组的资源限制。例如:同一租户下有用户user1和user2,user1和user2属于consumer_group1,consumer_group1的UTILIZATION_LIMIT为70;则user1和user2实际使用的CPU资源总和最大为当前租户70%的CPU资源。

清空用户级配置

通过租户下的用户连接数据库,清空当前租户下相关的资源配置数据,包括DBA_RSRC_CONSUMER_GROUPS、DBA_RSRC_GROUP_MAPPINGS、DBA_RSRC_PLAN_DIRECTIVES、DBA_RSRC_PLANS表中的数据。
dbms_resource_manager.clear_all_configs();

CPU使用率统计

  • 用户级CPU使用率

    新增information_schema.cpu_summary_by_user表显示当前租户下各用户的CPU使用信息,具体使用如下:

    SELECT * FROM information_schema.cpu_summary_by_user;
    • 需要提前为当前用户(user)配置消费组(consumer_group)。
    • 查询结果中的列名说明:

      TENANT_NAME:用户所属的租户名称。

      USER_NAME:用户名称。

      CPU_USAGE:用户CPU使用率,为用户实际使用的CPU占所在租户配置的MAX_CPU的比例。例如,当前租户的max_cpu为4U, 而用户实际用了2U, 那么CPU_USAGE为50%。

  • 租户级CPU使用率

    新增information_schema.cpu_summary_by_tenant表显示各租户的CPU使用信息,具体使用如下:

    SELECT * FROM information_schema.cpu_summary_by_tenant;

    查询结果中的列名说明:

    TENANT_NAME:租户名称。

    CPU_USAGE:租户CPU使用率,为租户实际使用的CPU占配置的MAX_CPU的占比。例如,当前租户的max_cpu为4U, 而租户实际用了2U, 那么CPU_USAGE为50%。