02 规划与设计
剖析 Snowflake 工作负载,然后做出迁移将要执行的架构决策,引擎选择、sort key、schema 转换、部署波次以及 dbt 模型设计。
起点
模块 01 已完成:Snowflake 环境已经搭建完毕,CDC 流和两个定时任务都在运行。
最重要的是,行程数据生成器仍在以每分钟约 60 条的速度写入
TRIPS_RAW。让它继续运行;本模块只从 Snowflake 读取。预留大约 90
分钟和约 0.5 个 Snowflake 积分。
为什么
ClickHouse 迁移表现不佳最常见的原因不是调优问题,而是架构问题。团队先搬数据,之后才考虑 设计。等他们意识到错误的 MergeTree 引擎正在无声地产出错误结果,或者从源 schema 照搬来的 sort key 完全忽视了实际的查询模式时,迁移已经"做完"了。本模块强制采用相反的顺序:先剖析 现有工作负载,再把引擎、排序键、类型映射和迁移顺序等决策明确记录下来。 模块 03 才会开始执行这些决策。
这也是合作伙伴最想跳过的模块。模块 03 的 setup.sh 会检查
migration-plan.md,缺失或不完整时会给出警告,但它绝不会阻断,你完全可以不带它就往前冲。
如果你这么做,运行模块 03 时你执行的将是你从未做过的决策:你会看到 fact_trips 以
ReplacingMergeTree 建起来,却不知道为什么是这个引擎而不是普通的 MergeTree;会看到一个
ORDER BY 键,却不知道它是如何从查询负载推导出来的;会在 dbt 配置里看到 delete_insert
和 FINAL,却不知道换成另一个工作负载时该如何推导它们;还会在模块 04 看到你既解释不了、
也无法向客户复现的基准测试提速。这里的 90 分钟,能让你在后续课程中不再只是照抄命令,
而是真正理解迁移过程。
概念:底层原理
本模块产出的每个决策都落入以下五类之一,每一类都配有一份练习表:
- 引擎系列:哪个 MergeTree 变体契合每张表的写入模式:
仅追加用普通
MergeTree、通过 CDC 接收更新的表用ReplacingMergeTree、预聚合汇总用AggregatingMergeTree。见 MergeTree 引擎。 ORDER BY键:ClickHouse 没有可以事后添加的索引;sort key 只选一次,而且是根据 实际查询负载来选,不是根据源表的 primary key。- 类型映射与方言差异:Snowflake 的
VARIANT、LATERAL FLATTEN和MERGE INTO在 ClickHouse 中没有直接等价物,需要翻译成对应形式。QUALIFY是个例外:ClickHouse 自 v24.5 起就有原生的QUALIFY子句, 但本实验仍然教子查询改写法,因为它可以移植到早于 v24.5 或不支持QUALIFY的 ClickHouse 版本与 SQL 引擎上。见 Snowflake 与 ClickHouse 对照。 - dbt 模型设计:每个模型的物化方式、引擎配置、增量策略和
FINAL的放置位置。见 ClickHouse 上的 dbt。 - 波次顺序:哪些对象因为下游还没有任何依赖而可以先搬,哪些必须等待。
步骤 1:剖析 Snowflake 环境
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/02-plan-and-design"
source ../01-setup-snowflake/.env
./scripts/01_profile_snowflake.sh这会针对你在模块 01 建立的实时 Snowflake 实例运行,并写出包含四个部分的 profile_report.md:
一份对象清单(每张表、视图、流和任务,附带行数和复杂度评级)、过去 7
天内按总耗时排序的前 10 个查询、表统计信息(行数、日期范围、空值率、VARIANT 使用情况),
以及自动检测到的 schema 兼容性差异。
profile_report.md 在 gitignore 中,它每次运行都从你自己的 Snowflake 账号重新生成,
因此是与机器相关的,绝不提交。不要指望在全新克隆里找到它,也不要试图自己去提交它。
如果 ACCOUNT_USAGE 还不可用(它需要 1-3 小时的数据传播延迟,或者需要
ACCOUNTADMIN 角色),脚本会退回到 INFORMATION_SCHEMA 并记录它无法测量的内容。
你也可以在 Snowflake 界面中手动运行 scripts/02_query_history.sql。
步骤 2:完成五份练习表
按顺序完成五份练习表。每一份先讲解一个概念,然后针对真实的 NYC 出租车工作负载给出选择题 练习。每个答案在你选定的那一刻就会被判定,并且每份练习表都有一个"Copy as markdown"按钮, 可以把填好的表格交给你,粘贴进你的迁移方案。
- 练习表 1:MergeTree 引擎选择,每张表的引擎系列与具体引擎选择
- 练习表 2:Sort key 设计,从查询负载推导出的
ORDER BY - 练习表 3:Schema 转换,类型映射与函数翻译
- 练习表 4:迁移波次方案,依赖排序与波次分配
- 练习表 5:dbt 模型设计,物化方式、引擎、增量策略与
FINAL的放置位置
你的答案保存在浏览器的 local storage 中,而不是仓库里,它们不会跟着你到另一台机器, 也无法在清除站点数据后留存。如果你在课程进行到一半时换了笔记本,就需要在新机器上 重做这些练习表。
步骤 3:填写迁移方案
打开 workshop_public/snowflake_migration_lab/02-plan-and-design/migration-plan.md,用你的
练习表答案填写每个小节。该文档有十个小节,顶部还有一份包含五个复选框的
完成度检查清单:
- [ ] Engine selection: completed
- [ ] Sort key design: completed
- [ ] Schema translation: completed
- [ ] Migration wave plan: completed
- [ ] dbt model design: completed模块 03 的 setup.sh 会检查这份清单,不完整时给出警告,但它不会
阻止你继续。无论如何都把它填完,正是让模块 03 的各项决策显得合乎逻辑、而不是像是随意
拍脑袋的原因。
如何确认已完成
当以下全部成立时,你就完成了:
- 五份练习表全部满分,每一份底部的得分行都显示
N/N correct。 workshop_public/snowflake_migration_lab/02-plan-and-design/migration-plan.md的完成度检查清单中每个复选框都已勾选。- 步骤 1 生成的
profile_report.md存在于磁盘上(它在 gitignore 中,所以不会出现在git status里)。
写完你自己的方案之后,把它与 范例:一份完成的方案 做对比, 那是针对同一工作负载完整填好的方案。用它来检验你的推理,并理解你与它选择不同的每一处, 而不是在自己想清楚之前把它当成模板来照填。
结束状态
磁盘上有一份填好的 migration-plan.md,每个复选框都已勾选,背后是五份完成的
练习表。Snowflake 生产者仍在运行,模块 03 从一个实时、持续变动的源端迁出数据,
而模块 05 的切换步骤要测量的正是迁移期间生产者在 Snowflake 与 ClickHouse 之间制造的确切
间隔。现在不要停掉它。