云上的 SaaS 服务商,往往提供的是多租户的服务。多个业务租户的数据库如果在一个单机数据库中做逻辑名字空间隔离,大小租户之间互相影响。如果每个业务租户使用一个独立的数据库,成本高,几十到上百套分散数据库环境,运维工作复杂,同时扩展性受限。
使用 OceanBase数据库内原生分布式多租户架构,可实现基于面向服务的多数据库资源整合,在保证隔离性和可用性的同时实现资源池化,而且大小租户可以独立扩缩容,可以为不同客户提供不同规格的实例,大幅提升资源利用率以及管理效率,同时帮助 SaaS 企业降低整体成本。经过大量的客户反馈和广泛案例实践统计,OceanBase 的资源整合方案能够帮助中型及以上企业降低 TCO 约 30%-50%。
点击查看 SaaS 多租户资源整合解决方案的更多信息 >>
相关案例
多点 DMall:微服务低成本升级系统经验总结
OceanBase 多租户特性介绍
多租户概念
租户是一个逻辑概念。在 OceanBase 数据库中,租户是资源分配的单位,是数据库对象管理和资源管理的基础,对于系统运维,尤其是对于云数据库的运维有着重要的影响。租户在一定程度上相当于传统数据库的"实例"概念。租户之间是完全隔离的。
在数据安全方面,OceanBase 数据库不允许跨租户的数据访问,以确保用户的数据资产没有被其他租户窃取的风险。在资源使用方面,OceanBase 数据库表现为租户"独占"其资源配额。总体上来说,租户(tenant)既是各类数据库对象的容器,又是资源(CPU、Memory、IO 等)的容器。
OceanBase 数据库通过租户实现资源隔离,让每个数据库服务的实例不感知其他实例的存在,并通过权限控制确保租户数据的安全性,配合 OceanBase 数据库强大的可扩展性,能够提供安全、灵活的 DBaaS 服务。
OceanBase 数据库采用了单集群多租户设计,天然支持云数据库架构,支持公有云、私有云、混合云等多种部署形式。
租户和资源池
租户是集群之上的递进概念,OceanBase 数据库采用了多租户架构。多租户架构适用于资源整合(Resource Consolidation)、SaaS 服务等场景,同时也降低了运维复杂度。
免费进行多租户创建的黑屏体验
集群偏向于部署层面的物理概念,是 Zone 和节点的集合,Zone 和节点具有部署地域(称为 Region)等属性;而租户则偏向于资源层面的逻辑概念,是在物理节点上划分的资源单元,可以指定其资源规格,包括 CPU、内存、日志盘空间、IOPS 等。
租户类似于传统数据库的数据库实例,租户通过资源池与资源关联,从而独占一定的资源配额,可以动态调整资源配额。在租户下可以创建 Database、表、用户等数据库对象。
要描述清楚租户的概念,首先需要描述清楚资源规格、资源单元(Unit)、资源池等前置概念。资源规格对应的视图是 DBA_OB_Unit_CONFIGS,资源池对应的视图是 DBA_OB_RESOURCE_POOLS,资源单元对应的视图是 DBA_OB_UnitS,租户对应的视图是 DBA_OB_TENANTS。
资源规格资源规格定义了常见物理资源项的大小,包括 CPU、内存、磁盘空间、IOPS 等。创建资源池时指定其资源规格,从而根据定义创建资源单元。
资源单元(Unit)Unit 是租户管理中非常重要的概念。OceanBase 按照 Unit 来管理物理资源,是 CPU、内存、存储空间、IOPS 等物理资源的集合。Unit 也是资源调度的基本单位,其具有节点、Zone、Region 等位置属性,节点是服务器的抽象,Zone 是机房的抽象,Region 是地域的抽象,通过调整 Unit 的位置属性从而调整租户的部署方式。
资源池每个 Unit 都归属于一个资源池,每个资源池由若干个 Unit 组成,资源池是资源分配的基本单位,同一个资源池内的各个 Unit 具有相同的资源规格,即该资源池内 Unit 的物理资源大小都相同。
如上图,展示了一个由 6 个 Unit 组成的资源池 a_pool,该资源池具有如下重要属性:
- ZONE_LIST:描述了该资源池中的 Unit 分布在哪些 Zone,本例为 ZONE_LIST=‘zone1,zone2,zone3’。
- UNIT_NUM:描述了 ZONE_LIST 中每个 Zone 中的 Unit 个数,本例为 UNIT_NUM=2。
- UNIT_CONFIG_ID:描述了该资源池关联的资源规格,从而决定该资源池中每个 Unit 的物理资源大小,包括 CPU、内存、日志盘空间、IOPS 等。
通过 Unit 的概念,我们将 OceanBase 数据库的物理概念和逻辑概念进行了关联。每个租户有若干 Unit ,分布于若干 Zone 的若干节点上。而每个节点上分布有若干个 Unit ,这些 Unit 归属于不同租户。概括的讲:集群由节点组成,节点是 Unit 的容器。租户由 Unit 组成,Unit 是数据库对象的容器。
创建租户时通过设置 RESOURCE_POOL_LIST,可以指定该租户关联到的资源池,从而该租户拥有指定资源池的 Unit。例如:设置租户 a 的 RESOURCE_POOL_LIST=(‘a_pool’),其部署图如下:
该租户部署于 3 个 Zone,每个 Zone 有 2 个 Unit,可以通过调整 a_pool 的 UNIT_CONFIG_ID:描述了该资源池关联的资源规格,从而决定该资源池中每个 UNIT_CONFIG_ID 参数来动态调整租户的物理资源。
还可以通过调整 Unit 在同一个 Zone 内不同节点的分布(称为 Unit 迁移),从而达到 Zone 内不同节点间的负载均衡。节点故障时通过将其上的 Unit 迁移到同 Zone 内其他节点上,从而达到自动容灾恢复的目的。通过调整 Unit 在不同 Zone 的分布(变更租户的 Locality 属性),从而调整租户的部署模式,例如 “同城三中心”、“两地三中心”、“三地五中心” 等,从而具备不同的容灾等级。
多租户间的隔离性
很多人好奇 Oceanbase 怎么实现多租户之间的隔离。其实租户就像一个容器,这套容器里包含了 table,database,user 等逻辑对象;也包含了分给这个租户的内存,cpu,磁盘空间等物理资源。
逻辑对象隔离
不同租户的逻辑对象一定要处在不同的名字空间。逻辑对象实际是记录在内部表中的数据,为了保证名字空间独立,OceanBase 的每个租户都有自己一套完整的内部表,用于记录租户内逻辑对象的元数据信息,以此保证逻辑对象的隔离性。
物理资源隔离
物理资源可以分为两类:一类是弹性资源,比如CPU,磁盘带宽等;另一类是刚性资源,比如内存,磁盘空间等。弹性资源是可以抢占的,刚性资源一旦被占用,除非占有者主动释放,否则是无法抢占的。
从定义上来说,刚性资源无法超卖,必须要强隔离;弹性资源可以一定程度上超卖。无论是刚性资源还是弹性资源,在observer里都有租户级别的记账,通过视图可以方便地查看。
select * from DBA_OB_UNIT_CONFIGS;
+----------------+-----------------+---------+---------+-------------+---------------+----------+----------+-------------+
| unit_config_id | NAME | MAX_CPU | MIN_CPU | MEMORY_SIZE | LOG_DISK_SIZE | MAX_IOPS | MIN_IOPS | IOPS_WEIGHT |
+----------------+-----------------+---------+---------+-------------+---------------+----------+----------+-------------+
| 1 | sys_unit_config | 1 | 1 | 1073741824 | 2684354560 | 10000 | 10000 | 1 |
| 1001 | 1c1g | 1 | 1 | 1073741824 | 3221225472 | 10000 | 10000 | 1 |
| 1002 | 1c2g | 1 | 1 | 2147483648 | 6442450944 | 10000 | 10000 | 1 |
| 1003 | 2c2g | 2 | 2 | 2147483648 | 6442450944 | 20000 | 20000 | 2 |
| 1004 | 2c4g | 2 | 2 | 4294967296 | 12884901888 | 20000 | 20000 | 2 |
+----------------+-----------------+---------+---------+-------------+---------------+----------+----------+-------------+
内存和磁盘空间隔离
内存和磁盘空间的隔离机制比较简单,一旦超过配额,后续的资源申请就会失败。为了降低资源耗尽的情况,observer 内部会根据内存和磁盘空间的消耗情况控制写入的速度。
CPU 隔离
observer 最基础的 CPU 隔离是通过用户态调度,控制活跃线程数来实现的。每个租户有独立的线程池,线程池的规格是由租户规格和一些配置参数来决定的。
同时,observer 也支持配置 cgroup,来实现 CPU 的隔离优化。cgroup 能对线程的 CPU 使用率进行精准的限制,达到租户之间 CPU 强隔离的效果。
observer
├── tenant1
│ └── tasks
│ ├── thread1
│ ├── thread2
│ └── ...
├── tenant2
│ └── tasks
│ ├── thread1
│ ├── thread2
│ └── ...
└── other
CPU 隔离能力详见 OceanBase 社区里的这篇博客 《为什么资源隔离对HTAP至关重要》中 “OceanBase 资源隔离的实现效果” 部分。
磁盘 I/O 资源隔离
observer 内所有的 IO 都是异步 IO,并且是绕过 OS 的 direct IO,磁盘带宽的隔离是通过控制 observer 提交异步 IO 的时间间隔来实现的。具体的控制策略比较复杂,这里不作详述。
磁盘 IO 隔离能力详见 这篇博客 《OceanBase 4.1 解读:给用户足够灵活简单的IO隔离体验》。