01 Môi trường nguồn
Cấp phát một môi trường Snowflake phản chiếu một triển khai khách hàng thực — 50M dòng, một pipeline dbt Medallion, một producer chuyến đi chạy trực tiếp và ba dashboard Superset.
Điểm khởi đầu
Module 00 đã hoàn tất: bộ công cụ đã cài, cả hai tài khoản dùng thử cloud đã hoạt động, repo
đã clone, và virtualenv dbt-snowflake đã dựng. Module này mất khoảng 45 phút và tiêu tốn
khoảng 2-4 Snowflake credit.
Vì sao
Bạn không thể lập kế hoạch di chuyển dựa trên một nguồn dữ liệu đồ chơi. Một bảng phẳng duy
nhất với vài dòng dữ liệu sẽ cho phép bạn bỏ qua mọi quyết định làm cho một cuộc di chuyển
thực sự trở nên khó. Thay vào đó, module này dựng đúng dáng hình của một triển khai khách
hàng thật: một cột VARIANT chứa JSON bán cấu trúc, một stream CDC, các task theo lịch, một
pipeline MERGE incremental, và một tầng BI đọc bên trên tất cả những thứ đó. Mỗi thứ trong
số đó trở thành một quyết định di chuyển cụ thể ở module 02 — module này tồn tại để bạn có
thứ thật mà chỉ vào khi quyết định đó xuất hiện, thay vì một sự trừu tượng.
Khái niệm — bên dưới lớp vỏ
Hạ tầng (Terraform). Chạy setup.sh sẽ cấp phát:
- Warehouse —
TRANSFORM_WH(SMALL, cho ELT) vàANALYTICS_WH(MEDIUM, cho BI), cùng một resource monitor (ANALYTICS_WH_MONITOR) giới hạn ở 50 credit/tháng. - Database —
NYC_TAXI_DB, với ba schema:RAW,STAGING,ANALYTICS. - Role —
TRANSFORMER_ROLE,ANALYST_ROLE,DBT_ROLE,LOADER_ROLE.
Dáng hình Medallion. Dữ liệu đi qua ba tầng bên trong NYC_TAXI_DB:
- RAW —
TRIPS_RAW(50M dòng chuyến đi tổng hợp, bao gồm một cộtVARIANTTRIP_METADATAmô phỏng telemetry của ứng dụng — đây chính là thử thách di chuyển JSON) cùng các bảng chiều (DIM_TAXI_ZONES,DIM_PAYMENT_TYPE,DIM_VENDOR). - STAGING — các view dbt làm sạch kiểu dữ liệu và làm phẳng cột
VARIANT. - ANALYTICS — các bảng dbt và model incremental:
fact_trips(50M dòng, chiến lượcMERGE), bốn bảng chiều, vàagg_hourly_zone_trips(một bảng tổng hợp incremental).
Hai đối tượng Snowflake giữ cho pipeline này tự chạy, độc lập với dbt:
TRIPS_CDC_STREAM— một stream Change Data Capture trênTRIPS_RAW.CDC_CONSUME_TASK— đọc stream đó mỗi 5 phút (chạy trongRAW, được resume trong lúc setup) — vàHOURLY_AGG_TASK, làm mới bảng tổng hợp theo giờ mỗi giờ một lần (chạy trongSTAGING, được resume sau khi dbt build xong).
Superset. Cả ba dashboard đều đọc từ schema ANALYTICS thông qua ANALYTICS_WH — không
dashboard nào chạm trực tiếp vào RAW hay STAGING. Chính đường đọc đó là thứ bạn sẽ tái
tạo ở phía ClickHouse về sau trong workshop.
Bước 1 — Cấu hình credential
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
cp .env.example .env
# Edit .env with your Snowflake credentials
cp dbt/nyc_taxi_dbt/profiles.yml.example ~/.dbt/profiles.yml
# Edit ~/.dbt/profiles.yml with your account detailsCả .env và ~/.dbt/profiles.yml đều đã được gitignore — chúng chứa account, user và
password Snowflake của bạn. Đừng bao giờ commit một trong hai file đó.
Bước 2 — Chạy setup
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
source .env && ./setup.shHãy chờ 5-10 phút, phần lớn thời gian dành cho việc sinh 50M dòng dữ liệu chuyến đi tổng
hợp bằng TABLE(GENERATOR). setup.sh cấp phát hạ tầng Terraform, nạp dữ liệu mồi vào
TRIPS_RAW, chạy dbt build, và khởi động Docker Compose (producer chuyến đi và Superset)
trong một lượt.
Bước 3 — Khởi động producer và Superset
setup.sh khởi động Docker Compose với môi trường đúng, đăng ký kết nối Snowflake trong
Superset, và tự động import cả ba dashboard.
Các file ZIP dashboard đã commit trong superset/dashboards/ có sqlalchemy_uri được ẩn
thành placeholder (LAB_USER, MYORG-MYACCOUNT). Bước auto-import sẽ dập lại URI từ file
.env của bạn, nên chuyện này diễn ra trong suốt khi setup.sh chạy. Nếu bạn tự import một
file ZIP thủ công qua UI của Superset, kết nối mà nó tạo ra sẽ dùng các placeholder đó và sẽ
không kết nối được — hãy sửa kết nối sau đó để trỏ đến account Snowflake thật của bạn.
Nếu bạn cần khởi động lại Superset thủ công:
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake/superset"
docker-compose --env-file ../.env up -dCờ --env-file ../.env nạp các biến môi trường từ thư mục cha.
Ba dashboard đó là Operations Command Center, Executive Weekly Report và Driver & Quality Analytics (cố tình chậm — nó là mục tiêu benchmark ClickHouse về sau trong workshop). Để xem cách dựng dashboard đầy đủ — nguồn dữ liệu, chart, filter — xem Superset trên Snowflake.
Bước 4 — Giữ dbt luôn cập nhật
Producer chuyến đi liên tục chèn khoảng 60 chuyến/phút vào TRIPS_RAW. Để giữ fact_trips
và agg_hourly_zone_trips luôn cập nhật trong lúc bạn làm việc, hãy chạy vòng lặp refresh
dbt trong một terminal riêng:
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
# Default: refresh every 5 minutes (auto-sources .env)
./scripts/run_dbt.sh
# Custom interval
./scripts/run_dbt.sh --interval 15m
# Run once and exit
./scripts/run_dbt.sh --once
# Include dbt tests after each run
./scripts/run_dbt.sh --test| Cờ | Tác dụng |
|---|---|
--interval <n> | Khoảng thời gian giữa các lượt chạy: 30s, 5m, 1h, hoặc số giây thuần (mặc định: 5m) |
--once | Chạy một lượt refresh duy nhất rồi thoát |
--test | Chạy dbt test sau mỗi dbt run |
Script luôn chạy theo kiểu incremental — nó không bao giờ thực hiện --full-refresh, nên
các dòng do producer chèn vào được giữ nguyên. Nhấn Ctrl-C bất cứ lúc nào để dừng nó; hãy để
nó chạy trong terminal riêng suốt phần còn lại của lab — module 03 vẫn dựa vào nó.
Bước 5 — Khám phá thư viện truy vấn
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"Thư mục truy vấn (workshop_public/snowflake_migration_lab/01-setup-snowflake/queries/)
chứa bảy file SQL có chú giải. Mỗi file chạy được trên môi trường Snowflake bạn vừa dựng, và
mỗi file mang một thử thách di chuyển cố ý mà module 02 sẽ dịch sang ClickHouse:
| Truy vấn | Cấu trúc | Thử thách di chuyển |
|---|---|---|
| Q1 | DATE_TRUNC, DATEADD | Khác biệt cú pháp nhỏ |
| Q2 | Window ROWS BETWEEN | Gần như giống hệt trong ClickHouse |
| Q3 | QUALIFY | Được hỗ trợ native trong ClickHouse từ v24.5 — ở đây vẫn viết lại thành subquery, để dễ mang đi |
| Q4 | LATERAL FLATTEN | Không có tương đương — dùng JSONExtract hoặc làm phẳng trước |
| Q5 | Đường dẫn dấu hai chấm của VARIANT | Thay bằng JSONExtractFloat/JSONExtractString |
| Q6 | MERGE INTO | Không có tương đương — dùng ReplacingMergeTree |
| Q7 | Snowflake Streams | Bị loại bỏ khi cutover — các lượt ghi trực tiếp đi thẳng vào ClickHouse qua producer |
Hãy mở từng file và chạy nó trên môi trường Snowflake của bạn trước khi đi tiếp. Khối comment trong mỗi truy vấn đã phác sẵn phần tương đương trong ClickHouse — module 02 là nơi bạn viết và chạy phía đó một cách thực sự.
Cách kiểm tra bạn đã xong
cd "$(git rev-parse --show-toplevel)/workshop_public/snowflake_migration_lab/01-setup-snowflake"
source .env && ./scripts/verify_environment.shScript này kiểm tra:
- Database & schema —
NYC_TAXI_DBtồn tại vớiRAW,STAGING,ANALYTICS. - Bảng & dữ liệu —
TRIPS_RAWcó ~50M dòng,FACT_TRIPSđã có dữ liệu, các bảng chiều tồn tại. - Stream CDC —
TRIPS_CDC_STREAMtồn tại trênTRIPS_RAW. - Task theo lịch —
CDC_CONSUME_TASKvàHOURLY_AGG_TASKđang ở trạng tháistarted. - Hoạt động CDC — các task đã chạy gần đây.
- Luồng từ producer — producer chuyến đi đang chèn dữ liệu liên tục.
- Superset — các dashboard BI truy cập được ở
http://localhost:8088.
Nếu bạn muốn tự kiểm tra bằng tay, lệnh SHOW TASKS LIKE '%TASK' IN DATABASE NYC_TAXI_DB;
chạy với role ACCOUNTADMIN (các task thuộc quyền sở hữu của role đó) sẽ xác nhận cả hai
task đang chạy.
Tổng kết
Bạn sẽ quay lại môi trường này nhiều lần trong vài module tới, và một lượt ./setup.sh đầy
đủ tốn 5-10 phút mà bạn không muốn phải trả mỗi lần chỉnh một file Terraform hay một model
dbt. setup.sh nhận các cờ dành riêng cho việc đó:
| Cờ | Khi nào dùng |
|---|---|
| (không có) | Lần chạy đầu tiên. Cấp phát mọi thứ và sinh 50M dòng tổng hợp (~12 phút tổng cộng). |
--skip-seed | Hạ tầng đã tồn tại và TRIPS_RAW đã có dữ liệu. Bỏ qua bước sinh dữ liệu tổng hợp (tiết kiệm ~8 phút). |
--skip-dbt | Các đối tượng Snowflake đã tồn tại nhưng bạn không cần chạy lại các phép biến đổi dbt (ví dụ khi kiểm thử thay đổi Terraform). |
--skip-superset | Docker không chạy hoặc bạn chưa cần tầng BI. |
--full-refresh | Buộc dbt dựng lại toàn bộ model incremental từ đầu (ví dụ sau một thay đổi schema). |
Các cờ có thể kết hợp. Hai kết hợp phổ biến:
# Re-run after a Terraform or SQL change — skip the ~10 min data load
./setup.sh --skip-seed
# Iterate on dbt models only — skip everything else
./setup.sh --skip-seed --skip-supersetLưu ý về chi phí. Việc nạp dữ liệu mồi chạy khoảng 12 phút và tốn 2 credit ($6), còn một
lượt dbt build đầy đủ chạy khoảng 8 phút và tốn 1.5 credit ($5). Một buổi lab đối tác dài 8
giờ cộng thêm khoảng 12 credit nữa (~$36) — warehouse tự động suspend khi rảnh, nên chi phí
ngừng phát sinh giữa các buổi. Tổng mỗi đối tác mỗi ngày là khoảng 16 credit, tức khoảng $47.
Trạng thái kết thúc
Snowflake đang hoạt động: NYC_TAXI_DB đã được dựng đầy đủ, stream CDC và cả hai task theo
lịch đang chạy, producer chuyến đi đang ghi khoảng 60 chuyến/phút vào TRIPS_RAW, và cả ba
dashboard Superset đã sẵn sàng ở http://localhost:8088.
Hãy để producer tiếp tục chạy. Đừng dừng stack Docker Compose và đừng chạy
./teardown.sh — các module 02 đến 05 phụ thuộc vào việc môi trường này vẫn còn sống, và
bước cutover ở module 05 đo chính xác khoảng trống mà producer tạo ra giữa Snowflake và
ClickHouse trong lúc di chuyển. Dỡ bỏ bây giờ sẽ làm phần còn lại của workshop thất bại theo
cách rất khó truy về bước này. Việc dỡ bỏ được trình bày ở cuối module 05, không phải ở đây.
00 Chuẩn bị
Cài bộ công cụ, tạo hai tài khoản dùng thử trên cloud, clone repo, và dựng cả hai virtualenv dbt — mọi thứ cuộc di chuyển cần trước khi bạn chạm vào dữ liệu.
02 Lập kế hoạch và thiết kế
Phân tích đặc tính workload Snowflake, rồi đưa ra các quyết định kiến trúc mà cuộc di chuyển sẽ thực thi — chọn engine, sort key, dịch schema, các đợt triển khai và thiết kế model dbt.