You need to enable JavaScript to run this app.
导航
分布式 DDL
最近更新时间:2024.11.27 15:57:31首次发布时间:2024.10.30 17:14:54

兼容建表模式下

定义

对于 ByteHouse 而言,默认情况下,CREATE、DROP、ALTER 和 RENAME 等 DDL 仅会在当前节点执行。若希望对整个集群生效,可以使用 ON CLUSTER 子句以分布式方式运行此类查询,初始节点会将 DDL 自动发送到每个节点执行。

Image
fe
例如,以下查询将在集群中的每个主机上创建 all_hits 分布式表:

CREATE TABLE IF NOT EXISTS all_hits ON CLUSTER cluster (p Date, i Int32) 
    ENGINE = Distributed(cluster, default, hits)

运行细节

  1. 事务性:On cluster 没有事务性,无法确保全部成功,也无法在单一节点是被时回滚。
  2. 幂等性:On cluster 在单个节点内执行查询的顺序是有保证的,因此如果发送了分布式 DDL,每个节点都会按发送顺序执行这些 DDL。
  3. 队列:分布式 DDL 会通过 ZK 调度,在队列中依次执行。因此即使某些节点当前不可用,待节点恢复响应,最终也会执行这条 DDL。可以通过系统表system.distributed_ddl_queue查看队列。
  4. 超时:超时时间通过distributed_ddl_task_timeout配置(会话级参数,默认180秒),若 DDL 超时,会返回超时,但其后台仍会根据队列执行。

最佳实践

  1. 每条 DDL(包含 Create,Alter,Truncate,Rename,Drop等)均以分布式 DDL 发送,不要只在单节点上操作,不然会引起多节点中元数据不一致。
  2. 若初始不是用分布式 DDL 执行的,部分节点上有表,部分没有,界面会显示表缺失,也会导致后续从网关路由的查询间歇性报错。建议重新发一次分布式 DDL(无需删表),会补全这些缺失的节点的表。
  3. 对于数据加工的场景,可能涉及建表、导数、验数等必须严格顺序执行的场景,建议将distributed_ddl_task_timeout配置设置为0(这样不再超时),这样可以确保在建表、Truncate 运行完后,再执行下一步操作。

通用建表模式下

定义

对于 ByteHouse 而言,只要开启了通用建表模式,向 ByteHouse 网关发送的 CREATE、DROP、ALTER 和 RENAME 等 DDL 均会以分布式 DDL 方式运行此类查询,初始节点会将 DDL 自动发送到每个节点执行。使得各节点上表信息的元数据一致,用于通用的建库、建表、改表场景。
但如果对节点直接发送 DDL,或通过网关的指定节点模式发送查询,DDL 只会在目标节点上生效。通常用于修复单一节点的数据问题。
Image
例如,以下查询将在集群中的每个主机上创建 all_hits 分布式表:

CREATE TABLE IF NOT EXISTS all_hits (p Date, i Int32) ENGINE = Distributed(cluster, default, hits)

运行细节

  1. 事务性:分布式 DDL 方式没有事务性,无法确保全部成功,也无法在单一节点是被时回滚。
  2. 幂等性:分布式 DDL 方式在单个节点内执行查询的顺序是有保证的,因此如果发送了分布式 DDL,每个节点都会按发送顺序执行这些 DDL。
  3. 队列:分布式 DDL 会通过 ZK 调度,在队列中依次执行。因此即使某些节点当前不可用,待节点恢复响应,最终也会执行这条 DDL。可以通过系统表system.distributed_ddl_queue查看队列。
  4. 超时:超时时间通过distributed_ddl_task_timeout配置(会话级参数,默认180秒),若 DDL 超时,会返回超时,但其后台仍会根据队列执行。

最佳实践

  1. 每条 DDL(包含 Create,Alter,Truncate,Rename,Drop等)均通过网关发送,这样会以分布式 DDL 的方式发送,不要只在单节点上操作,不然会引起多节点中元数据不一致。
  2. 若初始不是用分布式 DDL 执行的,部分节点上有表,部分没有,界面会显示表缺失,也会导致后续从网关路由的查询间歇性报错。建议重新发一次分布式 DDL(无需删表),会补全这些缺失的节点的表。
  3. 对于数据加工的场景,可能涉及建表、导数、验数等必须严格顺序执行的场景,建议将distributed_ddl_task_timeout配置设置为 0(这样不再超时),这样可以确保在建表、Truncate 运行完后,再执行下一步操作。