作者:马顺华
从事运维管理工作多年,目前就职于某科技有限公司,熟悉运维自动化、OceanBase部署运维、MySQL 运维以及各种云平台技术和产品。并已获得OceanBase认证OBCA、OBCP 证书、OpenGauss社区认证结业证书。OceanBase & 墨天轮第二、三、四、五届技术征文大赛,多次获得 一、二、三 等奖,时常在墨天轮发布原创技术文章,并多次被首页推荐。
OceanBase 数据库具有多租户的特性,在集群层面实现了实例资源的池化。在 OceanBase 数据库中,每一个租户即一个实例(类比 MySQL instance)。租户与租户之间数据、权限、资源隔离,每个租户拥有自己独立的访问端口及 CPU、内存访问资源。
背景信息
OceanBase 数据库可以灵活的调整租户资源分配情况(CPU、内存),并且整个过程对上层业务透明。通过多租户机制,OceanBase 集群可以帮助用户高效的利用资源,在保证可用性和性能的前提下,优化成本,并且做到按照需求弹性扩容。
为了帮助您更容易的理解 OceanBase 多租户的概念。下面通过创建一个 oceanbase 租户的例子分步骤进行说明。
一、部署 OceanBase 4.0 数据库
1、部署 OceanBase 数据库,此处参考之前部署文档,不在重新部署了
部署 OceanBase 4.0 三节点
「OceanBase 征文」体验 all-in-one 部署 OceanBase 4.0 三节点环境
2、查看部署情况
[root@CAIP131 soft]# obd cluster list
+----------------------------------------------------------+
| Cluster List |
+----------+-----------------------------+-----------------+
| Name | Configuration Path | Status (Cached) |
+----------+-----------------------------+-----------------+
| obtest40 | /root/.obd/cluster/obtest40 | running |
+----------+-----------------------------+-----------------+
[root@CAIP131 soft]#
二、创建多租户
1、创建资源规格 unit config
在 OceanBase 数据库中,资源单元 unit 是一个租户使用 cpu、内存的最小逻辑单元,也是集群扩展和负载均衡的一个基本单位,在集群节点上下线,扩容、缩容时会动态调整资源单元在节点上的分布进而达到资源的使用均衡。而 unit config 则规定了一个 unit 需要使用的计算存储资源(包含内存、CPU 和 IO 等)的规格,是一个配置信息。
因为其分布式的架构,一个 oceanbase 租户可以在资源规格、资源池、副本类型,副本分布几个不同维度灵活定义,所以创建租户时,也需要按照 unit config > resource pool > tenant 的顺序进行创建和定义。
OceanBase 数据库在创建租户前,需要先确定租户的 unit config。您需要使用 sys 租户管理员,通过如下 SQL 语句来创建。
下面创建两个 unit config,分别为 unit1,unit2 并指定 cpu,内存,iops,磁盘使用的最大及最小阈值。
1.1 创建 unit1 资源单元
创建 unit1 资源单元的 cpu、内存使用大小为 2 C、4 G。IOPS、磁盘使用大小为 128、10 G。
obclient [oceanbase]> CREATE RESOURCE UNIT unit1 MAX_CPU 2, MIN_CPU 2, MEMORY_SIZE '4G', MAX_IOPS 1024, MIN_IOPS 1024, IOPS_WEIGHT 0, LOG_DISK_SIZE '10G';
Query OK, 0 rows affected (0.020 sec)
obclient [oceanbase]>
1.2 创建 unit2 资源单元
创建 unit2 资源单元的 cpu、内存使用大小为 4 C、8 G。IOPS、磁盘使用大小为128、20 G。
obclient [oceanbase]> CREATE RESOURCE UNIT unit2 MAX_CPU 2, MIN_CPU 2, MEMORY_SIZE '4G', MAX_IOPS 1024, MIN_IOPS 1024, IOPS_WEIGHT 0, LOG_DISK_SIZE '10G';
Query OK, 0 rows affected (0.010 sec)
obclient [oceanbase]>
更多资源单元的操作请参见 管理资源。
2、创建资源池关联 unit config
上面说到 unit config 是一组租户的配置规格信息,而 resource pool 则是租户的资源实体,所以在这一步我们需要创建一个 resource pool,并且与 unit config 关联起来。
创建两个不同的资源池 pool1、pool2,并为其分别指定到 unit1、unit2 上。实现资源单元与资源池的对应。unit_num 表示在一个副本中指定多少个 unit 单元(同一个租户中,一个节点上最多只能有一个 unit),ZONE_LIST 则指定租户在当前集群中在哪几个副本进行部署。
本例中考虑到是单节点集群,我们都指定单个 unit 和 zone list。创建 resource pool 需要保证有足够的资源剩余,如果资源不足,您可以先尝试删除已有的 test 租户,或者将已有租户的 unit config 调整到更小。如何调整请参见下节:修改租户配置,调整实例资源规格。
2.1 创建资源池 pool1
obclient [oceanbase]> CREATE RESOURCE POOL pool1 UNIT='unit1',UNIT_NUM=1,ZONE_LIST=('zone1','zone2','zone3');
Query OK, 0 rows affected (0.037 sec)
obclient [oceanbase]>
2.2 创建资源池 pool2
obclient [oceanbase]> CREATE RESOURCE POOL pool2 UNIT=‘unit2’,UNIT_NUM=1,ZONE_LIST=(‘zone1’,‘zone2’,‘zone3’);
注意
上面的例子针对的是单节点的集群环境,如果您的集群有3个节点,那么 zone_list 的值应该为 (‘zone1’,‘zone2’,‘zone3’),其中 zone 的名称需要根据您创建的情况具体填写。
3、根据创建的 resource pool 创建租户
在完成 unit config、resource pool 的创建,完成资源单元和资源池的对应后,就可以正常开始租户创建了。
本例中由于是单节点集群,所以我们只能创建单副本的租户。如果希望创建 3 副本的租户,OceanBase 集群至少需要 3 个节点。
3.1 创建一个单副本租户 test_tenant
定义一个名为 tenant1 的一个单副本租户,并规定字符集为 utf8mb4,使用 pool1 的资源池,ob_tcp_invited_nodes 是租户白名单定义,初始可以设置为 ‘%’,表示任意 ip 地址均可以访问,后期可以修改。
obclient [oceanbase]>
obclient [oceanbase]> CREATE TENANT IF NOT EXISTS test_tenant CHARSET='utf8mb4', ZONE_LIST=('zone1','zone2','zone3'), PRIMARY_ZONE='zone1;zone2,zone3', RESOURCE_POOL_LIST=('pool1');
Query OK, 0 rows affected (27.808 sec)
obclient [oceanbase]>
注意
上面的例子针对的是单节点的集群环境,只能创建单副本的租户。如果您的集群有 3 个节点,那么 zone_list 的值应该为(‘zone1’,‘zone2’,‘zone3’),PRIMARY_ZONE 则填写 ‘zone1;zone2;zone3’,表示租户的 leader 优先分布在 zone1,其次为 zone2。
3.2 创建一个单副本租户 test_tenant2
类似的,定义一个名为 tenant2 的一个 单副本的租户,并规定字符集为 utf8mb4,使用 pool2 的资源池。
obclient [oceanbase]> CREATE TENANT IF NOT EXISTS test_tenant2 CHARSET='utf8mb4', ZONE_LIST=('zone1','zone2','zone3'), PRIMARY_ZONE='zone1;zone2,zone3', RESOURCE_POOL_LIST=('pool2');
Query OK, 0 rows affected (29.072 sec)
obclient [oceanbase]>
4、再次查看租户
在完成 tenant1、tenant2 租户创建后,您可以通过查询 oceanbase.DBA_OB_TENANTS 视图来确认租户是否创建成功。
obclient [oceanbase]> SELECT * FROM DBA_OB_TENANTS;
+-----------+--------------+-------------+----------------------------+----------------------------+-------------------+---------------------------------------------+-------------------+--------------------+--------+---------------+--------+
| TENANT_ID | TENANT_NAME | TENANT_TYPE | CREATE_TIME | MODIFY_TIME | PRIMARY_ZONE | LOCALITY | PREVIOUS_LOCALITY | COMPATIBILITY_MODE | STATUS | IN_RECYCLEBIN | LOCKED |
+-----------+--------------+-------------+----------------------------+----------------------------+-------------------+---------------------------------------------+-------------------+--------------------+--------+---------------+--------+
| 1 | sys | SYS | 2023-03-19 11:25:51.144832 | 2023-03-19 11:25:51.144832 | RANDOM | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | MYSQL | NORMAL | NO | NO |
| 1001 | META$1002 | META | 2023-03-19 11:40:56.558805 | 2023-03-19 11:41:18.910203 | zone1;zone2,zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | MYSQL | NORMAL | NO | NO |
| 1002 | test_tenant | USER | 2023-03-19 11:40:56.567380 | 2023-03-19 11:41:18.964012 | zone1;zone2,zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | MYSQL | NORMAL | NO | NO |
| 1003 | META$1004 | META | 2023-03-19 11:42:51.527332 | 2023-03-19 11:43:14.542812 | zone1;zone2,zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | MYSQL | NORMAL | NO | NO |
| 1004 | test_tenant2 | USER | 2023-03-19 11:42:51.528401 | 2023-03-19 11:43:15.186037 | zone1;zone2,zone3 | FULL{1}@zone1, FULL{1}@zone2, FULL{1}@zone3 | NULL | MYSQL | NORMAL | NO | NO |
+-----------+--------------+-------------+----------------------------+----------------------------+-------------------+---------------------------------------------+-------------------+--------------------+--------+---------------+--------+
5 rows in set (0.003 sec)
obclient [oceanbase]>
上述操作确认完成后,您已完成在同一个集群下实现两个租户的创建过程。接下来便可以在租户里正常的进行数据库操作了。
三、登录数据库
1、租户 tenant1 创建表
使用新创建的 tenant1 进行登录,并创建一张(test)测试表。
obclient -hXXX.XX.XXX.106 -P2883 -uroot@test_tenant#obtest40 -p
obclient [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| oceanbase |
| information_schema |
| mysql |
| test |
+--------------------+
4 rows in set
obclient [(none)]> use test;
Database changed
obclient [test]>
obclient [test]> create table test_ob(id decimal(10,0),id2 decimal(10,0),id3 date,id4 date,id5 float,id6 float,id7 varchar(30),id8 varchar(300));
Query OK, 0 rows affected (0.222 sec)
obclient [test]> show tables;
+----------------+
| Tables_in_test |
+----------------+
| test_ob |
+----------------+
1 row in set (0.005 sec)
obclient [test]>
2、查看租户隔离性
使用 tenant2 租户进行登录,查看 tenant1 下的 test 库情况。
obclient -hXXX.XX.XXX.106 -P2883 -uroot@tenant2#ob_test -p
obclient [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| oceanbase |
| test |
+--------------------+
4 rows in set (0.044 sec)
obclient [(none)]>
obclient [(none)]> use test;
Database changed
obclient [test]> show tables;
Empty set (0.003 sec)
obclient [test]>
可以看到集群下两个租户的资源、数据、权限都是隔离的,您可以进行更多测试,体验 OceanBase 的租户隔离特性。
四、修改租户配置和调整实例资源规格
OceanBase 数据库可以灵活的对租户资源的 CPU,内存资源进行调整,并且在线生效,对业务透明。修改租户所占用的 CPU、内存大小,您仅需要调整租户所对应的 Unit Config,不需要对资源池或者租户进行调整。
1、查看租户资源
租户资源单元可通过系统视图 oceanbase.DBA_OB_UNIT_CONFIGS 进行查看。
obclient [oceanbase]> SELECT * FROM oceanbase.DBA_OB_UNIT_CONFIGS;
+----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+----------+----------+-------------+
| UNIT_CONFIG_ID | NAME | CREATE_TIME | MODIFY_TIME | MAX_CPU | MIN_CPU | MEMORY_SIZE | LOG_DISK_SIZE | MAX_IOPS | MIN_IOPS | IOPS_WEIGHT |
+----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+----------+----------+-------------+
| 1 | sys_unit_config | 2023-03-19 11:25:51.123458 | 2023-03-19 11:25:51.123458 | 1 | 1 | 2147483648 | 2147483648 | 10000 | 10000 | 1 |
| 1003 | unit1 | 2023-03-19 11:35:40.215273 | 2023-03-19 11:35:40.215273 | 1 | 1 | 2147483648 | 2147483648 | 1024 | 1024 | 0 |
| 1004 | unit2 | 2023-03-19 11:37:40.567729 | 2023-03-19 11:37:40.567729 | 1 | 1 | 2147483648 | 2147483648 | 1024 | 1024 | 0 |
+----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+----------+----------+-------------+
3 rows in set (0.001 sec)
obclient [oceanbase]>
查询结果显示,unit1 资源单元 CPU、内存使用的分别是 1 C,2 G。
2、修改租户资源
通过以下命令调整 unit1 资源单元 CPU、内存的使用大小为 2 c,4 G。
obclient [oceanbase]>
obclient [oceanbase]> ALTER resource unit unit1 max_cpu =2,min_cpu =2 ,memory_size ='4G';
Query OK, 0 rows affected (0.015 sec)
obclient [oceanbase]>
3、再次查看租户资源
obclient [oceanbase]> SELECT * FROM oceanbase.DBA_OB_UNIT_CONFIGS;
+----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+----------+----------+-------------+
| UNIT_CONFIG_ID | NAME | CREATE_TIME | MODIFY_TIME | MAX_CPU | MIN_CPU | MEMORY_SIZE | LOG_DISK_SIZE | MAX_IOPS | MIN_IOPS | IOPS_WEIGHT |
+----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+----------+----------+-------------+
| 1 | sys_unit_config | 2023-03-19 11:25:51.123458 | 2023-03-19 11:25:51.123458 | 1 | 1 | 2147483648 | 2147483648 | 10000 | 10000 | 1 |
| 1003 | unit1 | 2023-03-19 11:35:40.215273 | 2023-03-19 13:03:08.574968 | 2 | 2 | 4294967296 | 2147483648 | 1024 | 1024 | 0 |
| 1004 | unit2 | 2023-03-19 11:37:40.567729 | 2023-03-19 11:37:40.567729 | 1 | 1 | 2147483648 | 2147483648 | 1024 | 1024 | 0 |
+----------------+-----------------+----------------------------+----------------------------+---------+---------+-------------+---------------+----------+----------+-------------+
3 rows in set (0.001 sec)
obclient [oceanbase]>
如上所示,租户配置的调整是在线立即生效的,调整成功后,unit1 的 CPU、内存为 2 c,4 G。OceanBase 数据库通过内核的虚拟化技术,在变更配置后租户的 CPU 和内存资源可以立即生效,无需数据迁移或者切换,对业务无感知。
4、查看租户资源信息
通过查看 DBA_OB_UNITS 信息,您可以获取到资源单元、资源池、租户在集群里的对应信息及 CPU、内存信息。
obclient [oceanbase]> SELECT * FROM DBA_OB_UNITS;
+---------+-----------+--------+------------------+---------------+----------------------------+----------------------------+-------+--------------+----------+---------------------+-----------------------+----------------+----------------+---------+---------+-------------+---------------+----------+----------+-------------+
| UNIT_ID | TENANT_ID | STATUS | RESOURCE_POOL_ID | UNIT_GROUP_ID | CREATE_TIME | MODIFY_TIME | ZONE | SVR_IP | SVR_PORT | MIGRATE_FROM_SVR_IP | MIGRATE_FROM_SVR_PORT | MANUAL_MIGRATE | UNIT_CONFIG_ID | MAX_CPU | MIN_CPU | MEMORY_SIZE | LOG_DISK_SIZE | MAX_IOPS | MIN_IOPS | IOPS_WEIGHT |
+---------+-----------+--------+------------------+---------------+----------------------------+----------------------------+-------+--------------+----------+---------------------+-----------------------+----------------+----------------+---------+---------+-------------+---------------+----------+----------+-------------+
| 1 | 1 | ACTIVE | 1 | 1 | 2023-03-19 11:25:51.130920 | 2023-03-19 11:25:51.130920 | zone1 | 172.20.2.120 | 2882 | NULL | NULL | NULL | 1 | 1 | 1 | 2147483648 | 2147483648 | 10000 | 10000 | 1 |
| 2 | 1 | ACTIVE | 1 | 1 | 2023-03-19 11:25:51.133117 | 2023-03-19 11:25:51.133117 | zone2 | 172.20.2.121 | 2882 | NULL | NULL | NULL | 1 | 1 | 1 | 2147483648 | 2147483648 | 10000 | 10000 | 1 |
| 3 | 1 | ACTIVE | 1 | 1 | 2023-03-19 11:25:51.135849 | 2023-03-19 11:25:51.135849 | zone3 | 172.20.2.122 | 2882 | NULL | NULL | NULL | 1 | 1 | 1 | 2147483648 | 2147483648 | 10000 | 10000 | 1 |
| 1004 | 1006 | ACTIVE | 1004 | 1003 | 2023-03-19 11:38:04.600745 | 2023-03-19 12:08:40.389600 | zone1 | 172.20.2.120 | 2882 | NULL | NULL | NULL | 1003 | 2 | 2 | 4294967296 | 2147483648 | 1024 | 1024 | 0 |
| 1005 | 1006 | ACTIVE | 1004 | 1003 | 2023-03-19 11:38:04.603642 | 2023-03-19 12:08:40.389600 | zone2 | 172.20.2.121 | 2882 | NULL | NULL | NULL | 1003 | 2 | 2 | 4294967296 | 2147483648 | 1024 | 1024 | 0 |
| 1006 | 1006 | ACTIVE | 1004 | 1003 | 2023-03-19 11:38:04.606282 | 2023-03-19 12:08:40.389600 | zone3 | 172.20.2.122 | 2882 | NULL | NULL | NULL | 1003 | 2 | 2 | 4294967296 | 2147483648 | 1024 | 1024 | 0 |
| 1007 | 1010 | ACTIVE | 1005 | 1005 | 2023-03-19 11:38:15.676495 | 2023-03-19 12:53:59.887471 | zone1 | 172.20.2.120 | 2882 | NULL | NULL | NULL | 1004 | 1 | 1 | 2147483648 | 2147483648 | 1024 | 1024 | 0 |
| 1008 | 1010 | ACTIVE | 1005 | 1005 | 2023-03-19 11:38:15.678623 | 2023-03-19 12:53:59.888529 | zone2 | 172.20.2.121 | 2882 | NULL | NULL | NULL | 1004 | 1 | 1 | 2147483648 | 2147483648 | 1024 | 1024 | 0 |
| 1009 | 1010 | ACTIVE | 1005 | 1005 | 2023-03-19 11:38:15.684346 | 2023-03-19 12:53:59.888529 | zone3 | 172.20.2.122 | 2882 | NULL | NULL | NULL | 1004 | 1 | 1 | 2147483648 | 2147483648 | 1024 | 1024 | 0 |
+---------+-----------+--------+------------------+---------------+----------------------------+----------------------------+-------+--------------+----------+---------------------+-----------------------+----------------+----------------+---------+---------+-------------+---------------+----------+----------+-------------+
9 rows in set (0.014 sec)
obclient [oceanbase]>
报错
1、创建 unit1 资源单元
obclient [oceanbase]> CREATE RESOURCE UNIT unit1 MAX_CPU 2, MAX_MEMORY '4G', MAX_IOPS 128,MAX_DISK_SIZE '10G', MAX_SESSION_NUM 64, MIN_CPU=2, MIN_MEMORY='4G', MIN_IOPS=128;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your OceanBase version for the right syntax to use near 'MAX_MEMORY '4G', MAX_IOPS 128,MAX_DISK_SIZE '10G', MAX_SESSION_NUM 64, MIN_CPU=2' at line 1
obclient [oceanbase]>
obclient [oceanbase]> CREATE RESOURCE POOL pool1 UNIT='unit1',UNIT_NUM=1,ZONE_LIST=('zone1','zone2','zone3');
ERROR 4733 (HY000): zone 'zone1' resource not enough to hold 1 unit. You can check resource info by views: DBA_OB_UNITS, GV$OB_UNITS, GV$OB_SERVERS.
server '"172.20.2.120:2882"' LOG_DISK resource not enough
obclient [oceanbase]>
解决办法:资源不足,建议增加资源,或降低要创建的资源。
2、登录租户报错
[root@CAIP131 soft]# obclient -h127 -P2883 -uroot@test_tenant -p
Enter password:
ERROR 2002 (HY000): Can't connect to MySQL server on '127' (115)
解决办法:
创建租户,并指定允许任何客户端 IP 连接该租户。ob_tcp_invited_nodes=’%'
变量 ob_tcp_invited_nodes 用于指定租户连接的白名单,即允许哪些客户端 IP 连接该租户。如果不调整 ob_tcp_invited_nodes 的值,则默认租户的连接方式为只允许本机的 IP 连接数据库。
总结
OceanBase 数据库通过租户实现资源隔离,每个数据库服务的实例不感知其他实例的存在,并通过权限控制确保不同租户数据的安全性。租户在一定程度上相当于传统数据库的"实例"概念。租户之间是完全隔离的。在数据安全方面,不允许跨租户的数据访问,确保用户的数据资产没有被其他租户窃取的风险。