【华为云MySQL技术专栏】TaurusDB多租户管理与资源隔离特性解读

举报
GaussDB 数据库 发表于 2024/11/29 14:39:28 2024/11/29
【摘要】 1. 技术背景SaaS(Software as a Service,软件即服务)在云上部署,可以将分散的计算存储资源集中利用,并让原来的用户都到云上来共享这些资源。云服务厂商为此提供了一种解决方案,一个实例可支持多个租户的数据存储与访问,降低了SaaS和租户的使用成本。基于此,云厂商还需要提供资源隔离的能力,以确保SaaS租户的数据安全。为了满足这个需求,多租户技术应运而生。该技术旨在解决如...

1. 技术背景

SaaS(Software as a Service,软件即服务)在云上部署,可以将分散的计算存储资源集中利用,并让原来的用户都到云上来共享这些资源。云服务厂商为此提供了一种解决方案,一个实例可支持多个租户的数据存储与访问,降低了SaaS和租户的使用成本。基于此,云厂商还需要提供资源隔离的能力,以确保SaaS租户的数据安全。

为了满足这个需求,多租户技术应运而生。该技术旨在解决如何在同一系统或组件下,让多个租户共享计算和存储资源的同时,确保各租户的数据隔离和资源隔离。

租户是一个逻辑概念,当一个企业或者组织在云平台注册账户后,平台就认为该账户是一个租户云服务厂商将以租户为基本单位来分配资源,并且确保这些资源相互独立。用户则是这些资源的使用者,一个租户可以有多个用户,每个用户都可以访问到该租户所分配到的资源。

以SaaS为例,通常SaaS服务提供商被视为一个租户。然而,当SaaS服务提供商面向多个不同客户时,这些客户同样应当被视作不同的租户。因此,为了有效管理和支持这些多租户环境,云计算供应商需要在其现有单租户实例配置的基础上,引入多租户的概念。

从广义上来看,多租户机制扩展了数据库实例能够服务的目标群体,使得单一实例能够同时服务于多个独立的客户或租户。而从狭义上来看,对于SaaS服务中的每一个租户而言,多租户架构不仅提高了资源利用率,还确保了各租户之间的良好隔离,即每个租户的数据和操作不会相互干扰,从而保障了服务的安全性和稳定性。

2. 概念简介

当前云上提供给租户管理的最小单元是数据库实例,即一个数据库实例服务于一个租户。然而,SaaS服务需要更灵活的租户管理方式,因此,TaurusDB推出了多租户管理及资源隔离功能,包括:

1)支持租户级数据隔离,确保不同租户只能访问自己的数据;

2)支持租户级资源隔离,通过以租户为单位的实例资源划分,允许各租户的资源配比可动态调整,既提高了系统的资源利用率,又能及时应对不同租户的业务高峰和波谷;

3)支持用户级资源隔离,通过以用户为单位的租户资源划分,实现了更细粒度的资源管理方案。

在多租环境下,我们是以“数据库”为粒度,来区分不同租户的数据。如图1所示,租户分为系统租户和普通租户。

图1 多租户管理概念图

每个实例在创建时都会默认拥有系统租户,该租户下的用户可以访问实例上的所有数据库,主要用于系统的管理和运维,这些用户也被称为系统用户。普通租户需要在系统租户下创建,其下的用户只能授权访问由该租户创建的数据库,无法访问其他租户的数据库,这类用户被称为普通用户。

此外,每个普通租户可以创建和管理多个用户数据库,但每个用户数据库只能属于一个普通租户。相比之下,系统租户可以管理所有数据库,包含普通租户创建的数据库,以及系统默认数据库,如mysql,sys,performance_schemainformation_schema等,这些数据库均属于系统租户的管理范畴。

3. 实现原理

3.1 数据隔离

在当前模式下,有多种方案可以实现数据隔离。

一是TaurusDB支持通过ACL语句来设置不同租户对数据库和表的访问权限,从而实现不同租户身份的数据隔离。此方案的优势在于不需要对内核进行修改,但限制在于不同租户无法拥有名称相同的数据库。

二是通过修改mysql.dbmysql.user系统表的结构,来记录数据库和用户所属的租户信息,从而保证不同租户之间能够创建相同的数据库名称,并且实现数据隔离。但是,此方案涉及到系统表的修改,对实例升级、其他依赖于系统表的功能兼容性不友好。

基于此,为实现各普通用户仅能访问到所属租户的数据库, TaurusDB提出了一个更为优化的解决方案。该方案新增多租系统表,用来记录当前实例的租户信息。在连接TaurusDB时,普通用户的登录名由“用户名@租户名”两部分构成。当前会话将保存对应的租户名,在创建数据库、用户或表空间时,将对各自的名称拼接租户名后缀后完成创建。当用户下一次登录时,TaurusDB会对所要访问的数据库、表空间等名称进行解析,得到所属的租户信息,并和当前会话的租户名称进行比较。

不同租户下数据库和用户的命名,如图2所示。

2 不同租户下数据库和用户的命名

最终,根据普通用户只能访问所属租户数据的约束逻辑,实现租户间的数据隔离。此方案不仅修改量小,并且在兼容性方面表现更加友好。

系统用户可以访问当前实例的所有数据库,普通用户只能访问所属租户下的数据库。

以图3为例,以系统租户的身份,创建数据库db1和db3,db1和db3只有系统租户才能访问。以普通租户A下的用户,创建数据库db1,db1存储的名字会自动调整为db1@tenantA;以普通租户B下的用户,创建数据库db2,db2的名称将自动调整为db2@tenantB。无论是系统用户或者普通用户,在查找数据库时,系统都会在数据库名(db)后面加上“@租户名”来寻找对应的数据库,从而确保不同租户只能访问自己租户名管理下的数据库数据。

3 数据隔离原理图

此外,在启用多租特性前,实例如果已经有部分存量的数据库(图3中的db2和db4),这些老版本的数据库db2和db4将默认属于系统租户。不过, TaurusDB支持将已存在的数据库所属租户修改为其他普通租户。如图2 中db2的所属租户可以从系统租户切换为租户A,db4的所属租户可以从系统租户切换为租户B,数据库与租户的映射关系将记录在系统表tenant_db中。

3.2 资源隔离

CPU的资源隔离是基于CGroup(Control Groups)[1,2]和Thread Pool技术实现。

CGroup作为一种资源隔离的机制,它允许用户根据需求,将一系列系统任务及其子任务整合到按资源划分等级的不同组内,为系统资源管理提供一个统一的框架。通过CGroup,用户可以限制、记录和优先分配任务组所使用的资源,从而有效地管理系统的性能和资源分配。

CGroup本质就是一个目录树,其中包含若干配置文件,用于配置当前层级的资源限额,并可以通过创建子目录的方式,把资源继续划分给到下一层级。值得注意的是,子目录分配的资源之和,不能超过父目录的资源配额。进程或者线程可以绑定到CGroup目录树的某一层级,从而让进程或线程受到绑定目录中的资源限制。

具体到本特性,核心的设计包含两个方面:

1)划分CGroup目录树

按照租户、用户、后台线程等不同类别的资源隔离需求设置目录树,每层目录下包含CPU.SharesCPU.Cfs_quota_us,Tasks等配置项,分别用于配置本层级可使用的最大CPU资源、最小CPU资源以及与本层级目录绑定的线程ID。

2)线程绑定到CGroup目录树节点

分为后台线程绑定和业务线程绑定,通过Thread Pool线程池的逻辑,将各个层级的CGroup目录和Thread Pool中的Worker Threads关联,这样,系统可以识别当前连接所属的租户/用户,并将其分配给已经绑定到对应CGroup目录的Worker Thread进行处理。

TaurusDB内部有一个专用的线程Main Listener,用来监听数据库的连接请求。当一旦收到一个新的请求时,该线程会将请求转发给默认的ThreadGroup,此ThreadGroup会解析并记录连接身份信息,并将此请求均匀地分配给其他的Listener线程。Listener线程负责监听连接请求,并根据连接身份将请求转发给对应ThreadGroup

TaurusDB中,每个用户都对应线程池中的一组ThreadGroup。当用户连接执行SQL时,由对应的ThreadGroup中的Worker Thead来执行,同时,这些ThreadGroup会与CGroup目录树中的特定目录进行绑定。

由于租户和用户是一对多的关系,一个用户只能属于一个租户,所以每个租户包含了多个ThreadGroupTaurusDB支持租户级和用户级的CPU资源隔离,如果设置了用户级的资源隔离,则会在用户所属租户的CGroup目录下,创建此用户的CGroup子目录。

ThreadGroup具体绑定在CGroup目录树上的哪个目录,需要根据“租户名、用户名以及是否设置了此用户的资源隔离”而定。如果设置了用户级的资源隔离,该用户对应的ThreadGroup会被绑定到此用户对应的CGroup目录上,否则该用户对应的ThreadGroup会被绑定到所属租户对应的CGroup目录上,并由租户的CGroup配置限制其资源使用。

CGroup目录分为三层,分别是进程层(process level)、租户层(tenant level)和用户层(user level),如图4所示。

图4 CGroup目录树结构

进程层用于区分后台线程和用户线程等,包括default、admin、others三个目录。

default目录用于绑定系统关键线程,此类线程(如主线程、连接监听线程、定时任务线程等)对时延敏感,必须及时获取到所需的CPU资。因此,将其放在根目录下,避免其他线程的“扰邻”影响。

admin目录用于绑定系统超级管理员的线程,即超级管理员访问TaurusDB时产生的前台线程将绑定到admin目录下,同样放在根目录下,确保不受其他线程的“扰邻”影响。

others目录用于绑定后台线程和租户线程,其中bg目录用于绑定后台线程,tenants目录用于绑定各租户线程,即系统租户或者普通用户访问TaurusDB时,产生的前台线程将绑定在tenants目录下。若需实现用户级资源隔离,还会进一步在tenants目录下创建consumer group子目录,以实现租户内部各用户间的资源划分。

3.3元数据管理

元数据管理将提供多个多租系统表,用于数据隔离和资源隔离;资源隔离所涉及到的元数据,包括租户信息、租户及其下用户的资源配置等,都将被保存在多租系统表中。TaurusDB内部的后台线程将定时把这些数据固化为CGroup目录树下的CPU.SharesCPU.Cfs_quota_us配置项。

由于tenants目录下的不同子目录对应不同租户和租户所属的用户,当Thread Pool创建Worker线程时,会将线程ID、租户、用户等信息传递给后台线程,由具有root权限的后台线程ID写入对应CGroup目录的Task文件中,与Task文件同一目录的CPU.SharesCPU.Cfs_quota_us配置项将对Task文件中保存的线程发挥作用,进而实现基于CGroup的资源隔离。

4. 业务场景/流程

4.1 数据隔离

使用系统租户下的管理员账号连接数据库,并创建多种资源配置信息,用于对租户资源进行限制。

CREATE resource_config cfg_1 MAX_CPU {max_cpu_val} MIN_CPU {min_cpu_val};
CREATE resource_config cfg_2 MAX_CPU {max_cpu_val} MIN_CPU {min_cpu_val};

使用系统租户下的管理员账号连接数据库,分别创建tenant_1和tenant_2个租户,且在创建租户时与指定的资源配置信息绑定。

CREATE tenant tenant_1 RESOURCE_CONFIG cfg_1;
CREATE tenant tenant_2 RESOURCE_CONFIG cfg_2;

创建租户tenant_1下的用户user1,tenant_2下的用户user2

CREATE USER 'user1@tenant_1'@'%' IDENTIFIED
 WITH mysql_native_password BY {pwssword};
GRANT priv ON *.* TO 'user1@tenant_1'@'%' WITH GRANT OPTION;

CREATE USER 'user2@tenant_2'@'%' IDENTIFIED
 WITH mysql_native_password BY {pwssword};
GRANT priv ON *.* TO 'user2@tenant_2'@'%' WITH GRANT OPTION;

创建成功后,通过“user1@tenant_1”账户连接数据库创建数据库test1

以相同的方式通过“user2@tenant_2”账户连接数据库,创建数据库test2。

对于系统用户root,能看到租户tenant_1和tenant_2下的数据库对于用户user1,只能看到数据库test1对于用户user2,只能看到数据库test2,具体效果如上图2所示

4.2 租户级资源隔离

tenant_1和tenant_2进行sysbench压测,对比不同租户下的CPU使用率。

sysbench
 --db-driver=mysql
  --mysql-host=<host> --mysql-port=<port>
   --mysql-user=user1@tenant_1
    --mysql-password=<password>
     --mysql-db=sbtest --table_size=25000 --tables=250
      --time=600 --range_selects=0 --skip-trx=1 --threads=128
       --percentile=95 --report-interval=1 oltp_read_only run

sysbench
 --db-driver=mysql
  --mysql-host=<host> --mysql-port=<port>
   --mysql-user=user1@tenant_2
    --mysql-password=<password>
     --mysql-db=sbtest --table_size=25000 --tables=250
      --time=600 --range_selects=0 --skip-trx=1 --threads=128
       --percentile=95 --report-interval=1 oltp_read_only run

结果图5所示,10:58-11:00对应租户tenant_1的结果,11:01-11:03对应租户tenant_2测试结果。

图5 租户级隔离指标对比图

结果显示,tenant_1相比tenant_2的CPU使用率,比例接近2:1;tenant_1相比tenant_2的QPS使用率,比例接近2:1。

4.3 用户级资源隔离

在此场景中,继续沿用创建的租户tenant_1,以及该租户下的用户user1和user2。接下来,通过租户tenant_1连接数据库,并创建两个资源消费组group1和group2。然后,将消费组group1绑定到用户user1,将消费组group2绑定到用户user2。

CALL dbms_resource_manager.create_consumer_group
('group1', 'comment');
CALL dbms_resource_manager.create_consumer_group
('group2', 'comment');
CALL dbms_resource_manager.set_consumer_group_mapping
('USER', 'user1', 'group1');
CALL dbms_resource_manager.set_consumer_group_mapping
('USER', 'user2', 'group2');

首先,创建一个资源计划plan1,并为其配置资源计划指令plan_directive_for_user1,该指令将plan1与group1进行关联。接着,再创建资源计划plan2,并为其配置资源计划指令plan_directive_for_user2,plan_directive_for_user2将plan2与group2关联。

CALL dbms_resource_manager.create_plan
('plan1', 'comment')
CALL dbms_resource_manager.create_plan_directive
('plan1', 'group1', 'plan_directive_for_user1', 10, 40);
CALL dbms_resource_manager.create_plan_directive
('plan1', 'group2', 'plan_directive_for_user2', 10, 40);

启用资源计划

CALL dbms_resource_manager.set_resource_manager_plan('plan1');

对租户tenant_1下的用户user1和user2执行sysbench测试,对比不同用户下的CPU使用率和QPS。

sysbench
 --db-driver=mysql
  --mysql-host=<host> --mysql-port=<port>
   --mysql-user=user1@tenant_1
    --mysql-password=<password>
     --mysql-db=sbtest --table_size=25000 --tables=250
      --time=600 --range_selects=0 --skip-trx=1 --threads=128
       --percentile=95 --report-interval=1 oltp_read_only run
sysbench
 --db-driver=mysql
  --mysql-host=<host> --mysql-port=<port>
   --mysql-user=user2@tenant_1
    --mysql-password=<password>
     --mysql-db=sbtest --table_size=25000 --tables=250
      --time=600 --range_selects=0 --skip-trx=1 --threads=128
       --percentile=95 --report-interval=1 oltp_read_only run

结果下图6所示,11:15-11:17对应租户tenant_1下user1的测试结果,11:19-11:21对应租户tenant_1下user2的测试结果。

6 用户级隔离指标对比图

结果显示,user1相比user2的CPU使用率,比例接近1:1。user1相比user2的QPS使用率,比例接近1:1。

5. 总结

本文从实现原理和业务场景两方面介绍了TaurusDB的多租户管理与资源隔离特性。该特性不仅支持租户间数据隔离,支持租户级某个租户下的用户级的资源隔离,为使用者更加灵活和安全的资源配置和管理方案。

如果想进一步了解此特性,可以参考官方文档:多租户管理与资源隔离 https://support.huaweicloud.cn/kerneldesc-gaussdbformysql/gaussdbformysql_20_0053.html

6. 参考

[1] Linux管理之CGroup简介:https://tech.meituan.com/2015/03/31/cgroups.html

[2] https://kubernetes.io/docs/concepts/architecture/cgroups/

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。