基于本文回答

播面 播面

文图音视,全方位拆解八股文
0
评论

在 Doris中,如何通过配置 Colocate Group 实现本地化计算、零网络传输的极速关联查询?

在 Apache Doris 中,Colocate Join 是一种极速关联查询技术。它通过将相互关联的表(如事实表和维度表,或主表和子表)的数据按相同的分桶键和路由规则,强制存储在相同的物理节点(BE)上

当进行 Join 查询时,Doris 可以直接在本地进行数据关联,彻底避免了节点间的数据 Shuffle(网络传输),从而实现百毫秒甚至毫秒级的极速关联查询。

以下是实现 Colocate Group 的完整配置步骤、原理及验证方法。


一、 Colocate Group 的核心约束(前提条件)

要让多张表加入同一个 Colocate Group,它们必须满足以下强一致性约束:

  1. 分桶键(Distribution Keys)一致:分桶列的数量、类型和顺序必须完全一致。
  2. 分桶数(Bucket Number)一致:表的分桶数量必须完全相同。
  3. 副本数(Replication Number)一致:表的副本数量必须相同。
  4. 同数据库:属于同一个 Database(跨库的 Colocate 暂不支持)。

二、 实战:配置 Colocate Group

假设我们有两张表:订单表 orders 和订单详情表 order_items,它们通过 order_id 进行关联。

1. 创建订单表(主表)

PROPERTIES 中通过 "colocate_with" = "group_order_details" 属性来定义/加入一个 Colocate Group。

sql
CREATE TABLE orders (
    order_id BIGINT NOT NULL COMMENT "订单ID",
    user_id BIGINT NOT NULL COMMENT "用户ID",
    order_date DATE COMMENT "下单日期",
    total_amount DECIMAL(15, 2) COMMENT "总金额"
) ENGINE=OLAP
DUPLICATE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 16 -- 1. 分桶键为 order_id,分桶数为 16
PROPERTIES (
    "colocate_with" = "group_order_details", -- 2. 定义 Colocate Group 组名
    "replication_num" = "3"                  -- 3. 副本数为 3
);

2. 创建订单详情表(子表)

详情表必须保持相同的分桶键、分桶数、副本数,并指向相同的 colocate_with 组名。

sql
CREATE TABLE order_items (
    item_id BIGINT NOT NULL COMMENT "明细ID",
    order_id BIGINT NOT NULL COMMENT "订单ID", -- 必须与 orders.order_id 类型一致
    product_id BIGINT NOT NULL COMMENT "商品ID",
    price DECIMAL(15, 2) COMMENT "单价",
    quantity INT COMMENT "数量"
) ENGINE=OLAP
DUPLICATE KEY(item_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 16 -- 1. 分桶键必须也是 order_id,分桶数必须是 16
PROPERTIES (
    "colocate_with" = "group_order_details", -- 2. 组名必须完全一致
    "replication_num" = "3"                  -- 3. 副本数必须一致
);

三、 验证 Colocate 效果

配置完成后,我们需要验证数据是否真的实现了本地化计算。

1. 验证元数据状态

使用以下命令查看 Colocate Group 的状态:

sql
SHOW COLOCATE JOIN;

输出关键字段解读:

  • GroupId:组 ID(格式通常为 db_id.group_id)。
  • GroupName:组名(如 group_order_details)。
  • TableIds:该组内包含的表 ID。
  • IsStable必须为 true。如果是 false,说明 Doris 正在后台进行数据重平衡(Rebalance)以强制对齐,此时查询可能仍会有 Shuffle。

2. 验证执行计划(EXPLAIN)

运行你的 Join 查询,并在前面加上 EXPLAIN

sql
EXPLAIN 
SELECT * 
FROM orders o 
JOIN order_items i ON o.order_id = i.order_id;

如何判断成功?
在输出的执行计划(Execution Plan)中,观察 HASH JOIN 节点:

  • 如果看到 colocate: true 或者没有 HASH_SHUFFLE / BROADCAST 相关的 Exchange 节点,说明 Colocate Join 成功触发
  • 数据直接在本地的 BE 节点上进行 Scan 和 Join,无任何跨节点数据传输。

四、 进阶:Colocate 组的维护与行为

  1. 自动负载均衡(Rebalance)
    当 BE 节点宕机、扩容、或缩容时,Doris 的 FE(Frontend)会自动调度,重新将同一个 Colocate Group 内的所有表的分片(Tablets)搬迁到相同的 BE 节点上,这个过程是自动的,但重建期间 IsStable 会临时变为 false

  2. 如何退出 Group
    如果不想让某张表继续在组内,可以通过 ALTER TABLE 修改属性(将其设置为空):

    sql
    ALTER TABLE order_items SET ("colocate_with" = "");
  3. 动态分区表的 Colocate
    如果表使用了动态分区,只要分桶规则和副本数一致,依然可以使用 Colocate Group。Doris 会确保所有分区的数据都按规则对齐。


五、 极速性能调优建议

  1. 分桶键的选择:分桶键不仅是 Join 的关联键,也决定了数据的分布。选择高基数(Cardinality)的列作为分桶键(如本例中的 order_id),避免严重的数据倾斜。
  2. 合理设置 Bucket 数量
    • 建议单个 Bucket 的数据量在 1GB ~ 10GB 之间。
    • 分桶数不宜过多,否则会增加 FE 元数据压力和 BE 的线程开销。
  3. 避免过度使用:只对高频、大表关联、对延迟极其敏感的场景使用 Colocate Group。因为强行绑定多张表的数据分布会降低 HDFS/对象存储/本地磁盘的写入并发灵活性。
00:00
00:00