了解或使用过 OceanBase 的朋友都知道 “多租户”这一概念,OceanBase 的租户类似于传统数据库实例,比如 OceanBase 支持 MySQL 兼容模式的租户,站在客户端的角度,使用一个 MySQL 兼容模式的租户,就类似于使用一个普通的 MySQL 数据库实例。
OceanBase 4.3 版本在已有的多租户架构基础上,新增了功能——租户克隆。
本文将向大家介绍租户克隆的作用和使用。
背景
当我们需要使用 OceanBase 数据库时,会在一台或多台机器上拉起 OceanBase 进程,这些进程会组成 OceanBase 集群。
在这个集群中,我们可以创建出需要的租户。
单个 OceanBase 集群中可以创建出多个租户,租户间互相隔离。
如下图所示,在 OceanBase 的系统租户下执行该克隆语句,就可以对指定的源租户快速克隆出一个新租户。
新克隆租户在初始时刻包含的数据,就是源租户在语句执行时刻的一个快照。
租户克隆操作可以快速把源租户的元数据信息,拷贝一份,给到新克隆租户来使用。初始时刻,新克隆租户访问的是和源租户完全相同的物理宏块(宏块,就是上图中画的 Macro Block,是 OceanBase 中基础的数据存储单元)。因为克隆过程只拷贝了元数据,而不是拷贝数据,所以克隆操作可以快速完成。
该新克隆租户与源租户是两个独立的租户,他们之间保持了 OceanBase 一直以来的租户隔离特性,存在严格的数据隔离和资源隔离。新克隆租户的任何数据改动,都不会影响到源租户;源租户的数据改动,也不会影响到新克隆租户。新克隆租户与源租户具有自己独占的 CPU、内存、IOPS 资源,不相互抢占。
边学边练,效果拔群
这个功能的使用并不复杂,可以在 sys 租户下执行该克隆租户语句,对指定租户克隆出一个新租户:
CREATE TENANT new_tenant_name FROM source_tenant_name
WITH
RESOURCE_POOL [=] resource_pool_name,
UNIT [=] unit_config
该操作会根据源租户的 unit 分布情况,自动根据源租户的资源分布,为新租户创建出资源池,语句中的 resource_pool_name 标识资源池的名称,unit_config 标识新克隆租户的 resource pool 单个 unit 的规格。
正所谓 “纸上得来终觉浅,实践才能出真知”,强烈推荐大家点击下面的链接,根据在线体验页面左边的实验文档,亲手实践一把!
-
在线实验地址:https://www.oceanbase.com/demo/tenant-cloning
- 因为新租户初始状态下和源租户共享物理宏块,所以该克隆操作可以在一分钟左右快速完成,不会耽误大家的时间。
-
课后小测地址:https://exam.oceanbase.com/pre?did=-vUB27_psMExtDp26-VCp
-
大家完成课后小测,并在小测中上传实验截图,就可以从社区论坛中获取积分,并有机会获得抽奖的礼物。
-
坚持完成全部十期实验并通过结课考试的同学,还可以获得更多的积分奖励,并有机会获得 OBCA / OBCP 考试券。活动详情见:【积分 + 福利】OceanBase DBA 实战营(第二季)—— 体验再升级,好礼不停息!(7 月 14 日正式上线)
-
-
大家积极参与在线体验的实验,也是我能够持续为大家更新《DBA 实战营(第二季)》课程内容的动力!
- 大家如果都不来在线体验进行实验并完成课后小测的话,老大马上就要让我停更 OceanBase 社区的这些教程了……
除此以外,从 OB 4.3.0 版本开始,提供了主租户克隆的能力,OCP 社区版也进行了白屏化的产品适配,详见:OCP 官网文档。
有什么用?
如果大家在使用OceanBase的过程中遇到以下六种场景,租户克隆功能就会发挥它的价值。
场景一:报表任务
业务正在大促,卖得非常好,数据库运行平稳,但已处于满载状态。老板非常高兴,走到值班室,问技术团队要一个当前整体销售情况的报表。这时候,是选择冒着被“广进”的风险跑这个报表任务呢?还是选择对满脸期待的老板进行下预期管理呢?如果最终决定运行这个报表任务,当前这种情况下,又该开多大的并发度来跑大查询呢?
这时就可以利用租户克隆技术,快速基于生产租户克隆出一个新的报表租户,用新克隆出来的报表租户执行在线数据分析任务。
从 OceanBase 4.3 版本开始,支持行列混合存储,如果源租户是行列混存结构,克隆得到的新租户也是行列混存结构,可以良好支持 AP 负载。
场景二:快弹只读备租户
生产租户压力很大,同时内部运营系统,还会发送不那么确定的复杂查询负载。我们希望将这些来自内部的复杂查询负载,从生产租户上快速移走。
这时就可以利用租户克隆技术,快速基于生产租户克隆出一个新租户,让这个新租户作为生产租户的备租户。新租户会主动去生产租户上拉取日志,提供一个准实时的弱读服务。
如此一来,我们就可以将内部运营系统的复杂查询负载,快速转移到这个新的只读备租户中。
场景三:应用版本发布
不少应用的版本发布流程,都是先备份数据库,再更新应用版本。若这次应用版本发布出现问题,就用发布前的那个数据库备份,来还原数据库,最终实现整体版本发布的回退。备份数据库及用备份来恢复数据库,在数据量增大后都变得特别慢,导致整个版本发布过程执行时间特别长。
为了最小化版本发布对生产经营的影响,版本发布大多选择在凌晨进行,同时为了应对各类突发情况,整个版本发布过程时常需要相关同学现场值守。发版时间太长,一方面对业务生产经营产生影响,另一方面会让参与同学倍感疲倦。
租户克隆技术就可以在一定程度上解决这个问题。首先在版本正式发布前,可以基于生产租户克隆出一个预发测试租户,用这个预发测试租户来做最后的版本预发验证。版本发布的第一个流程,利用租户克隆技术,对生产租户克隆出一个小规格的临时备份租户。如果版本发布出现问题,就可以用这个临时备份租户,克隆出新的生产租户,来将数据库还原到版本发布之前。
因为租户克隆过程执行得很快,可以大幅度减少版本发布需要的执行时间。
场景四:数据库变更
这是 DBA 同学经常遇到的场景。比如研发同学找到你帮忙调整一个索引,并且告诉你这个变更在测试环境已经验证了很久了,绝对没问题。结果你一执行完索引变更,数据库 CPU 直接就飙到 100%,同时你发现,如果要将之前的索引重新构建出来,至少要 6 个小时。
这时,租户克隆机制就可以帮你解决这个问题,具体做法和应用版本发布的操作类似。
场景五:快速构建开发测试环境
当前我们的代码已经可以通过像 git 这样的工具被分支化管理,比如:你要做一个 bugfix,你可以快速拉出一个 bugfix 分支并在分支上编写代码。但是整个研发过程,不光是编码,还有测试验证。测试验证时常需要基于主干测试库,构建出一个分支测试库。主干测试库可能很大,进而构建这个分支测试库耗时很长,最终导致编码 5 分钟,搭建测试环境 5 个小时的情况。
租户克隆技术就可以解决这个问题,快速从主干测试租户中克隆一个分支测试租户,以支持分支的测试验证。
场景六:数据导出
部分时候,我们需要将数据库中大量的表数据按 csv 格式,导出到对象存储中,以供下游的大数据分析系统使用。由于担心影响线上生产服务,不敢开太大的导出并发,导致导出速度缓慢。
这时可以利用克隆功能,克隆出一个新的导出租户,用这个新的导出租户来执行数据导出任务,尽可能地减少对生产租户的影响。
实现方案
这段实现方案部分内容,对于感兴趣的同学,可能会是这篇文章的精华,可以加深对这个功能的理解。
为了避免大家不爱看这种很偏原理性的东西,这部分内容已经尽量进行了简化。对于不感兴趣的同学,也可以直接跳过,并不会影响功能的使用和运维。
租户克隆主要分成两个步骤:
-
为数据库租户创建快照备份。
- 为源数据库租户创建快照备份时,将源数据库租户的元数据拷贝出来,形成数据库租户快照的元数据,源数据库租户和数据库租户快照最初共同引用相同的宏块。直到源租户有新的数据写入,才产生出新的宏块,用于记录新写入的数据;用户为快照备份只需要付出快照独占的宏块占据的存储空间成本;
- 在源数据库租户创建快照的瞬间,部分已经提交的数据,可能还没有刷入宏块中,需要借助重做日志,将数据库租户快照整体恢复到一致性快照时间点。数据库租户快照的元数据中,会记录下需要的重做日志范围,同时递增对应日志文件的引用计数。
-
通过数据库租户快照克隆出新的数据库租户。
- 从数据库租户快照克隆创建新数据库租户时,会将快照的元数据拷贝出来,形成新克隆数据库租户的元数据,然后读取和回放快照创建时记录的关联重做日志,最终将新克隆出的数据库租户恢复到一致性快照时间点。
这里我再多啰嗦两句,主要是解释一下租户克隆与租户快照的关系:
第一句:该租户克隆操作,其内部动作是:创建租户快照,基于租户快照克隆租户,删除租户快照。
第二句:在租户克隆机制中,“租户快照” 实体只是短暂 的在租户克隆语句执行过程中存在。
在不久的将来,我们还会把 “租户快照” 的能力完全开放给用户。
前置准备
租户快照功能依赖于日志归档,需要客户在开启日志归档的条件下使用。
关键指标
租户实例规格,16c128g;单个 ls tablet 数量 50w;数据量 1TB;租户克隆预期时间 2min30s 之内。
其他说明
-
克隆出来的新租户与源租户之间存在严格的数据隔离和资源隔离。新租户的任何数据改动,均不会影响到源租户,同时源租户的任何数据改动也不会影响到新租户;新租户与源租户之间不会相互抢占 CPU、内存等资源。
-
对于源租户与克隆出来的新租户,在初始状态下使用的是共享物理宏块,后续随着源租户与新租户各自的数据写入,两个租户的共享宏块逐渐减少,独占宏块逐渐增多,存储空间的占用也会逐步增加,需要及时关注 OBServer 节点上存储空间的占用情况。
-
租户克隆任务执行过程中,不能进行以下操作:
- 对源租户执行 Switchover 操作
- 通过修改源租户的
UNIT_NUM
个数或 Primary Zone 第一优先级进行租户扩缩容操作 - 对源租户执行增加副本、减少副本、调整副本分布等操作
- 对源租户手动执行 Transfer 操作
- 对源租户手动执行 Unit 迁移操作
- 对源租户执行升级操作
如果必须执行上述操作,您可以取消克隆任务后再执行
租户克隆性能测试数据
一、测试目标
- 50w tablet 8c64g 租户预期的克隆耗时;
- 克隆出来租户的性能和同规格普通创建出来的 租户一致;
- 对某个租户 1002 进行克隆之后,该租户 1002 的性能不变;
- 执行克隆操作对源租户性能的影响
二、环境搭建
1、机器规格:
32c 256G * 3
数据盘- 800G
clog --500G
observer.log --500G
2、环境搭建
lsblk
mkdir obdata
mkdir 4
parted -s /dev/nvme1n1 mklabel gpt
parted -s /dev/nvme1n1 mkpart primary 0% 98%
mkfs.ext4 /dev/nvme1n1p1
mount /dev/nvme1n1p1 /data/0
parted -s /dev/nvme3n1 mklabel gpt
parted -s /dev/nvme3n1 mkpart primary 0% 98%
mkfs.ext4 /dev/nvme3n1p1
mount /dev/nvme3n1p1 /data/obdata
parted -s /dev/nvme2n1 mklabel gpt
parted -s /dev/nvme2n1 mkpart primary 0% 98%
mkfs.ext4 /dev/nvme2n1p1
mount /dev/nvme2n1p1 /data/4
3、测试版本
observer (OceanBase 4.3.0.0)
REVISION: 1-dbddb05096c7165316a8ac199d8a8c857571f671
BUILD_BRANCH: HEAD
BUILD_TIME: Jan 23 2024 15:20:09
BUILD_FLAGS: RelWithDebInfo
BUILD_INFO: jenkins-oceanbase_build_master_7u-B20496
三、测试结果
1、租户克隆预期耗时
测试场景
- 原租户和克隆租户规格均为:8c 64G
- 工具:sysbench
- 数据量:50W tablet
./sysbench --test=lua/test.lua --mysql --host=123.456.789.000 --oltp_table_size=100 --max-time=300 --report-interval=3 --max-requests=0 --num-threads=16 --mysql-user=uroot@ddl_8_mysql --mysql-db=test --mysql-port=2828 --db-ps-mode=disable --mysql-ignore-errors=2006,2013,6002,6001,4012,1213,1020,1205,4038,30006,24761,25402,24756 --oltp-tables-count=100 --oltp-dist-type=uniform --oltp_auto_inc=prepare
测试步骤
- 建租户 → 开启归档 → 导入数据 → 执行克隆
测试结果
create tenant clone_tenant1 from mysql_tenant with RESOURCE_POOL = clone_pool_1,unit = primary_unit;
Query OK, 0 rows affected (1 min 42.039 sec)
2、克隆对租户性能的影响
测试场景
- 原租户和目标租户规格均为8c 64g
- 工具:bmsql(未经过调优)
- 数据:1000 warehouses
- 并发线程:1000
- runMins = 5
测试步骤
- 建租户 → 开启归档 → 装载数据 → 建索引 → 合并
- 对原租户运行测试
- 对原租户再跑一次测试(测试期间克隆租户)克隆时间 (1 min 56.096 sec)
- 对克隆租户运行测试
- 对原租户运行测试
测试结果
测试对象 | 结果 |
---|---|
原租户 | Measured tpmC (NewOrders) = 42924.97 tpmTOTAL = 95521.57 |
原租户(测试期间发生过克隆) | Measured tpmC (NewOrders) = 42674.26 Measured tpmTOTAL = 94747.83 |
克隆租户 | Measured tpmC (NewOrders) = 42061.48 Measured tpmTOTAL = 93640.05 |
原租户(完成过克隆) | Measured tpmC (NewOrders) = 42335.9 Measured tpmTOTAL = 93861.98 |
结论:
- 克隆出来租户的性能和同规格普通创建出来的租户基本一致;
- 对某个租户进行克隆之后,该租户性能无明显变化;
- 执行克隆操作对源租户性能影响不大。