Snowflake MigrationClickHouse Workshops

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.

Môi trường nguồn Snowflake: một generator tổng hợp chạy một lần và một producer chuyến đi trên Docker chạy liên tục chèn dữ liệu vào NYC_TAXI_DB, nơi ba dashboard Superset đọc qua analytics warehouse

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ột VARIANT TRIP_METADATA mô 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ược MERGE), 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ên TRIPS_RAW.
  • CDC_CONSUME_TASK — đọc stream đó mỗi 5 phút (chạy trong RAW, đượ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 trong STAGING, được resume sau khi dbt build xong).

Bên trong NYC_TAXI_DB: TRIPS_RAW với một cột metadata VARIANT nạp dữ liệu cho một CDC stream và một task consume theo lịch, trong khi dbt dựng các view staging rồi đến các bảng fact, chiều và tổng hợp theo giờ

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 details

Cả .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.sh

Hã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 -d

Cờ --env-file ../.env nạp các biến môi trường từ thư mục cha.

Nguồn dữ liệu của dashboard Superset: ba dashboard vận hành đọc schema analytics thông qua analytics warehouse

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)
--onceChạy một lượt refresh duy nhất rồi thoát
--testChạ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ấnCấu trúcThử thách di chuyển
Q1DATE_TRUNC, DATEADDKhác biệt cú pháp nhỏ
Q2Window ROWS BETWEENGần như giống hệt trong ClickHouse
Q3QUALIFYĐược hỗ trợ native trong ClickHouse từ v24.5 — ở đây vẫn viết lại thành subquery, để dễ mang đi
Q4LATERAL FLATTENKhô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 VARIANTThay bằng JSONExtractFloat/JSONExtractString
Q6MERGE INTOKhông có tương đương — dùng ReplacingMergeTree
Q7Snowflake StreamsBị 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.sh

Script này kiểm tra:

  1. Database & schema — NYC_TAXI_DB tồn tại với RAW, STAGING, ANALYTICS.
  2. Bảng & dữ liệu — TRIPS_RAW có ~50M dòng, FACT_TRIPS đã có dữ liệu, các bảng chiều tồn tại.
  3. Stream CDC — TRIPS_CDC_STREAM tồn tại trên TRIPS_RAW.
  4. Task theo lịch — CDC_CONSUME_TASK và HOURLY_AGG_TASK đang ở trạng thái started.
  5. Hoạt động CDC — các task đã chạy gần đây.
  6. Luồng từ producer — producer chuyến đi đang chèn dữ liệu liên tục.
  7. 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-seedHạ 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-dbtCá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-supersetDocker không chạy hoặc bạn chưa cần tầng BI.
--full-refreshBuộ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-superset

Lư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.

Trên trang này

Track your progress?

Optional. We email a link to confirm your address; progress records once you open it.

Please use your work email address, not a personal one.

Progress tracking also requires accepting the current Terms of Service in Privacy settings.

VI