【leader角色tablet分布不均】2-2-2 拓扑下创建副本集表或者分区表,leader角色tablet都分布primary zone的同一个observer

【 使用环境 】测试环境
【 OB or 其他组件 】OB
【 使用版本 】4.3.5
【问题描述】集群从1-1-1通过 ob-operator 扩容到2-2-2 拓扑后,在新建租户下不断创建副本集表或者分区表,leader角色tablet都始终分布primary zone的同一个observer,其 LS_ID 为0,非用户创建
【复现路径】通过 ob-operator 扩容成功之后,apply -f tenant.yaml,再连接 obproxy 创建分区表
【期望】租户设置的leader zone是zone1,期望新创建的tablet的 leader LS 能均衡分配在 zone1 的 observer1或者observer2,或者用户可自己指定,这样可以均衡利用两个observer的资源
【原始问题】【leader角色tablet分布不均】3个zone、每个zone两个observer拓扑下创建副本集表或者分区表,leader角色tablet都分布primary zone的同一个observer
【相关日志】https://upfile.live/zh-cn/files/d144f690

创建租户:

apiVersion: oceanbase.oceanbase.com/v1alpha1
kind: OBTenant
metadata:
  name: tenant-test-0
  namespace: oceanbase
spec:
  obcluster: vsmongo
  tenantName: tenant_test_0
  unitNum: 2
  charset: utf8mb4
  connectWhiteList: '%'
  forceDelete: true
  credentials:
    root: root-password
#    standbyRo: t1-ro
  pools:
    - zone: zone1
      type:
        name: Full
        replica: 1
        isActive: true
      priority: 3
      resource:
        maxCPU: 13
        minCPU: 13
        memorySize: 24Gi
        maxIops: 9223372036
        minIops: 9223372036
        iopsWeight: 2
        logDiskSize: 72Gi
    - zone: zone2
      type:
        name: Full
        replica: 1
        isActive: true
      priority: 2
      resource:
        maxCPU: 13
        minCPU: 13
        memorySize: 24Gi
        maxIops: 9223372036
        minIops: 9223372036
        iopsWeight: 2
        logDiskSize: 72Gi
    - zone: zone3
      type:
        name: Full
        replica: 1
        isActive: true
      priority: 1
      resource:
        maxCPU: 13
        minCPU: 13
        memorySize: 24Gi
        maxIops: 9223372036
        minIops: 9223372036
        iopsWeight: 2
        logDiskSize: 72Gi

创建分区表:

for i := 0; i < 1000; i++ {
		createDatabaseSQL := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", flg.DBName)
		if _, err := db.Exec(createDatabaseSQL); err != nil {
			fmt.Printf("Failed to create db: %v, sql: %s\n", err, createDatabaseSQL)
			return err
		}

		// 生成字段定义
		fields := []string{"id INT PRIMARY KEY"}
		for i := 0; i < flg.FieldCount; i++ {
			fields = append(fields, fmt.Sprintf("f%d VARCHAR(%d)", i+1, 255))
		}
		columns := strings.Join(fields, ", ")

		// 创建表SQL
		createSQL := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (%s) DUPLICATE_SCOPE = 'cluster' partition by hash(id + 1) partitions 4;", fmt.Sprintf("%s_auto_%d", flg.TableName, i), columns)
		_, err := db.Exec(createSQL)
		if err != nil {
			return err
		}
	}

分区表拓扑信息:

2 个赞

可以了解下均衡策略:
数据负载均衡最佳实践-OceanBase

2 个赞

你创建表的语句发一下 看看

1 个赞

这样创建的分区表:

...
CREATE TABLE IF NOT EXISTS test.vsmongo_auto_97 (id INT PRIMARY KEY, f1 VARCHAR(255), f2 VARCHAR(255), f3 VARCHAR(255), f4 VARCHAR(255), f5 VARCHAR(255)) DUPLICATE_SCOPE = 'cluster' partition by hash(id + 1) partitions 4;
CREATE TABLE IF NOT EXISTS test.vsmongo_auto_98 (id INT PRIMARY KEY, f1 VARCHAR(255), f2 VARCHAR(255), f3 VARCHAR(255), f4 VARCHAR(255), f5 VARCHAR(255)) DUPLICATE_SCOPE = 'cluster' partition by hash(id + 1) partitions 4;
CREATE TABLE IF NOT EXISTS test.vsmongo_auto_99 (id INT PRIMARY KEY, f1 VARCHAR(255), f2 VARCHAR(255), f3 VARCHAR(255), f4 VARCHAR(255), f5 VARCHAR(255)) DUPLICATE_SCOPE = 'cluster' partition by hash(id + 1) partitions 4;
1 个赞

根据表名查一下 这个信息
SELECT A.duplicate_scope, B.flag
FROM oceanbase.DBA_OB_TABLE_LOCATIONS AS A JOIN oceanbase.DBA_OB_LS AS B ON A.ls_id = B.ls_id
WHERE A.table_name = ‘tbl1’
AND A.role = ‘LEADER’;

1 个赞

全是NONE

1 个赞

这个信息 在业务租户下 查看

1 个赞

租户下:

我的目的是想对比一下ob与mongo创建库、表的分配策略:

  1. mongo在分片集群钟创建database时,会根据每个分片的数据量选择一个数据量最小的分片作为priamy shard,然后创建的表如果没有设置分片键的话,这个新表一定是分配到这个primary shard的。如果开启hash分片键的话,数据分成多个chunk,均匀分布到每个分片,在写场景能合理利用每个分片的能力;
  2. 然后我想测试并了解一下ob这边创建副本表、分区表的策略机制。理论上ob应该也有一种或多种分配策略(比如数据量、负载、tablet数量)将 leader tablet 绑定在 primary zone 的每一个 observer LS。当前看起来都绑定在一个 observer,可能那块有问题,没有符合预期的效果

【期望】租户设置的leader zone是zone1,期望新创建的tablet的 leader LS 能均衡分配在 zone1 的 observer1或者observer2,或者用户可自己指定,这样可以均衡利用两个observer的资源
你的这个期望目前是已经实现了的。
查询分区leader时候多加一个条件 table_id>50000;

sys租户下查看 根据表查一下这个信息
select * from oceanbase.CDB_OB_TABLE_LOCATIONS where table_name = “dup_t1”;


所有的复制表会被包括在一个广播日志流中。广播日志流每个zone只有一个。但是会在非该日志流所在每一个租户unit下创建只读副本。
意思是你的两台observer都有副本,但是广播日志流只会在一个节点上,所以leader也集中在一个节点上。
如果想测试负载均衡,创建几个普通分区表即可。
https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000001499574

我创建的租户 primary_zone 选项是 zone1;zone2;zone3,那么这个租户所有创建的tablet对应的leader基本上都会在 zone1,其他两个只读 follower在zone2、zone3。副本这块没有问题。

但是现在的问题是: zone1有两个observer,他们俩资源对等,新建1000个分区表的 leader 角色 tablet 只在同一个 observer

image

这个实现我没有找到相关文档,我这个建表要怎么改哈?
CREATE TABLE IF NOT EXISTS test.vsmongo_auto_99 (id INT PRIMARY KEY, f1 VARCHAR(255), f2 VARCHAR(255), f3 VARCHAR(255), f4 VARCHAR(255), f5 VARCHAR(255)) DUPLICATE_SCOPE = ‘cluster’ partition by hash(id + 1) partitions 4;

把复制表相关的DUPLICATE_SCOPE删掉
https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003378475

2 个赞

学习了

确实符合预期了 :+1: :+1:

另外有个小疑惑:从上面去掉DUPLICATE_SCOPE创建分区表这个步骤来看,分区表默认就是复制表。那分区表必须是复制表吧,应该不能创建不是复制的分区表吧?

“创建分区表这个步骤来看,分区表默认就是复制表” 这句话啥意思 如果分区表是复制表,表下所有分区也都是复制表

应该是我对普通表的理解有问题,ob的普通表就是租户的LOCALITY属性决定。我以前认为它还只有一个LS,所以给它加上了 DUPLICATE_SCOPE= ‘cluster’

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

可以多看看官方的文档 系统学习一下ob