当遇到需要进行实时数据处理或大规模数据采集等场景(如:实时分析、日志收集),面临大量并发读写请求时,通过合理的Table Group选择与Shard Count制定可以实现数据分布和负载均衡,优化查询性能,从根本上提升数据的存储与计算效率。
Table Group与Shard Count设置建议
Hologres拥有灵活指定Shard和Table Group的特性,相比一些同类产品,具备更加灵活、易用、方便根据具体场景定制化Schema的能力,更加灵活应对业务需求,加上用户对自身业务的理解,能够比较高效、充分地利用Hologres高性能。推荐设置Table Group基本原则如下:
- 如无必要不建议新建Table Group,使用默认Table Group即可,规格详情请参见实例管理。 
- 对于大规格实例(大于256 Core)建议根据业务情况拆分多个Table Group,以使得业务使用更加均衡。 - 数据量过大,可新建独立较大Shard数的Table Group。 
- 表的数据量很小但数量很多,可独立出一个小Shard数的Table Group,减小Query启动开销。 
 
- 需要Join在一起的表(Local Join),必须放在同一个Table Group中。 
- 不要为每个表都设置一个Table Group。 
- 设置Shard数时,充分考虑Worker个数以及后续的扩容情况,尽量使得Shard数与Worker个数为倍数关系,以此让资源分配更加平衡。 
- 不支持修改已经创建Table Group的Shard数。如果您需要修改Shard数量,请新建Table Group。 
- 不建议Shard数设置过多,否则会导致无法分配计算资源,带来额外开销。Hologres从2.0版本开始,将会默认为单个Table Group的Shard数设置上限,并为整个实例设置Shard数上限,防止出现Shard数设置过多导致无法分配计算资源的问题,当超过约定的Shard总数上限时,会提示异常too many shards in this instance,具体Shard数上限规则如下: - 单个Table Group的Shard数上限=单个Table Group默认Shard数 * 2
- 实例总的Shard数上限=单个Table Group默认Shard数 * 8
- 如需调整单Table Group的Shard数上限和实例总Shard数上限,需要使用如下GUC参数取消Shard数上限,但是不建议使用,否则可能会因为Shard数过多导致无法分配计算资源。 - set hg_experimental_enable_shard_count_cap =off;
- Shard数上限一览表: - 实例规格 - 默认计算节点数 - 默认Shard数(适用于V0.10.31及以上版本) - 单个Table Group的shard count上限(适用于V2.0及以上版本) - 实例总的shard count上限(适用于V2.0及以上版本) - 32 Core - 2 - 20 - 40(20*2) - 160(20*8) - 64 Core - 4 - 40 - 80(40*2) - 320(40*8) - 96 Core - 6 - 60 - 120(60*2) - 480(60*8) - 128 Core - 8 - 80 - 160(80*2) - 640(80*8) - 160 Core - 10 - 80 - 160(80*2) - 640(80*8) - 192 Core - 12 - 80 - 160(80*2) - 640(80*8) - 256 Core - 16 - 120 - 240(120*2) - 960(120*8) - 384 Core - 24 - 160 - 320(160*2) - 1280(160*8) - 512 Core - 32 - 160 - 320(160*2) - 1280(160*8) - ...... - ...... - M - M*2 - M*8 
 
权限说明
- 新建Table Group、修改默认Table Group、删除Table Group、迁移表的Table Group(Resharding)需要实例的Superuser账号进行操作。使用Superuser账号执行如下语句为普通用户授予Superuser权限。 - --将“云账号ID”替换为实际用户名。如果是RAM用户,账号ID前需要添加“p4_”。 ALTER USER "云账号ID" SUPERUSER;
- 将新建表放入指定Table Group操作需要账号有新建表权限。 
获取Table Group元数据
- 查看默认Table Group - SELECT * FROM hologres.hg_table_group_properties WHERE tablegroup_name IN ( SELECT tablegroup_name FROM hologres.hg_table_group_properties WHERE property_key = 'is_default_tg' AND property_value = '1' );- 结果: 说明- 结果中is_default_tg代表为默认Table Group,shard_count代表Table Group对应的Shard数。 - tablegroup_name | property_key | property_value -----------------+------------------+---------------- test_tg_default | tg_version | 1 test_tg_default | table_num | 1 test_tg_default | is_default_tg | 1 test_tg_default | shard_count | 3 test_tg_default | replica_count | 1 test_tg_default | created_manually | 0 (6 rows)
- 查看当前数据库有哪些Table Group - SELECT tablegroup_name FROM hologres.hg_table_group_properties GROUP BY tablegroup_name;- 结果: - tablegroup_name ----------------- test_tg_default (1 row)
- 查看某Table Group设置的Shard数 - SELECT property_value AS shard_count FROM hologres.hg_table_group_properties WHERE property_key = 'shard_count' AND tablegroup_name ='<tg_name>';- 结果: - shard_count ------------- 3 (1 row)
- 查看某Table Group下有哪些表 - SELECT table_namespace AS schema_name, table_name FROM hologres.hg_table_properties WHERE property_key = 'table_group' AND property_value = '<tg_name>';- 结果: - schema_name | table_name -------------+------------ public | a (1 row)
- 查看某张表所在的Table Group - SELECT property_value AS table_group_name FROM hologres.hg_table_properties WHERE property_key = 'table_group' AND table_name = '<table_name>';- 结果: - table_group_name ------------------ test_tg_default (1 row)
新建Table Group
若是有新上的业务或者需要重新创建Table Group并指定新的Shard数,可以使用以下命令语句。
- 新建Table Group后,原来的表和数据还会在原Table Group中,不会默认迁移到新的Table Group中。 
- 需要将原来表和数据都迁移至新的Table Group或者删除,原Table Group才会失效。 
CALL HG_CREATE_TABLE_GROUP ('<new_tg_name>', <shard_count>);参数说明如下:
| 参数 | 类型 | 说明 | 
| new_tg_name | Text | 新建的Table Group名。 | 
| shard_count | INT4 | Table Group对应的Shard数。 | 
使用示例:
-- 新建一个Shard数为8的新Table Group,命名为tg_8
CALL HG_CREATE_TABLE_GROUP ('tg_8', 8);修改默认Table Group
新建一个数据库后,实例会有一个默认Table Group,以及默认的Shard数。详情请参见实例管理。若是数据库中有多个Table Group,想要修改默认Table Group,使得后续新建的表存放于新的Table Group中,可以使用如下命令语句。
Hologres实例V0.9及以上版本执行以下命令语句修改默认Table Group,V0.9以下版本请先升级到更高版本。
CALL HG_UPDATE_DATABASE_PROPERTY ('default_table_group', '<tg_name>');参数说明:
| 参数 | 类型 | 说明 | 
| tg_name | TEXT | 默认Table Group名称,设置后,其Shard count为设置的Table Group的Shard数。 | 
使用示例:
-- 将新创建TG设为默认Table Group,后续新建的表,将默认使用新的Table Group (v0.9及以上版本)
CALL HG_UPDATE_DATABASE_PROPERTY ('default_table_group', 'tg_8');将新建表放入指定Table Group
可以通过以下命令语句将新建表,显式放入指定的Table Group中。
BEGIN;
CREATE TABLE table_name (
    col type,
  ....
);
CALL SET_TABLE_PROPERTY('table_name', 'table_group', '<tg_name>');
COMMIT;参数说明:
| 参数 | 类型 | 说明 | 
| table_name | TEXT | 新建的表名。 | 
| tg_name | TEXT | 指定的Table Group名称,设置后,其Shard Count为设置的Table Group的Shard数。 | 
使用示例:
-- 新建表tbl1并直接关联名为tg_8的Table Group
BEGIN;
CREATE TABLE tbl1 (
    col1 text
);
CALL SET_TABLE_PROPERTY('tbl1', 'table_group', 'tg_8');
COMMIT;(Resharding)迁移表至新建Table Group
在Hologres中,Shard用于提升数据处理的并发度,合理的设置Shard数,有利于提高查询或者写入的性能。一般情况下,Hologres实例默认的Shard数已经能满足大部分场景,无需再手动修改。
当实例扩容后,例如32core扩容到128core,该数据库的Shard数不会随着扩容默认更改,因此建议您针对该数据库增加Shard数,以获取更好的性能。如果是该实例下新建的DB,其Shard数为当前规格的默认数量。实例规格与Shard的相关描述,请参见实例管理。
当实例扩容或者缩容后,其之前DB的Shard数不会自动随之增加或减少,需要通过命令语句设置Shard数,并重新进行数据导入。
- 针对普通表和物理分区表,使用Rebuild语法和内置存储过程均可。 
- 针对逻辑分区表,建议使用Rebuild语法,可自动实现按分区串行执行。 
通过Rebuild语法Resharding
Hologres自V3.1版本起,支持通过Rebuild命令修改表属性,包括迁移表的Table Group。Rebuild语法可异步执行迁移任务,并支持实时监测任务进度,详情请参见REBUILD(Beta)。
通过内置存储过程Resharding
Hologres自V0.10版本起,提供Resharding命令语法,用于修改Shard数后自动实现Rebalance的功能,无需再重新建表导数据,即可将原来的表和数据Resharding到各Shard上,简化操作步骤,实现最优性能。
- 使用限制 - 仅Hologres V0.10及以上版本支持Resharding,请前往Hologres管控台的实例详情页查看当前实例版本,如果您的实例是V0.10以下版本,请您使用常见升级准备失败报错或加入Hologres钉钉交流群反馈,详情请参见如何获取更多的在线支持?。 
- 目前Resharding是单表级别,当使用Resharding时,需要停止该表的写入(如Flink、数据集成等写入),对表的查询不受影响。V1.1 版本开始,支持 - set table readonly,实时任务写入自动Failover。
- Resharding会消耗CPU资源,且在Resharding过程中会导致存储增加,建议在业务低峰期处理。 
- 如果表开启了Binlog,请在Resharding之前关掉Binlog,待Resharding完成后再开启Binlog,详细操作请参见订阅Hologres Binlog。 
- 暂不支持表字段带有Serial自增序列以及Default值进行Resharding,带Serial字段的表在Resharding时会报错,带Default字段的表Resharding后会丢失Default属性。 
- 表在Resharding时不能有其他的依赖比如view等,若存在请在Resharding前删除相关依赖,否则会报错 - “ERROR: resharding table xxx can not executed because other objects depend on it.”。
- Hologres V2.2.29及以上版本、V3.0.36及以上版本,支持对有View依赖的表执行Resharding,通过 - set hg_experimental_hg_insert_overwrite_enable_view=on;命令开启GUC。
- Resharding只适用简单模型,不适用于专家模型。关于Hologres权限模型介绍,详情请参见Hologres权限模型。 
- Resharding暂不保留表的动态分区属性。 
- 仅Hologres V2.0及以上版本的Resharding操作支持保留列COMMENTS。如果您的实例版本低于V2.0,请提前备份列COMMENTS,并在Resharding完成后手动设置。 
 
- 语法示例 - 如果您的实例为V2.0.24及以上版本,推荐使用HoloWeb进行Resharding操作,详情请参见Table Resharding。 
- 如果您的实例版本低于V2.0.24,可以通过以下命令将业务的部分表迁移至新建的Table Group。如果实例版本低于V0.10,请先升级到更高版本。 
 说明- 在迁移之前,需要有一个新建的Table Group,若是没有新建Table Group,请参见新建Table Group进行新建。 
- 表迁移时需要停止对该表的写入,查询不受影响。 
- 原Table Group的表全部迁移后,原Table Group将会被自动删除。若是因为业务需求需要建立多个Table Group,建议合理设置每个Table Group的Shard数。 
- 表迁移时分区表只需要操作父表即可。 
- 如果您的实例类型为计算组型,您需要将表从Table Group A迁移至目标Table Group B,则必须使用Table Group B的主计算组W来执行此次迁移任务。此外,W计算组需要具备对Table Group A的访问权限,即W计算组需加载为Table Group A的Follower计算组。计算组Table Group授权操作请参见计算组Table Group授权管理。 
 - -- V1.1及以上版本命令语法 CALL HG_MOVE_TABLE_TO_TABLE_GROUP('<table_name>','<new_table_group_name>'); -- V0.10版本命令语法 CALL HG_UPDATE_TABLE_SHARD_COUNT('<table_name>','<new_table_group_name>');
- 参数说明 - 参数 - 说明 - 示例 - table_name - 需要迁移的表名。一次命令仅支持单表迁移,若是有多个表,需要多次执行。分区表只需要操作父表即可。 - new_table - table_group_name - 新的Table Group名。 - new_tg 
- 异常处理 - Table Resharding过程中,会先将表设为只读状态,而后通过临时表的方式进行Table Group迁移。由于Resharding任务涉及数据导入,可能需要执行较长时间,因此可能会出现多种异常情况,如OOM、手动终止任务等,此时原表会仍处于只读状态,且数据库中出现名为<initial_table_name>_xxxxxxxx的临时表,此时需要根据如下情况进行操作: - Hologres实例版本低于 V2.0.24,请升级实例或提交工单解决,升级实例请参见实例升级。 
- Hologres实例版本为 V2.0.24及以上: - 如果您通过HoloWeb进行Resharding操作,请单击继续运行或取消任务,详情请参见Table Resharding。 
- 如果您通过执行上述命令进行Resharding操作,请按以下步骤操作: - 如果您希望继续对该表进行Resharding:对中断原因进行处理后,重新对该表运行HG_MOVE_TABLE_TO_TABLE_GROUP命令即可。 
- 如果您希望取消Resharding并恢复初始状态:请依次运行如下命令进行恢复: - -- 取消原表的readonly属性 CALL set_table_property('<schema_name>.<table_name>','readonly','false'); -- 清理临时表 -- 获取临时表名(分区表) SELECT schema_name,target_temp_table_name FROM hologres.hg_resharding_properties WHERE reshard_table_name = <schema_name>.<table_name> AND is_parent_table IS TRUE; -- 获取临时表名(非分区表) SELECT schema_name,target_temp_table_name FROM hologres.hg_resharding_properties WHERE reshard_table_name = <schema_name>.<table_name> AND is_parent_table IS FALSE AND is_sub_table IS FALSE; -- 清理临时表 DROP TABLE IF EXISTS <schema_name>.<target_temp_table_name>; -- 清理系统表。系统表中会记录当前表的Resharding进度,如果希望取消任务,需要清理系统表中的对应数据 CALL hologres.hg_internal_clear_resharding_properties('<schema_name>.<table_name>');
 
 
 
删除Table Group
可以通过以下命令语句删除空的Table Group。如果Table Group有表存在,则无法删除。
CALL HG_DROP_TABLE_GROUP('<tg_name>');使用示例:
--删除名为tg_8的Table Group
CALL HG_DROP_TABLE_GROUP('tg_8');查看Shard与Worker的倾斜关系
Shard数与Worker个数存在一定的分配关系,详情请参见Shard与计算节点Worker的关系。如果Worker个数与Shard分配不均,那么很容易出现Worker资源倾斜,导致负载不均,资源得不到高效利用。因此在Hologres V1.3版本提供worker_info系统视图,用于查询当前数据库的Worker、Table Group和Shard之间的关系,从而帮助排查解决倾斜问题,详细的Worker资源倾斜排查请参见查看Worker倾斜关系。
使用最佳实践
Table Group是比较高级的功能,一般情况下,不建议业务新建Table Group以及修改Shard数。若是因为业务有不同的需求,可以按照最佳实践合理规划,详情请参见Table Group设置最佳实践。
常见问题
Resharding是个比较复杂的过程,涉及到创建临时表、修改原始表只读状态、写入目标表、更换表名称和记录同步状态等多个环节,如果中间环节因为某些原因出现异常,可能造成系统状态不确定等问题,可通过以下方法进行排查。
当出现internal error: Get rundown is not allowed in recovering state.异常时,说明当前正在更新的表处于Read Only状态,不能执行Insert、Update、Delete等操作,此时需要退出Read Only状态。
- 执行如下命令检索当前处于Read Only状态的表。 - select * from hologres.hg_table_properties where property_key ='readonly' and property_value='true';
- 执行如下命令退出Read Only状态。 - call set_table_property('<table_name>','readonly','false');- table_name为需要退出Read Only状态的表名称。