首批通过分布式安全可靠测评,为关键业务系统打造
租户分区数上限计算方式
更新时间:2025-11-19 03:26
从 OceanBase 数据库 V2.1 版本开始,对内存使用做了按租户拆分,目前大部分内存模块已经拆分到各个租户下面,这样便于计算每个分区的内存开销,同时也可实现根据租户内存计算理论分区数上限,避免无限制创建分区导致租户内存爆掉。
如何计算分区数上限
首先,我们需要计算出租户可用内存上限,计算方式如下:
统计每个租户在各个 Server 上的分区数量。
select svr_ip, svr_port, table_id >> 40 as tenant_id, count(*) as part_num from (select * from __all_virtual_clog_stat group by table_id, partition_idx) as vt group by svr_ip, table_id >> 40 order by svr_ip, tenant_id;统计每个租户在每个 Server 上的内存上限。
select u.svr_ip, u.svr_port, t.tenant_id, uc.max_memory, p.replica_type from __all_unit u, __All_resource_pool p, __all_tenant t, __all_unit_config uc where p.resource_pool_id = u.resource_pool_id and t.tenant_id = p.tenant_id and p.unit_config_id = uc.unit_config_id;查询每个 Server 的
memstore_limit_percentage。select svr_ip, svr_port, name, value from __all_virtual_sys_parameter_stat where name = 'memstore_limit_percentage';对于 F 类型的 unit,需要为 memstore 预留内存。
- 租户可用内存上限 = 租户总内存上限 * (1-memstore_limit_percentage)。
对于 L 类型的 unit,无需为 memstore 预留内存。
- 租户可用内存上限 = 租户总内存上限。
接下来,可以利用上面的租户可用内存来计算理论分区数上限值:
没有使用 Partition Group 的版本(V2.2 之前的版本不支持 Partition Group),设租户当前分区总数为 num,根据如下计算公式进行评估:
所需总内存 = 128K * num + max(1000, num/10) * 400K
需要确保算出来的值不能超过租户可用内存上限,否则需调大租户内存规格。 此外,还需要确保:
- num >= 1 万 时,同时有写入的分区比例不超过 10%。
- num < 1 万时,同时有写入的分区总数不超过 1000 个。
OceanBase 数据 V2.2 及之后的版本,如果使用了 Partition Group 功能,由于一个 Partition Group 中可能包含很多 partition,其内存开销要比普通的单个分区大,我们按每个 Partition Group 预留 (528KB+1MB)内存来计算,根据系统已有的 Partition Group 数量计算需要为 Partition Group 预留的内存。
OceanBase 数据库 V3.x 和 V4.x 版本的最大限制
| 类型 | OceanBase 数据库 V3.x 版本最大限制 | OceanBase 数据库 V4.x 版本最大限制 |
|---|---|---|
| OceanBase 数据库的分区副本数 | 建议值为 5w;说明: OceanBase 数据库分区总数受隐藏参数 _max_partition_cnt_per_server 影响,V2.2.77 版本默认值为 10w;V3.2.3 版本默认值为 50w; 但是超过 5w 会存在稳定性问题,后续需要对所有部署的集群做这个配置的修改。SYS 租户大概需要使用 4000 分区,所以用户可用的所有租户最大为46000。 |
无严格限制,详细内容参见:使用限制 不再有 _max_partition_cnt_per_server 配置,主要取决于租户的资源,每个 OceanBase 数据库节点的分区副本数可根据租户内存大小来预估,1G 内存约支持约 2 万 tablet。 |
| 租户分区数 | 租户的分区总数限制是根据租户的资源来计算的,计算公式如下: partition_num = (max_memory - memstore_limit) / partition_mem + max_memory:租户最大内存 + memstore_limit:MEMStore 内存 + partition_mem:每个分区占用的内存(系统按这个大小来估算分区总数并加以限制) partition_mem 的计算公式 - 不使用 PG:partition_mem = 128K(static) +1/10 * 400K(dynamic) =168K,假定 1/10 的分区处于 active 状态 - 使用 PG:partition_mem = 128K(static) + 1/10 * (400+1024) K = 270K,按照 512K 来估算 PG 中的 partition 如果 memstore_limit_percentage 配置的是 50%,假设没有使用 PG; partition_num = (0.5 * 租户内存) / (128K + 400K * 1/n) 假设租户内存 32G,n = 10; 最大分区数为10w个。远大于节点的 5w 个建议。 所以,内存 >16G, 一般可以不用考虑租户的分区限制,瓶颈在集群上。 | 每个 OceanBase 数据库节点的分区副本数可根据租户内存大小来预估,1G 内存约支持约 2 万 tablet (内存的计算需要扣除 meta 租户,2 万 tablet 受变量 _max_tablet_cnt_per_gb 控制)。MEMORY 资源:内存资源不支持共享,Meta 租户和用户租户的内存资源需要隔离。默认 Meta 租户占整体租户规格的 10%。 为了保证 Meta 租户正常运行,Meta 租户内存资源规格最小为 512M,不设最大值。整体租户内存规格减去 Meta 租户内存规格即为用户租户的内存规格。整体租户规格最小值为 1G。下面举例说明:
|
| 单表分区个数限制 | MySQL 模式:8192 个 | MySQL 模式:8192 个 |
版本升级注意事项
如果租户某个 unit 全部是 L 副本,那么该 unit 必须为 L 类型,否则不允许升级,升级脚本会执行该检查。 对于全部为 L 副本的 unit,如果创建时设定的是 Full 类型,那么计算租户可用内存时会为 memstore 预留相应比例的内存(根据
memstore_limit_percentage配置项的值),这样租户的可用内存会打折扣,升级之后很可能由于内存受限导致 L 副本无法工作(分不出内存),因此在升级脚本中添加了该检查。注意
RS 目前不支持直接修改 resource pool 的类型,需要通过 locality 变更来处理,先删除这样的 unit,再添加新的 L 类型 unit。
目前 V2.1 版本租户 unit 最小规格为 5G 内存,避免做了内存拆分之后太小的租户运行异常,升级脚本会执行该检查。
版本升级过程中,升级前置检查流程也会对分区数量所需内存进行检查,由于升级过程中可能会创建一些内部表,故检查时会在当前租户分区数量基础上额外加 512 个分区,检查内存是否足够,不足则升级流程报错,报错示例如下,其中会打印
tenant_id:
根据上节的计算方法,用租户当前的分区数量计算所需总内存,评估内存升级之后是否够用,若不够需要先给租户增加内存,或者将
memstore_limit_percentage配置项的值调小,直到足够为止。