如何指定表组的主副本所在的 Zone ?

【 使用环境 】线上环境
【 使用版本 】OceanBase_CE_V4.3.2.1
【问题描述】
image

我将系统中 具有业务关联的多个表放入同一个表组,而且这些也是核心业务表,负载比普通表要高不少。
如上图所示,我希望将表组 z2 下的数据表的主副本全部挪到 Zone 3。

image

然而,哪怕这个时候 Zone 3 没有一个表组分布,哪怕 Zone 3 的 表分区数量也少,但 z2 表组就是死活赖在 Zone 2,而不会被自动负载均衡到 Zone 3。

请问,OB 分区负载均衡的算法大概是怎样实现的呢 ?
如何才能按照自己的意愿,将指定表组的主副本转移到指定 Zone 呢 ?



https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001052198
ob有transfer功能 ,可以参考一下
https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001050184

OceanBase 数据库当前版本仅支持租户级别的 Primary Zone,不再支持表级、DB 级、Table Group 级配置 Primary Zone。如果创建租户时未指定 primary_zone ,默认填写为 RANDOM ,表示各个 Zone 优先级相同。

https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001049926

我们的表组 SHARDING 都是 'NONE'

所有分区与表组中 table_id 最小的表的分区聚集在同一个LS

请问该如何理解这个话呢?如果表组中 table_id 最小的表在哪个 LS,其他表也会全部迁移到该 LS 吗?

如果我 表组 中有 10个表,它们的 table_id 都 > 100,都位于 LS 2

我之后再将一个数据表 t_min 加入该表组,t_mintable_id 假设是 1 (也就是表组中它最小),位于 LS 1,那么其他 10 个表的主副本也都会迁移到 LS 1,是吗 ?

如果是这样的话,那我就可以将一个 table_id 更小且位于 Zone 3 的表也加入该表组,来触发该表组的主副本迁移到 Zone 3。

4.x版本负载均衡模块无法直接操纵分区分布,而是需要先对LS(Log Stream,日志流)的数量和leader进行均衡,然后才能在日志流分布基础上进行分区均衡。需要注意,分区均衡仅针对用户表和全局索引。

关于分区表的Leader分布,OceanBase数据库的Leader分布并非简单地根据节点平均分配。在OceanBase集群中,Leader的分布受到多种因素的影响,包括但不限于负载均衡策略、分区策略以及系统健康状况等。OceanBase设计有负载均衡模块,该模块旨在优化资源使用并确保数据访问的高效性。

  1. 默认分布:默认情况下,OceanBase会尝试通过其内置的负载均衡策略来自动管理Leader的分布,以达到数据和负载在各个节点之间的均衡。这意味着虽然不保证绝对的“平均”,但系统会动态调整以接近最优分布。
  2. 自定义分配规则:虽然直接自定义Leader分配规则的功能不是直接暴露给用户的,但您可以通过影响分区策略间接影响Leader的分布。例如,通过精心设计分区键和分区函数,可以在一定程度上引导数据(及相应的Leader)倾向于分布在特定的节点或区域。此外,OceanBase支持的分区类型(如Range、List、Hash等)能够灵活地根据业务需求组织数据,间接影响Leader的分布格局。
  3. 负载均衡与调整:在V4.3.1版本中,OceanBase采用的日志流(Log Stream, LS)架构,副本以日志流为粒度分布,每个日志流承载多个分区。负载均衡主要集中在LS层面,先实现LS的均衡,进而影响其上的分区分布。这意味着,虽然直接干预每个分区Leader的分配较为复杂,但通过运维操作和配置调整,可以促进整个集群的负载更加均衡。

综上所述,分区表的Leader分布不是简单地基于节点平均分配,但OceanBase提供了机制来确保整体的负载均衡和优化数据分布。如果您有特定的分布需求或遇到分布不均的问题,建议查阅官方文档关于负载均衡和分区策略的部分,或者发帖提问

租户内均衡

https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001053047

租户间均衡

OB为多租户架构,每个租户拥有自己的资源池,资源单位为unit,包含CPU、内存、磁盘等规格。租户间的均衡即集群级的unit均衡。

1 个赞

但是,从实践来看,这个负载均衡机制似乎并不是太能实现负载的均衡。

我创建了几个表组,这几个表组里的表都是核心业务表,尤其是 z2z3,这两个表组里的表都是CPU负载、磁盘IO 较高的表,但是 OB 却将它们放在同一个 Zone,导致 OCP 触发了负载超限的告警。

-- 查询指定 Zone 的 LEADER 分布,以及 table_id
SELECT zone, table_name, tablegroup_name, MIN(table_id) AS table_id
FROM
  oceanbase.DBA_OB_TABLE_LOCATIONS 
WHERE
  database_name = 'db_name' 
  AND role = 'LEADER'
  AND zone = 'zone3'
  AND table_type='USER TABLE'
  GROUP BY zone, table_name
  ORDER BY zone, table_id;

通过这种方式,我已经解决了这个问题。

1、Table Group 的 Sharding 属性为 NONE 的表 自成一个均衡组 Table Group 下所有分区都分布在一个日志流上,表会按 Table Group 中 table_id 最小的表对应的分区分布对齐聚集在同一个 LS
2、如果在建表前,Table Group 中已存在用户表,后续新建的表会按 Table Group 中 table_id 最小的用户表对应的分区分布对齐。
3、 分区数量均衡的查询方法
SELECT svr_ip,svr_port,ls_id,count(*) FROM oceanbase.CDB_OB_TABLE_LOCATIONS WHERE tenant_id=xxx AND role=‘leader’ AND table_type=‘USER TABLE’ GROUP BY svr_ip,svr_port,ls_id;
分区磁盘均衡的查询方法
SELECT a.svr_ip,a.svr_port,b.ls_id,sum(data_size)/1024/1024/1024 as total_data_size FROM oceanbase.CDB_OB_TABLET_REPLICAS a, oceanbase.CDB_OB_TABLE_LOCATIONS b WHERE a.tenant_id=b.tenant_id AND a.svr_ip=b.svr_ip AND a.svr_port=b.svr_port AND a.tablet_id=b.tablet_id AND b.role=‘leader’ AND b.table_type=‘USER TABLE’ AND a.tenant_id=xxxx GROUP BY svr_ip,svr_port,ls_id;

4.2 版本 默认情况下调整表分组后等 2 小时负载均衡机制才会启动。有

租户参数 partition_balance_schedule_interval,默认值 2 小时。改到 几分钟可以快一点做均衡。看看是不是这个原因

和这个没关系哦,这个参数对我们来说是已知的,都是等到它负载均衡完毕后看结果的。
非常感谢您和大家的热心回复。