Colocate Join
本小节介绍如何使用 Colocate Join。
Colocate Join 功能是分布式系统实现 Join 数据分布的策略之一,能够减少数据多节点分布时 Join 操作引起的数据移动和网络传输,从而提高查询性能。
在 StarRocks 中使用 Colocate Join 功能,您需要在建表时为其指定一个 Colocation Group(CG),同一 CG 内的表需遵循相同的 Colocation Group Schema(CGS),即表对应的分桶副本具有一致的分桶键、副本数量和副本放置方式。如此可以 保证同一 CG 内,所有表的数据分布在相同一组 BE 节点上。当 Join 列为分桶键时,计算节点只需做本地 Join,从而减少数据在节点间的传输耗时,提高查询性能。因此,Colocate Join,相对于其他 Join,例如 Shuffle Join 和 Broadcast Join,可以有效避免数据网络传输开销,提高查询性能。
Colocate Join 支持等值 Join。
使用 Colocate Join 功能
创建 Colocation 表
在建表时,您需要在 PROPERTIES 中指定属性 "colocate_with" = "group_name"
以创建一个 Colocate Join 表,并且指定其归属于特定的 Colocation Group。
说明
自 2.5.4 起,支持了对不同 Database 中的表执行 Colocate Join,您只需要在建表时指定相同的
colocate_with
属性即可。
示例:
CREATE TABLE tbl (k1 int, v1 int sum)
DISTRIBUTED BY HASH(k1)
PROPERTIES(
"colocate_with" = "group1"
);
如果指定的 CG 不存在,StarRocks 会自动创建一个只包含当前表的 CG,并指定当前表为该 CG 的 Parent Table。如果 CG 已存在,StarRocks 会检查当前表是否满足 CGS。如果满足,StarRocks 会创建该表,并将该表加入 Group。同时,StarRocks 会根据已存在的 Group 中的数据分布规则为当前表创建分片和副本。
一个 Group 归属于一个 Database。Group 名在一个 Database 内唯一,在内部存储中,Group 的全名为 dbId_groupName
,但您只感知 groupName
。
说明
如果您为不同 Database 的表指定了相同的 Colocation Group,以保证这些表互相 colocate,则该 Colocation Group 都会存在每个 Database ,您可以通过执行
show proc "/colocation_group"
查看每个 Database 包含的 Colocation Group 信息。
分桶键哈希值,对分桶数取模得到桶的序号(Bucket Seq)。假设一个表的分桶数为 8,则共有 [0, 1, 2, 3, 4, 5, 6, 7] 8 个分桶(Bucket),每个分桶内会有一个或多个子表(Tablet),子表数量取决于表的分区(Partition)数量:为单分区表时,一个分桶内仅有一个子表。如果是多分区表,则会有多个子表。
为了使得表能够有相同的数据分布,同一 CG 内的表必须满足下列约束:
- 同一 CG 内的表的分桶键的类型、数量和顺序完全一致,并且桶数一致,从而保证多张表的数据分片能够一一对应地进行分布控制。分桶键,即在建表语句中
DISTRIBUTED BY HASH(col1, col2, ...)
中指定一组列。分桶键决定了一张 表的数据通过哪些列的值进行 Hash 划分到不同的 Bucket Seq 下。同 CG 的表的分桶键的名字可以不相同,分桶列的定义在建表语句中的出现次序可以不一致,但是在DISTRIBUTED BY HASH(col1, col2, ...)
的对应数据类型的顺序要完全一致。 - 同一个 CG 内所有表的所有分区的副本数必须一致。如果不一致,可能出现某一个子表的某一个副本,在同一个 BE 上没有其他的表分片的副本对应。
- 同一个 CG 内所有表的分区键,分区数量可以不同。
同一个 CG 中的所有表的副本放置必须满足下列约束:
- CG 中所有表的 Bucket Seq 和 BE 节点的映射关系和 Parent Table 一致。
- Parent Table 中所有分区的 Bucket Seq 和 BE 节点的映射关系和第一个分区一致。
- Parent Table 第一个分区的 Bucket Seq 和 BE 节点的映射关系利用原生的 Round Robin 算法决定。
CG 内表的一致的数据分布定义和子表副本映射,能够保证分桶键取值相同的数据行一定在相同 BE 节点上,因此当分桶键做 Join 列时,只需本地 Join 即可。
删除 Colocation Group
当 Group 中最后一张表彻底删除后(彻底删除是指从回收站中删除。通常,一张表通过 DROP TABLE
命令被删除后,会在回收站默认停留一天的时间后,再被彻底删除),该 Group 也会被自动删除。
查看 Group 信息
您可以通过以下命令查看集 群内已存在的 Group 信息。只有拥有 root
角色的用户才可以查看,不支持普通用户查看。
SHOW PROC '/colocation_group';
示例:
mysql> SHOW PROC '/colocation_group';
+-------------+--------------+----------+------------+----------------+----------+----------+
| GroupId | GroupName | TableIds | BucketsNum | ReplicationNum | DistCols | IsStable |
+-------------+--------------+----------+------------+----------------+----------+----------+
| 11912.11916 | 11912_group1 | 11914 | 8 | 3 | int(11) | true |
+-------------+--------------+----------+------------+----------------+----------+----------+
列名 | 描述 |
---|---|
GroupId | 一个 Group 的全集群唯一标识。前半部分为 DB ID,后半部分为 Group ID。 |
GroupName | Group 的全名。 |
TabletIds | 该 Group 包含的表的 ID 列表。 |
BucketsNum | 分桶数。 |
ReplicationNum | 副本数。 |
DistCols | Distribution columns,即分桶列类型。 |
IsStable | 该 Group 是否稳定。 |
您可以通过以下命令进一步查看特定 Group 的数据分布情况。
SHOW PROC '/colocation_group/GroupId';
示例:
mysql> SHOW PROC '/colocation_group/11912.11916';
+-------------+---------------------+
| BucketIndex | BackendIds |
+-------------+---------------------+
| 0 | 10002, 10004, 10003 |
| 1 | 10002, 10004, 10003 |
| 2 | 10002, 10004, 10003 |
| 3 | 10002, 10004, 10003 |
| 4 | 10002, 10004, 10003 |
| 5 | 10002, 10004, 10003 |
| 6 | 10002, 10004, 10003 |
| 7 | 10002, 10004, 10003 |
+-------------+---------------------+
8 rows in set (0.00 sec)
类名 | 描述 |
---|---|
BucketIndex | 分桶序列的下标。 |
BackendIds | 分桶中数据分片所在的 BE 节点 ID 列表。 |
修改表 Group 属性
您可以通过以下命令修改表的 Colocation Group 属性。
ALTER TABLE tbl SET ("colocate_with" = "group_name");
如果该表之前没有指定过 Group,则该命令会检查 Schema,并将该表加入到该 Group(如 Group 不存在则会创建)。如果该表之前有指定其他 Group,则该命令会先将该表从原有 Group 中移除,并将其加入新 Group(如 Group 不存在则会创建)。
您也可以通过以下命令,删除一个表的 Colocation 属性:
ALTER TABLE tbl SET ("colocate_with" = "");
其他相关操作
当对一个具有 Colocation 属性的表进行增加分区 ADD PARTITION
或修改副本数操作时,StarRocks 会检查该操作是否会违反 CGS,如果违反则会拒绝该操作。
Colocation 副本均衡和修复
Colocation 表的副本分布需遵循 Group 中指定的分布,所以其副本修复和均衡相较于普通分片有所区别。
Group 具有 IsStable 属性,当 IsStable 为 true 时(即 Stable 状态),表示当前 Group 内的表的所有分片没有正在进行的变动,Colocation 特性可以正常使用。当 IsStable 为 false 时(即 Unstable 状态),表示当前 Group 内有部分表的分片正在做修复或迁移,此时,相关表的 Colocate Join 将退化为普通 Join。