尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

clickhouse-operator 集群 Schema 自动迁移机制详解:扩缩容下的建表与删表流程

clickhouse-operator 集群 Schema 自动迁移机制详解:扩缩容下的建表与删表流程 clickhouse-operator 集群 Schema 自动迁移机制详解扩缩容下的建表与删表流程【免费下载链接】clickhouse-operatorAltinity Kubernetes Operator for ClickHouse creates, configures and manages ClickHouse® clusters running on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/cl/clickhouse-operator导读ClickHouse 集群在 Kubernetes 上扩容新增分片/副本或缩容删除分片/副本时如何自动完成数据库、本地表、分布式表和复制表的创建与清理是保证集群可用性与数据一致性的关键。本文以 Altinity clickhouse-operator 官方文档 docs/schema_migration.md 为骨架结合pkg/model/chi/schemer模块的真实源码系统讲解 Schema 自动创建、自动删除的完整流程、schemaPolicy配置控制方式以及底层 SQL 生成原理。读完本文你将能理解 operator 扩缩容时建什么表、从哪建、怎么建、何时删并能据此排查或设计自己的 Schema 迁移方案。一、什么是 Schema 迁移Schema Migration在 clickhouse-operator 的语境中Schema 迁移特指当 ClickHouseInstallationCHI资源的分片shard或副本replica数量发生变化时operator 自动在新实例上补齐数据库与表结构并在实例被移除时清理相关表对象。这一点在官方文档 docs/schema_migration.md 开篇即被点明clickhouse-operatorautomates schema management when cluster is scaled up or down即扩缩容时的 Schema 管理完全由 operator 自动化完成用户不需要手工对每个新 Pod 执行 DDL。从源码结构看这一能力由独立模块 pkg/model/chi/schemerschemer包实现它通过 HTTP 方式连接 ClickHouse 实例执行 SQL并负责生成所有建表/删表语句。二、Schema 自动创建扩容时建表流程2.1 官方文档定义的两条路径原文档给出了两条清晰的创建逻辑新增分片shard added分析集群中其他分片的分布式表distributed tables及对应的本地表local tables创建本地表和分布式表所需的数据库创建本地表创建分布式表。新增副本replica added分析同一分片内其他副本的复制表replicated tables创建复制表所需的数据库创建复制表随后执行与新增分片相同的逻辑即继续补建分布式表与本地表。2.2 源码实现HostCreateTables与createTablesSQLs在源码层面扩容建表的入口是 pkg/model/chi/schemer/schemer.go 中的HostCreateTables(ctx, host)方法其核心逻辑为调用createTablesSQLs()分别获取两类 SQL 集合getReplicatedObjectsSQLs()见 replicated.go收集复制对象的建库、建表、建函数 SQLgetDistributedObjectsSQLs()见 distributed.go收集分布式对象的建库、建表、建函数 SQL先在新 host 上执行复制对象 SQL再执行分布式对象 SQL对应原文档副本逻辑先于分片逻辑的描述两类 SQL 均以SetRetry(true).SetLogQueries(true)选项执行保证 DDL 失败可重试并留下查询日志。关键实现片段schemer.go// HostCreateTables creates tables on a new host func (s *ClusterSchemer) HostCreateTables(ctx context.Context, host *api.Host) error { ... replicatedObjectNames, replicatedCreateSQLs, distributedObjectNames, distributedCreateSQLs : s.createTablesSQLs(ctx, host) if len(replicatedCreateSQLs) 0 { err1 s.ExecHost(ctx, host, replicatedCreateSQLs, clickhouse.NewQueryOptions().SetRetry(true).SetLogQueries(true)) } if len(distributedCreateSQLs) 0 { err2 s.ExecHost(ctx, host, distributedCreateSQLs, clickhouse.NewQueryOptions().SetRetry(true).SetLogQueries(true)) } ... }2.3 复制对象的创建逻辑getReplicatedObjectsSQLsgetReplicatedObjectsSQLs在真正生成 SQL 之前会先调用shouldCreateReplicatedObjects(host)做前置判断replicated.go若schemaPolicy.shard All且集群实例数 ≥ 2则显式要求每个分片都建复制对象若schemaPolicy.replica None则不创建复制对象若该分片内副本数 ≤ 1len(shard) 1没有可参考的复制来源不创建复制对象。通过判断后依次生成三类 SQLSQL 生成函数作用定义位置sqlCreateDatabaseReplicated从clusterAllReplicas(cluster, system.databases)读取全集群数据库生成CREATE DATABASE IF NOT EXISTS ...sql.gosqlCreateTableReplicated从system.tables读取非系统库、引擎属于Ordinary/Atomic/Memory/Lazy的表用replaceRegexpOne将CREATE改写为CREATE ... IF NOT EXISTSsql.gosqlCreateFunction从system.functions收集用户自定义函数同样改写为CREATE FUNCTION IF NOT EXISTSsql.go值得注意的是sqlCreateDatabaseReplicated会依据 ClickHouse 版本选择不同的 DDL 片段版本 ≥ 22.12 时使用engine_full否则使用enginesql.go这正是版本感知version.Matches( 22.12)的体现。2.4 分布式对象的创建逻辑getDistributedObjectsSQLsshouldCreateDistributedObjectsdistributed.go的判断条件为schemaPolicy.shard None时不创建分布式对象集群内 host 数 ≤ 1 时没有分发目标不创建。sqlCreateTableDistributed的实现更具技巧性它通过正则extract(engine_full, Distributed\\([^,], *\?([^,\])\?, *[^,])从分布式表的engine_full中解析出其引用的远端数据库名再LEFT JOIN system.tables找到对应的本地表定义最终生成分布式表 被引用的本地表的完整创建语句sql.go。所有查询都带有SETTINGS skip_unavailable_shards 1保证部分分片不可用时查询依然成功。三、Schema 自动删除缩容时清理流程原文档对删除路径的说明只有一句话但含义关键If cluster is scaled down and some shards or replicas are deleted,clickhouse-operatordrops replicated table to make sure nothing is left in ZooKeeper.即缩容时删除复制表确保 ZooKeeper 中不残留元数据。这是 Replicated 表模型下必须做的事——如果只删 Pod 不删 ZooKeeper 中的 replica 路径后续同名校验、重挂载都会失败。3.1HostDropTables删表 SQL 的生成HostDropTables(ctx, host)调用sqlDropTable()生成三类 DROP 语句schemer.go、sql.go字典DROP DICTIONARY IF EXISTS db.name来源system.dictionaries表/视图DROP TABLE IF EXISTS db.name SYNC来源system.tables筛选引擎含%MergeTree%或%View%并排除system、information_schema、INFORMATION_SCHEMA三个系统库复制数据库DROP DATABASE IF EXISTS name SYNC来源system.databases仅当engine Replicated。其中SYNC修饰符保证 DROP 等待副本数据同步完成后再返回避免竞态。注意视图View没有独立的删除查询按 ClickHouse 约定统一用DROP TABLE删除——源码注释中明确引用了这一点sql.go。3.2HostDropReplica清理 ZooKeeper 残留针对复制表副本残留问题schemer 提供了HostDropReplica方法schemer.go其 SQL 由sqlDropReplica生成sql.gofunc (s *ClusterSchemer) sqlDropReplica(shard int, replica string) []string { return []string{ fmt.Sprintf(SYSTEM DROP REPLICA %s, replica), fmt.Sprintf(SYSTEM DROP DATABASE REPLICA %d|%s, shard, replica), } }即对每个被删除的 host 执行SYSTEM DROP REPLICA replica与SYSTEM DROP DATABASE REPLICA shard|replica从 ZooKeeper 中摘除对应副本注册信息这正是原文档make sure nothing is left in ZooKeeper的实现来源。3.3 删除流程的调用链在控制器层删除逻辑集中在 pkg/controller/chi/worker-deleter.go对将被删除的 host 调用HostDropTables第 504 行附近对复制副本调用HostDropReplica第 476 行附近删除前还会通过HostSyncTables执行SYSTEM SYNC REPLICA以同步复制状态第 255、312 行附近。四、schemaPolicy控制 Schema 迁移行为的配置项Schema 迁移并非一刀切operator 通过 CHI 资源中的schemaPolicy字段精细控制复制/分布式对象的创建范围。合法取值定义在 pkg/model/chi/schemer/const.go字段取值含义replicaNone不创建复制对象Replicated 表replicaAll默认创建复制对象shardNone不创建分布式对象shardAll默认创建分布式对象与复制对象shardDistributedTablesOnly只创建分布式表相关对象配置写法参见完整示例 docs/chi-examples/99-clickhouseinstallation-max.yamlschemaPolicy: replica: All shard: All在 pkg/model/chi/normalizer/normalizer.go 的normalizeClusterSchemaPolicy中这些取值会被大小写归一化处理未知值统一回退到默认值replica: All、shard: All保证任何用户输入都不会破坏 operator 的稳定性switch strings.ToLower(policy.Replica) { case strings.ToLower(schemer.SchemaPolicyReplicaNone): policy.Replica schemer.SchemaPolicyReplicaNone case strings.ToLower(schemer.SchemaPolicyReplicaAll): policy.Replica schemer.SchemaPolicyReplicaAll default: // Unknown value, fallback to default policy.Replica schemer.SchemaPolicyReplicaAll }shard分支同样如此未知值回退到SchemaPolicyShardAll。因此可以推断只要不显式配置schemaPolicyoperator 默认会在扩缩容时全量维护复制表与分布式表。schemaPolicy与shouldCreateReplicatedObjects/shouldCreateDistributedObjects两个判断函数直接联动见 2.3、2.4 节构成完整的决策链路normalizer 归一化配置 → schemer 判断是否创建 → 生成 SQL → 执行。五、从源码结构看 Schema 迁移的完整生命周期综合上文可以将 operator 的 Schema 迁移生命周期总结为如下闭环扩容新增副本新 host 就绪后控制器调用HostCreateTables→ 先建复制对象数据库 → 复制表 → 函数再建分布式对象分布式表及其引用的本地表扩容新增分片同样走HostCreateTables但shouldCreateReplicatedObjects会依据分片内副本数判断是否需要复制对象缩容删除副本控制器调用HostDropReplica清理 ZooKeeper 副本注册再调用HostDropTables删除本地表、视图与复制数据库缩容删除分片对分片内各 host 执行同样的删除逻辑确保 ZooKeeper 无残留任何时刻HostSyncTables可执行SYSTEM SYNC REPLICA等待复制追上进度用于删除前的状态校验。整个流程都运行在 worker-migrator.go 与 worker-deleter.go 的协调器上下文里与 CHI 的滚动更新、Pod 调度等机制解耦属于独立、可重入的 Schema 维护子流程。六、使用建议与注意事项基于以上机制在实际使用中值得注意扩容后 Schema 自动补齐无需手工 DDL只要新 Pod 正常 Readyoperator 会自动完成建库建表可参考 docs/schema_migration.md 中的预期行为核对缩容前关注复制表残留删除分片/副本后若观察到 ZooKeeper 中存在旧 replica 路径说明删除流程未完整执行可检查worker-deleter.go中HostDropReplica的执行日志日志关键字Drop replica合理配置schemaPolicy单副本测试环境可设replica: None减少 ZooKeeper 依赖纯查询分发场景可设shard: DistributedTablesOnly版本差异sqlCreateDatabaseReplicated针对 ClickHouse ≥ 22.12 使用了engine_full低版本集群会自动走兼容分支升级 ClickHouse 大版本时无需改动 operator 配置视图删除ClickHouse 无独立 DROP VIEW 语句schemer 统一以DROP TABLE IF EXISTS ... SYNC删除视图这符合 ClickHouse 官方语义。总结clickhouse-operator将集群扩缩容时的 Schema 维护完整自动化以 docs/schema_migration.md 描述的行为为准绳以 pkg/model/chi/schemer 模块为实现核心通过复制对象优先、分布式对象次之的建表顺序和删表 删 ZooKeeper 副本的删表策略保证集群在任何规模的扩缩容操作下都能维持正确的表结构与 ZooKeeper 状态。理解本文的决策链schemaPolicy→shouldCreate*→sql*→ExecHost即可在遇到 Schema 相关异常时快速定位根因。【免费下载链接】clickhouse-operatorAltinity Kubernetes Operator for ClickHouse creates, configures and manages ClickHouse® clusters running on Kubernetes项目地址: https://gitcode.com/GitHub_Trending/cl/clickhouse-operator创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表