Chuyển đến nội dung chính

Cách sử dụng dbt với Snowflake: Hướng dẫn toàn diện

Tìm hiểu cách tích hợp dbt với Snowflake cho quy trình dữ liệu hiện đại. Bao gồm thiết lập, biến đổi, bảo mật, CI/CD và tối ưu hiệu năng.
· 15 phút đọc

Khám phá cùng AI

Khi các nhóm dữ liệu hiện đại áp dụng những ngăn xếp phân tích ngày càng phức tạp, xu hướng đang chuyển sang xây dựng các thực hành chuẩn trong quy trình kỹ thuật dữ liệu. Các công cụ như dbt (Data Build Tool) là một khung nguồn mở đưa các thực hành tốt nhất của kỹ thuật phần mềm—như quản lý phiên bản, kiểm thử và tài liệu—vào quy trình phân tích. 

Sự kết hợp giữa dbt và Snowflake (một kho dữ liệu thuần đám mây) đã trở thành nền tảng của quy trình analytics engineering. Hướng dẫn này khám phá các khái niệm nền tảng, cách thiết lập và các chiến lược triển khai nâng cao để tích hợp dbt với Snowflake, giúp các nhóm dữ liệu xây dựng pipeline dễ bảo trì, an toàn và hiệu năng cao hơn.

Nếu bạn mới bắt đầu với các công cụ này, tôi khuyến nghị bạn tham gia lộ trình kỹ năng Snowflake Foundations và khóa học Giới thiệu về dbt. 

dbt–Snowflake: Khái niệm nền tảng và lợi ích

Hãy nói về cách dbt và Snowflake phối hợp với nhau. Phần này giới thiệu khả năng của dbt, mức độ tương thích với Snowflake và lợi ích khi tích hợp chúng.

dbt (Data Build Tool) là gì?

dbt (Data Build Tool) là một khung nguồn mở cho phép các nhóm dữ liệu biến đổi, kiểm thử và tạo tài liệu cho dữ liệu trực tiếp trong kho dữ liệu bằng SQL được tăng cường với Jinja templating. 

dbt không phải là một ngôn ngữ lập trình; nó hoạt động như một bộ biên dịch, nhận các mô hình SQL dạng mô-đun và chuyển chúng thành các truy vấn SQL có thể thực thi chạy trong kho dữ liệu (ví dụ, Snowflake). 

Bằng cách kết hợp quản lý phiên bản, kiểm thử tự động và tài liệu, dbt đưa các thực hành đã được kiểm chứng của kỹ thuật phần mềm vào analytics engineering, giúp pipeline biến đổi đáng tin cậy, dễ bảo trì và có thể mở rộng trong quy trình ELT.

Các thành phần cốt lõi của nó gồm một bộ biên dịch và một bộ chạy. Chức năng của chúng:

  • Compiler: người dùng dbt viết mã bằng Jinja, được biên dịch thành SQL thô.
  • Runner: Chúng ta thực thi mã đã biên dịch trên kho dữ liệu như Snowflake để lấy kết quả.

Để dbt hoạt động, có một vài thành phần cơ bản hỗ trợ dòng chảy tổng thể:

  • Models: Các câu lệnh select cốt lõi được lưu thành tệp .sql.
  • Seeds: các tệp .csv mà dbt có thể nạp vào kho dữ liệu làm tham chiếu cho mô hình của bạn.
  • Sources: Dữ liệu trong kho dữ liệu mà bạn muốn trích xuất.
  • Data Tests: các tệp .sql kiểm thử dữ liệu của bạn để đảm bảo tuân thủ quy tắc.
  • Documentation: dbt hỗ trợ trang tài liệu có thể hiển thị cây phụ thuộc của mô hình.

Để biết thêm chi tiết về dbt, tôi khuyến nghị khóa học giới thiệu về dbt xuất sắc này.

Tổng quan về tích hợp dbt và Snowflake

Kết hợp Jinja templating của dbt với các kiểu dữ liệu mạnh mẽ của Snowflake như Streams, chúng ta có thể rất sáng tạo trong các quy trình biến đổi.

Ví dụ, có thể chúng ta chỉ muốn biến đổi dữ liệu mới nạp hoặc áp dụng các biến đổi khác nhau giữa bảng staging và bảng prod để kiểm tra sức khỏe dữ liệu. 

Cặp đôi này nhanh chóng trở nên phổ biến để giúp kỹ sư dữ liệu có nhiều kiểm soát và linh hoạt hơn với pipeline, khi ngày càng nhiều công ty thường xuyên áp dụng dbt.

Lợi ích của việc dùng dbt

Có nhiều lợi ích với dbt: phương pháp phát triển phần mềm truyền thống, kiểm thử tự động và tăng năng suất. 

Phát triển dựa trên mã

Chúng ta có thể xử lý dữ liệu và SQL giống như mã truyền thống. Điều này mang lại tính mô-đun, khả năng kiểm thử và quản lý phiên bản. Tận dụng template và các câu lệnh điều khiển luồng kiểu Python, chúng ta nhận được những chức năng mạnh mẽ từ dbt.

Kiểm thử tự động

Sử dụng cấu hình data_test tích hợp của dbt, chúng ta có thể thường xuyên chạy kiểm thử với dữ liệu mà không cần pipeline SQL rối rắm. Thực tế, dbt đã có sẵn một số kiểm thử cơ bản mạnh mẽ có thể triển khai dễ dàng trong tệp cấu hình.

Tăng năng suất

Trong dbt có các công cụ như tạo tài liệu tự động và trực quan hóa pipeline. Thành viên mới có thể onboard nhanh hơn và thành viên hiện tại hiểu sâu hơn về luồng dữ liệu. Điều này giúp giảm thời gian làm quen và cải thiện hiểu biết chung về quy trình.

Lợi ích của việc dùng Snowflake

Có nhiều lợi ích khi dùng nền tảng đám mây của Snowflake. Kiến trúc tách lưu trữ và tính toán giúp giảm xung đột tài nguyên và tối ưu chi phí. Nó sử dụng zero-copy cloning, cho phép tạo bản sao cơ sở dữ liệu mà không tốn thêm lưu trữ. 

Ngoài ra, Snowflake hỗ trợ một số kiểu bảng phức tạp như dynamic tables và Streams, cho phép logic làm mới theo từng phần. Để biết thêm chi tiết về Snowflake, hãy xem bài viết giải thích cách Snowflake hoạt động.

Quan trọng hơn, các tính năng này rất bổ trợ cho dbt. Chúng ta có thể tận dụng làm mới theo từng phần để giúp dbt kích hoạt biến đổi dựa trên dữ liệu mới. Ta cũng có thể tận dụng việc tách tính toán và lưu trữ của Snowflake, cho phép dbt thực hiện các biến đổi tính toán nặng mà không ảnh hưởng đến khả năng tải và lưu trữ dữ liệu.

Tất cả đi kèm với khả năng mở rộng nhanh của Snowflake và mô hình chi phí trả theo mức dùng. Khi độ phức tạp của script dbt tăng, chúng ta có thể dễ dàng nâng cấp kích thước warehouse tính toán của Snowflake để đáp ứng. Đồng thời, có thể dùng giám sát của Snowflake để thu gọn warehouse và dùng dbt để tinh gọn hiệu năng truy vấn.

Các điểm cộng hưởng chính giữa dbt và Snowflake

Khi kết hợp, Snowflake và dbt hỗ trợ nhau rất tốt. Việc tinh chỉnh liên tục của Snowflake giúp giữ chi phí đám mây thấp. dbt có thể tận dụng phương pháp phân vùng bảng như clustering keys và bộ nhớ đệm của Snowflake để giảm chi phí dữ liệu.

Snowflake không dễ được quản lý bằng các công cụ như Git. Vì dbt được xây trên các nguyên tắc tương tự ngôn ngữ lập trình, chúng ta có thể dùng quy trình làm việc dựa trên Git để quản lý phát triển dễ hơn với CI/CD. Điều này giúp quản lý phiên bản cho pipeline, vốn khó nếu làm hoàn toàn trong Snowflake.

Để giúp nhà phát triển cộng tác dễ hơn, dbt cũng có giao diện UI hiển thị toàn bộ job dbt ở một nơi. Điều này hỗ trợ nhóm theo dõi quy trình và đảm bảo chạy đúng. Gần đây dbt cũng giới thiệu Studio IDE cho phép tích hợp Git và cơ sở dữ liệu dễ dàng cùng quy trình kiểm thử. Một số nhóm thậm chí chọn dùng UI của Snowflake để tích hợp đầy đủ.

Nhiều nhóm dữ liệu đã bắt đầu sử dụng chung dbt và Snowflake để khai thác tối đa cơ sở dữ liệu của họ. Tiếp tục tìm hiểu về dbt trong giới thiệu thực hành dbt cho kỹ sư dữ liệu và tìm hiểu cách mô hình hóa dữ liệu Snowflake hoạt động qua khóa học này.

Từ Snowflake Quickstarts: Tăng tốc với dbt Core & Snowflake

Triển khai và cấu hình dbt Snowflake

Hãy cùng điểm qua một số cơ bản về cách cấu hình Snowflake và dbt để tích hợp đúng. Chúng ta cũng sẽ đề cập một số thực hành tốt về thiết kế cấu trúc dự án.

Điều kiện tiên quyết và thiết lập

Chúng ta sẽ bắt đầu với thiết lập cơ sở dữ liệu Snowflake rồi đến thiết lập dbt. 

Điều kiện tiên quyết cho Snowflake

Bạn sẽ cần một cơ sở dữ liệu, schema và virtual warehouse riêng để lưu dữ liệu dbt. Ngoài ra, bạn cần một vai trò người dùng dbt cụ thể để dbt truy cập. Khi thiết lập dbt, bạn sẽ cung cấp thông tin xác thực của người dùng đó để dbt giao tiếp với Snowflake. Trong phần này, tôi sẽ đưa ra một vài hướng dẫn cơ bản, nhưng để biết thêm chi tiết về quản lý cơ sở dữ liệu và vai trò người dùng trong Snowflake, vui lòng tham khảo khóa học Giới thiệu về Snowflake.

  1. Tạo cơ sở dữ liệu, schema và virtual warehouse riêng
	CREATE DATABASE analytics_db;
	CREATE SCHEMA analytics_db.transformations;
	CREATE WAREHOUSE dbt_wh
	  WITH WAREHOUSE_SIZE = 'XSMALL'
	  AUTO_SUSPEND = 60
	  AUTO_RESUME = TRUE
	  INITIALLY_SUSPENDED = TRUE;
	
  1. Tạo vai trò và người dùng dbt riêng. Điều này rất quan trọng để cho phép dbt truy cập máy chủ Snowflake của bạn
	CREATE ROLE dbt_role;
	GRANT USAGE ON WAREHOUSE dbt_wh TO ROLE dbt_role;
	GRANT USAGE ON DATABASE analytics_db TO ROLE dbt_role;
	GRANT USAGE, CREATE SCHEMA ON DATABASE analytics_db TO ROLE dbt_role;
	GRANT ALL PRIVILEGES ON SCHEMA analytics_db.transformations TO ROLE dbt_role;

	CREATE USER dbt_user PASSWORD='StrongPassword123'
	  DEFAULT_ROLE = dbt_role
	  DEFAULT_WAREHOUSE = dbt_wh
	  DEFAULT_NAMESPACE = analytics_db.transformations;
	GRANT ROLE dbt_role TO USER dbt_user;
	
  1. Cuối cùng, tìm tên tài khoản Snowflake của bạn. Chúng ta sẽ cần sau khi thiết lập dbt. Có thể tìm trong phần cài đặt và chi tiết tài khoản của Snowflake. Vui lòng tham khảo tài liệu Snowflake để biết thêm chi tiết.

Cấu hình dbt

Để chạy dbt, chúng ta sẽ cài đặt bằng pip và cấu hình tệp profiles.yml.

  1. Cài đặt dbt trong môi trường Python của bạn. Bạn sẽ cần cả gói dbt-core và dbt-snowflake
pip install dbt-core dbt-snowflake
  1. Cấu hình tệp profiles.yml và lưu vào ~/.dbt/profiles.yml
snowflake-db:
  target:dev
  outputs:
    dev:
      type: snowflake
      account: [account_id from earlier]
      user: [dbt_user]
      password: [dbt_pw]
      role: [dbt_role]
      warehouse:[dbt_warehouse]
      database: [dbt_database]
      schema: [dbt_schema]
      threads: 4
      client_session_keep_alive: False
      query_tag: [anything]
  1. Khởi tạo một dự án dbt
dbt init --profile snowflake-db
  1. (Cách khởi tạo thay thế) Nếu bạn không muốn cấu hình trước tệp YAML, bạn có thể đi qua các bước khởi tạo của dbt bằng lệnh sau.
dbt init snowflake-profile-name

Lệnh này sẽ hướng dẫn từng bước và tạo tệp profiles.yml nếu cần!

  1. Để chắc chắn kết nối hoạt động, chúng ta có thể dùng chức năng debug:
dbt debug --connection

Lệnh này sẽ kiểm tra cài đặt kết nối của bạn có hợp lệ hay không và báo lỗi nếu không.

Điều cần cân nhắc: thay vì ghi trực tiếp user và password trong tệp profiles.yml, hãy thử dùng biến môi trường. Ví dụ, dbt_password có thể lưu vào biến môi trường SNOWFLAKE_PASSWORD. Sau đó trong profiles.yml bạn viết password: “{{env_var(‘SNOWFLAKE_PASSWORD’)}}”. Điều này giúp tránh lộ thông tin xác thực trong tệp cấu hình và tăng thêm một lớp bảo mật.

Thiết lập quản lý phiên bản

Kết nối với Git giúp khai thác tối đa cấu hình dbt của bạn. Các bước chính xác có thể khác nếu bạn làm trong môi trường doanh nghiệp. Nguyên tắc chung khá đơn giản: Tạo một repository trên GitHub hoặc GitLab. Sau đó liên kết tài khoản dbt của bạn với tài khoản GitHub/GitLab. Khi xong, bạn có thể git clone repository của mình! Để biết thêm thông tin kết nối Git với dbt, hãy xem tài liệu Git của dbt cho nền tảng cụ thể của bạn.

Thiết kế cấu trúc dự án

Một cấu trúc dự án nhất quán và theo mẫu giúp dự án mới khởi động nhanh hơn bằng cách quy định rõ nơi đặt mọi thứ. 

Tổ chức models

Chia dự án thành các thư mục staging, intermediate và marts. Bên trong mỗi phần, bạn có thể xác định các phòng ban khác nhau với mô hình và SQL riêng. 

	models/
	│   ├── intermediate
	│   │   └── finance
	│   │       ├── _int_finance__models.yml
	│   │       └── int_payments_pivoted_to_orders.sql
	│   ├── marts
	│   │   ├── finance
	│   │   │   ├── _finance__models.yml
	│   │   │   ├── orders.sql
	│   │   │   └── payments.sql
	│   │   └── marketing
	│   │       ├── _marketing__models.yml
	│   │       └── customers.sql
	│   ├── staging
	│   │   ├── jaffle_shop
	│   │   │   ├── _jaffle_shop__docs.md
	│   │   │   ├── _jaffle_shop__models.yml
	│   │   │   ├── _jaffle_shop__sources.yml
	│   │   │   ├── base
	│   │   │   │   ├── base_jaffle_shop__customers.sql
	│   │   │   │   └── base_jaffle_shop__deleted_customers.sql
	│   │   │   ├── stg_jaffle_shop__customers.sql
	│   │   │   └── stg_jaffle_shop__orders.sql
	│   │   └── stripe
	│   │       ├── _stripe__models.yml
	│   │       ├── _stripe__sources.yml
	│   │       └── stg_stripe__payments.sql
	│   └── utilities
	│       └── all_dates.sql/

Mỗi thư mục trong models có một mục đích:

  • Staging: Dữ liệu thô đã được làm sạch, đổi tên.
  • Intermediate: Các phép nối hoặc biến đổi nặng logic.
  • Marts: Bảng cuối phục vụ nghiệp vụ.

Với các tệp cấu hình của models thuộc staging, intermediate và marts, bạn có thể đặt cấu hình +materialized để xác định cách xuất SQL được tạo trong Snowflake. Chúng ta có thể chọn view, table hoặc incremental dataset:

  • View: Mặc định, nhẹ.
  • Table: Có bộ đệm nhưng dùng nhiều lưu trữ hơn.
  • Incremental: Cho tập dữ liệu lớn thường xuyên bổ sung.

Cấu hình có thể trông như sau:

# The following dbt_project.yml configures a project that looks like this:
# .
# └── models
#     ├── csvs
#     │   ├── employees.sql
#     │   └── goals.sql
#     └── events
#         ├── stg_event_log.sql
#         └── stg_event_sessions.sql

name: my_project
version: 1.0.0
config-version: 2

models:
  my_project:
    events:
      # materialize all models in models/events as tables
      +materialized: table
    csvs:
      # this is redundant, and does not need to be set
      +materialized: view

Tối ưu nâng cao và Macros

Một lợi thế lớn khi tích hợp dbt và Snowflake là chúng ta nhận được tối ưu từ cả hai nền tảng. Với Snowflake, có nhiều cách xử lý truy vấn để chạy nhanh hơn. Với dbt, ta có thể tối ưu mã bằng macro và kỹ thuật materialization.

Kỹ thuật tinh chỉnh hiệu năng

Có một số tính năng độc đáo của Snowflake mà ta có thể tận dụng để cải thiện hiệu năng truy vấn. 

Tối ưu truy vấn

Hai cách tối ưu lớn trong Snowflake là predicate pushdown và clustering keys. 

Predicate pushdown là ý tưởng thay đổi thời điểm Snowflake lọc dữ liệu để đọc ít dữ liệu hơn. Ví dụ, hình dung chúng ta truy vấn với hai lớp lọc: một lọc bảo mật và một lọc phân loại. 

Lọc bảo mật xác định ai có thể xem phần nào của bảng dựa trên vai trò. Lọc phân loại nằm trong mệnh đề WHERE của truy vấn. Snowflake sẽ chọn bộ lọc chạy trước sao cho cần đọc ít dữ liệu nhất.

Để hỗ trợ predicate pushdown, chúng ta có thể cân nhắc clustering keys. Dù Snowflake làm khá tốt việc gom cụm bảng, khi dữ liệu đạt nhiều TB, việc duy trì phân vùng hợp lý trở nên khó khăn. 

Bằng cách định nghĩa clustering keys, ta giúp Snowflake phân vùng dữ liệu phù hợp với cách ta thường truy vấn bảng. Ví dụ, có thể ta chọn hai cột luôn đi cùng nhau như ngày và loại tài sản. Mỗi loại tài sản có số lượng ngày đủ nhỏ khiến việc tái phân vùng hợp lý và xác định vị trí dữ liệu hiệu quả. 

Kết hợp clustering keys với tối ưu predicate pushdown của Snowflake có thể giúp điều hướng các bảng lớn hiệu quả hơn nhiều.

Mở rộng warehouse

Việc dùng tài nguyên trong hệ thống trả theo mức dùng như Snowflake rất quan trọng! Bạn nên tuân theo một vài nguyên tắc đơn giản:

  • Dùng auto-suspend của Snowflake để tạm dừng warehouse khi pipeline của bạn không chạy trong thời gian dài
  • Khi truy cập lại warehouse sau một thời gian, auto-resume sẽ khởi động lại warehouse khi cần
  • Đảm bảo dùng warehouse XS hoặc S cho phát triển và mở rộng khi cần cho sản xuất

Những điều chỉnh warehouse đơn giản này sẽ giúp việc sử dụng Snowflake hiệu quả hơn về lâu dài.

Dynamic Tables so với incremental models

Ở phía dbt, chúng ta có thể tận dụng dynamic tables và incremental models để đơn giản hóa logic cập nhật. 

Dynamic Tables là một kiểu bảng trong Snowflake tự động làm mới dựa trên thời gian trễ được định nghĩa. dbt có khả năng materialize dynamic tables như một phần của cấu hình và thiết lập tương tự như trong Snowflake.

models:
  <resource-path>:
    +materialized: dynamic_table
    +on_configuration_change: apply | continue | fail
    +target_lag: downstream | <time-delta>
    +snowflake_warehouse: <warehouse-name>
    +refresh_mode: AUTO | FULL | INCREMENTAL
    +initialize: ON_CREATE | ON_SCHEDULE

Điều này thuận tiện cho pipeline chuyển tải dữ liệu đơn giản mà không cần SQL phức tạp. Phần hay nhất là chúng ta có thể kết nối tới các dynamic tables này và có dữ liệu mới khi cần.

Một cách linh hoạt khác để xây dựng bảng là dùng incremental model. Khi viết SQL, chúng ta lọc theo một cột cho biết dữ liệu nào là mới. Sau đó dùng macro is_incremental() để cho dbt biết chỉ áp dụng bộ lọc đó khi cấu hình materialized incremental table. 

SQL mẫu của bạn có thể trông giống như sau, từ tài liệu dbt:

{{
    config(
        materialized='incremental'
    )
}}

select
    *,
    my_slow_function(my_column)

from {{ ref('app_data_events') }}

{% if is_incremental() %}

  -- this filter will only be applied on an incremental run
  -- (uses >= to include records whose timestamp occurred since the last run of this model)
  -- (If event_time is NULL or the table is truncated, the condition will always be true and load all records)
where event_time >= (select coalesce(max(event_time),'1900-01-01') from {{ this }} )

{% endif %}

Tái sử dụng logic với macros

Bạn vừa thấy tôi nhắc đến “macro”. Đây là các đoạn mã có thể tái sử dụng trong dbt. Có thể là phép tính dùng lại nhiều lần hoặc các biến đổi xảy ra thường xuyên. 

Macro dành riêng cho Snowflake

Chúng ta tạo macro bằng Jinja templating. Một trường hợp phổ biến là clone cơ sở dữ liệu trước khi làm việc.

	{% macro clone_tables(table_to_clone) -%}

	–- shows all tables within a schema
	    {% set all_tables_query %}
	        show tables in schema {{ clone_tables }}
	    {% endset %}

	-- take the set results and use the run_query macro
	    {% set results = run_query(all_tables_query) %}

	    {{ "create or replace schema " ~ generate_schema_name(var("custom_tables_list")) ~ ";" }}

	--execute the cloning function
	    {% if execute %}
	        {% for result_row in results %}
	            {{ log("create table " ~ generate_schema_name(var("custom_tables_list")) ~ "." ~ result_row[1] ~ " clone " ~ clone_tables~ "." ~ result_row[1] ~ ";") }}
	            {{ "create table " ~ generate_schema_name(var("custom_tables_list")) ~ "." ~ result_row[1] ~ " clone " ~ clone_tables~ "." ~ result_row[1] ~ ";" }}
	        {% endfor %}
	    {% endif %}
	{%- endmacro %}

Template này nhận một schema đầu vào, tạo danh sách bảng rồi clone chúng sang warehouse/schema được cung cấp trong cấu hình dbt. Bạn có thể dùng macro này trong mã dbt hoặc khi khởi chạy dbt.

Để luyện tập thêm Jinja trong dbt, tôi rất khuyến nghị case study xây dựng mô hình dữ liệu thương mại điện tử với dbt này. Nó hướng dẫn qua một số Jinja templating phức tạp với dbt và mang lại trải nghiệm thực hành nâng cao!

Che giấu PII với dbt:

Khi làm việc với thông tin khách hàng, có thể chúng ta gặp dữ liệu nhận dạng cá nhân (PII) và cần che dấu trong cơ sở dữ liệu. Điều này rất đơn giản với Snowflake! Chúng ta có thể dùng CREATE MASKING POLICY để cho Snowflake biết cột và kiểu dữ liệu nào cần che khi truy vấn. Các chính sách này đảm bảo không rò rỉ PII khi truy vấn thông tin nhạy cảm. 

Sau đó, chúng ta có thể dùng tests của dbt với SQL tùy chỉnh để kiểm tra các bảng che dữ liệu đúng. Ví dụ, nếu chúng ta định nghĩa một masking policy chỉ cho phép vai trò ANALYST thấy PII như sau:

	CREATE OR REPLACE MASKING POLICY email_mask AS (val string) returns string ->
	  CASE
	    WHEN current_role() IN ('ANALYST') THEN VAL
	    ELSE '*********'
	  END;

Khi đó, dùng vai trò người dùng dbt_account để truy vấn dữ liệu sẽ trả về chuỗi '*********'. 

Nếu bài kiểm thử của chúng ta đơn giản như:

	SELECT *
	FROM schema.table
	WHERE email <> '*********'

Nếu truy vấn này trả về kết quả, thì nên coi là thất bại. Không email nào được trả về khác với chuỗi đã che. Khi đó, chúng ta nên kiểm tra lại masking policy trên Snowflake và tiếp tục thử đến khi hoạt động đúng.

Bảo mật và quản trị

Như thường lệ, bảo mật là trụ cột chính của truy cập đám mây. Chúng ta sẽ điểm qua một số cơ bản về bảo mật và bảo vệ dữ liệu trong phần này.

Khung kiểm soát truy cập

Khung bảo mật chính của Snowflake là kiểm soát truy cập dựa trên vai trò (RBAC) và sử dụng tài khoản dịch vụ. 

RBAC (Role-Based Access Control)

Định nghĩa đặc quyền RBAC cho phép áp dụng cài đặt bảo mật cho một nhóm người dùng rộng mà không cần gán từng cá nhân. Điều này giúp dễ bảo trì. 

Như đã nêu ở trên, chúng ta tạo vai trò bằng câu lệnh CREATE ROLE. Để cấp quyền, dùng GRANT <privilege> … TO ROLE và ngược lại gỡ quyền bằng REVOKE <privilege> … FROM ROLE. 

Một số thực hành tốt:

  • Dùng vai trò dựa trên đặc quyền tối thiểu. Ví dụ, chỉ cho quyền đọc với vai trò dbt_reader, quyền tạo bảng với dbt_writer, và quyền xóa chỉ cho tài khoản quản trị như dbt_admin.
  • Cân nhắc tạo vai trò chỉ có quyền truy cập một số môi trường như dev, staging và prod.

Tài khoản dịch vụ

Tài khoản dịch vụ là các tài khoản máy móc đặc biệt tương tác không có con người. Các tài khoản này không dùng tên người dùng và mật khẩu. Thay vào đó, chúng dùng khóa công khai và giới hạn mạng để giảm thiểu rủi ro.

Tạo tài khoản dịch vụ có thể như sau:

CREATE USER dbt_service
RSA_PUBLIC_KEY = <keysring>

Bằng cách này, bạn có một tài khoản duy nhất do quản trị viên quản lý và không còn phải lo về từng người dùng. Khuyến nghị xoay vòng khóa thường xuyên để tránh rò rỉ. Đồng thời, hãy theo dõi chặt chẽ hoạt động mạng bằng LOGIN_HISTORY của Snowflake.

Bảo vệ dữ liệu

Bảo vệ dữ liệu và đăng nhập của bạn. Dù trong ví dụ chúng ta hardcode thông tin xác thực, thực tế đó là thực hành kém. Hãy dùng secret manager như AWS Secrets Manager hoặc GitHub Secrets để lưu thông tin xác thực quan trọng. 

Các công cụ này cho phép bạn lưu thông tin xác thực trực tuyến chỉ người dùng có khóa RSA/Bảo mật phù hợp mới truy cập được. Không ai nhìn thấy giá trị thực và việc xoay mật khẩu/khóa trở nên dễ dàng với quản lý tự động của chúng.

Đảm bảo mọi kết nối được bảo mật đúng cách và người dùng ở mạng doanh nghiệp phù hợp để truy cập dữ liệu. Điều này thường thiết lập bằng các VPN như GlobalProtect. Vì chúng ta kết nối tới Snowflake, rất nhiều mã hóa đầu-cuối được xử lý bởi đám mây. Lại là một lợi ích khác khi dùng Snowflake! 

Cuối cùng, chúng ta muốn kiểm toán hoạt động. Snowflake có ghi log truy vấn qua các bảng như QUERY_HISTORY và QUERY_HISTORY_BY_USER. Chúng ta có thể theo dõi mức sử dụng, lỗi và mọi lạm dụng bảo mật trong các log này. Thông qua dbt, chúng ta theo dõi lần chạy mới, thay đổi hoặc chỉnh sửa dự án bằng pipeline quản lý phiên bản.

Quản lý phiên bản và template mã giúp duy trì theo dõi thay đổi và tuân thủ. Bất kỳ vấn đề nào do thay đổi gây ra có thể được phát hiện dễ dàng trong các pull request bắt buộc và xử lý trước khi trở thành mối lo.

Giám sát và quản lý chi phí

Hãy bàn về cách tiết kiệm chi phí! Trong dbt, tất nhiên. Giám sát hiệu năng mô hình là điều tối quan trọng. Các mô hình từng chạy trơn tru có thể chậm dần khi kích thước bảng tăng.

Giám sát hiệu năng

Với dbt, cách tốt nhất để giám sát hiệu năng là dùng các gói tích hợp như dbt-snowflake-monitoring hoặc công cụ ngoài như Looker và Datafold để trực quan hóa và so sánh dữ liệu.

Cách dùng dbt-snowfake-monitoring

Bắt đầu với dbt-snowflake-monitoring khá dễ! Trong tệp packages.yml của dbt, thêm như sau:

packages:
  - package: get-select/dbt_snowflake_monitoring
    version: [">=5.0.0", "<6.0.0"] # We'll never make a breaking change without creating a new major version.

Sau đó, trong mỗi tệp YAML của dự án, thêm:

dispatch:
  - macro_namespace: dbt
    search_order:
      - <YOUR_PROJECT_NAME>
      - dbt_snowflake_monitoring
      - dbt
query-comment:
  comment: '{{ dbt_snowflake_monitoring.get_query_comment(node) }}'
  append: true # Snowflake removes prefixed comments.

Giờ bạn đã sẵn sàng dùng gói này để giám sát như mức dùng warehouse, thời lượng truy vấn và các mô hình thất bại! Nó dùng quyền truy cập hiện có của người dùng dbt để ghi các bảng vào Snowflake, chứa thông tin hữu ích. Ví dụ, nếu tôi muốn xem chi tiêu warehouse theo tháng, tôi có thể dùng SQL sau:

select
    date_trunc(month, date)::date as month,
    warehouse_name,
    sum(spend_net_cloud_services) as spend
from daily_spend
where service in ('Compute', 'Cloud Services')
group by 1, 2

Công cụ bên ngoài

Các công cụ bên ngoài như Looker hoặc Tableau có thể tích hợp trực tiếp với dbt để trực quan hóa dữ liệu và hiệu năng dễ dàng. Với cảnh báo, dbt có thể gửi email hoặc thông báo Slack.

Để so sánh sâu hơn, các stack ngoài như Datafold cung cấp hiểu biết sâu hơn về cách chất lượng dữ liệu bị ảnh hưởng bởi thay đổi. Datafold tự động tạo data diff với mỗi thay đổi mã bạn thực hiện. Điều này cho phép thành viên khác dễ dàng rà soát mã và tác động lên dữ liệu. Loại kiểm thử hồi quy tự động này giúp chúng ta duy trì chất lượng dữ liệu mà không phải liên tục xây các kiểm tra và công cụ mới.

Kỹ thuật tối ưu chi phí

Chúng ta không thể tránh chạy quy trình ETL, nhưng có thể lên kế hoạch để giảm tác động chi phí tính toán và lưu trữ. Nhờ thiết kế tách biệt của Snowflake, ta có thể tối ưu warehouse và lưu trữ độc lập để mang lại môi trường tối ưu chi phí linh hoạt hơn.

Với warehouse, cách tốt nhất là giảm thời gian rảnh. Phân bổ các pipeline tự động càng đều càng tốt để giảm thời gian rảnh, các đợt tăng đột biến nhu cầu tính toán và cạnh tranh tài nguyên. 

Giám sát thường xuyên bằng các bảng WAREHOUSE_LOAD_HISTORY và QUERY_HISTORY để hiểu cách tài nguyên được dùng. Thực hành tốt là bắt đầu với XS. Nếu truy vấn chạy quá chậm, khi đó mới nâng cấp theo SLA của nhóm bạn.

Với lưu trữ, thực hành tốt là loại bỏ bảng không cần thiết. Dù bản thân Snowflake không có các tầng lưu trữ lạnh như AWS và Google, bạn có thể chọn chuyển dữ liệu từ Snowflake sang AWS/Google để dùng các tầng lạnh này và giảm chi phí lưu trữ. 

Các chính sách lưu giữ dữ liệu có thể nêu rõ mốc thời gian cho các bảng ít dùng và khi nào chúng sẽ được chuyển sang lưu trữ lạnh. 

Với các bảng lớn tăng trưởng thường xuyên, hãy theo dõi sát. Khi chúng lớn hơn, khả năng tự động phân vùng hiệu quả của Snowflake suy giảm. Tận dụng tự động clustering như đã đề cập để giúp Snowflake phân vùng dữ liệu tốt hơn. Phân vùng tốt giúp giảm thời gian đọc lưu trữ và tiết kiệm chi phí.

CI/CD và Tự động hóa

Nhờ tích hợp gốc của dbt với quản lý phiên bản, CI/CD và pipeline tự động trở nên dễ dàng. Chúng ta sẽ đề cập một số lựa chọn điều phối tự động và thực hành tốt về kiểm thử.

Điều phối pipeline

Với dbt Cloud, chúng ta có thể dùng Snowflake Tasks để kích hoạt chạy theo lịch cho các dự án dbt. Cách hoạt động là trước tiên tạo một dự án dbt trong Snowflake bằng repository Git của chúng ta, rồi tạo một task thực thi dự án đó. 

Ví dụ, chúng ta có thể làm như sau để tạo một dự án dbt:

CREATE DBT PROJECT sales_db.dbt_projects_schema.sales_model
  FROM '@sales_db.integrations_schema.sales_dbt_git_stage/branches/main'
  COMMENT = 'generates sales data models';

Sau đó dùng mã sau để chạy dự án đó:

CREATE OR ALTER TASK sales_db.dbt_projects_schema.run_dbt_project
  WAREHOUSE = sales_warehouse
  SCHEDULE = '6 hours'
AS
  EXECUTE DBT PROJECT sales_db.dbt_projects_schema.sales_model args='run --target prod';

Thực tế, nó còn toàn diện đến mức chúng ta có thể chạy kiểm thử sau đó để đảm bảo dự án chạy đúng:

CREATE OR ALTER TASK sales_db.dbt_projects_schema.test_dbt_project
        WAREHOUSE = sales_warehouse
        AFTER run_dbt_project
AS
  EXECUTE DBT PROJECT sales_db.dbt_projects_schema.test_dbt_project args='test --target prod';

Về lập lịch, chúng ta có thể đặt thời gian cố định như 60 MINUTES và 12 HOURS hoặc dùng cron như USING CRON 0 9 * * * UTC..

Tuy nhiên, các mô hình hiếm khi tĩnh, và chúng ta thường phải lặp lại chúng. Sẽ tốn thời gian nếu xây thủ công từng phần của pipeline. Đây là lúc GitHub Actions phát huy tác dụng. Chúng ta thường dùng GitHub Actions trong pipeline CI/CD để tự động kiểm thử và dựng mã. 

GitHub Actions được thiết kế bằng các tệp YAML bên trong thư mục .github/workflows trong repository. Chúng ta có thể kích hoạt chúng bất cứ khi nào tạo pull request, để chạy qua một số kiểm thử dbt.

name: dbt pull test

# CRON job to run dbt at midnight UTC(!) everyday
on:
  pull_request:

types:
openedreopened
# Setting some Env variables to work  with profiles.yml
# This should be your snowflake secrets
env:
  DBT_PROFILE_TARGET: prod
  DBT_PROFILE_USER: ${{ secrets.DBT_PROFILE_USER }}
  DBT_PROFILE_PASSWORD: ${{ secrets.DBT_PROFILE_PASSWORD }}

jobs:
  dbt_run:
    name: dbt testing on pull request
    runs-on: ubuntu-latest
    timeout-minutes: 90
    
    # Steps of the workflow:
    steps:
      - name: Setup Python environment
	uses: actions/setup-python@v4
	with:
	  python-version: "3.11"

      - name: Install dependencies
	run: |
          python -m pip install --upgrade pip
	  python -m pip install -r requirements.txt
	
      - name: Install dbt packages
	run: dbt deps
        # optionally use this parameter
        # to set a main directory of dbt project:
        # working-directory: ./my_dbt_project
	    		
      - name: Run tests
	run: dbt test
        # working-directory: ./my_dbt_project

Thiết lập tự động hóa đúng cách có thể khiến cuộc sống của bạn dễ dàng hơn và giúp nhà phát triển khác thấy các mô hình đã kiểm thử. Điều này tinh gọn quy trình phát triển bằng cách giảm nhu cầu kiểm thử thủ công.

Khung kiểm thử

dbt đi kèm bộ kiểm thử mạnh mẽ. Nó có một số kiểm thử dữ liệu tổng quát dựng sẵn có thể đặt trực tiếp trên mô hình và cho phép logic SQL tùy chỉnh. Các kiểm thử tổng quát được đặt trên các cột cụ thể trong mô hình và kiểm tra các cột này có vượt qua bài kiểm thử đó hay không. Các kiểm thử dựng sẵn gồm:

  • unique: mọi giá trị trong cột này phải là duy nhất
  • not_null: không được có giá trị null trong cột
  • accepted_values: kiểm tra giá trị có nằm trong danh sách chấp nhận hay không
  • relationships: kiểm tra giá trị trong cột này có tồn tại trong bảng liên quan khác hay không

Đây là ví dụ sử dụng các mối quan hệ (từ tài liệu về kiểm thử của dbt):

version: 2

models:
  - name: orders
    columns:
      - name: order_id
        data_tests:
	# makes sure this column is unique and has no nulls
          - unique
          - not_null
      - name: status
        data_tests:
	#makes sure this column only has the below values
          - accepted_values:
              values: ['placed', 'shipped', 'completed', 'returned']
      - name: customer_id
        data_tests:
	# makes sure that the customer ids in this column are ids in the customers table
          - relationships:
              to: ref('customers')
              field: id

Chúng ta có thể dùng SQL tùy chỉnh để tạo các kiểm thử cụ thể và tổng quát hơn. Mục tiêu là các kiểm thử trả về những dòng thất bại. Nghĩa là nếu có kết quả, kiểm thử coi như thất bại. Các tệp SQL tùy chỉnh này nằm trong thư mục tests.

Ví dụ, nếu muốn biết có bán hàng âm nào không, chúng ta có thể dùng:

	select
	    order_id,
	    sum(amount) as total_amount
	from {{ ref('sales') }}
	group by 1
	having total_amount < 0

Sau đó, chúng ta tham chiếu kiểm thử đó trong tệp schema.yml bên trong thư mục test:

version: 2
data_tests:
  - name: assert_sales_amount_is_positive
    description: >
    Sales should always be positive and are not inclusive of refunds

Nếu muốn dùng kiểu kiểm tra này trên nhiều bảng và cột, chúng ta có thể biến nó thành một kiểm thử tổng quát. Trông có thể như sau:

{% test negative_values(model, group,sum_column) %}

    select {{group}},
    sum({{sum_column}}) as total_amt
    from {{ model }}
    group by 1
    having total_amt < 0
{% endtest %}

Giờ chúng ta có thể dùng kiểm thử này trong tệp yaml của models giống như các kiểm thử tổng quát khác mà dbt cung cấp! Bạn có thể kiểm tra số hành khách âm trên một chuyến đi hoặc lợi nhuận âm, v.v. Khả năng là vô tận.

Để việc kiểm thử liền mạch và đơn giản hơn, chúng ta có thể tận dụng zero-copy cloning của Snowflake. CREATE TABLE <object> CLONE <source_object> của Snowflake có thể tạo một bản sao zero-copy trong môi trường dev/test của bạn. 

Khi đó, toàn bộ kiểm thử và CI có thể thực hiện trên đối tượng clone. Lợi ích là không cần thêm dung lượng lưu trữ để có môi trường kiểm thử an toàn. Ngoài ra, bất cứ khi nào cần thêm môi trường kiểm thử, chúng ta có thể tạo nhiều môi trường với việc clone tức thời này.

Xu hướng mới và triển vọng tương lai

Hãy nhìn vào các cải tiến và xu hướng sắp tới từ dbt và Snowflake.

Phát triển tích hợp gốc

dbt liên tục cải thiện tích hợp cả với sản phẩm lõi và với AI. Trong Snowflake, chúng ta có thể dùng Snowsight như một giao diện UI để quản lý workspace dbt. Bằng cách tích hợp liền mạch hơn vào môi trường Snowflake, chúng ta giảm nhu cầu làm việc trên mô hình dbt bên ngoài. Thay vào đó, có thể tập trung quy trình bằng cách cho phép nhóm chỉnh sửa và cộng tác qua UI của Snowflake.

Để tăng tốc phát triển, dbt cung cấp trợ lý dùng AI gọi là dbt Copilot. Trợ lý này có thể truy cập qua dbt Studio IDE, Canvas hoặc Insights và dùng xử lý ngôn ngữ tự nhiên để tăng tốc những phần tốn thời gian của phát triển mô hình như viết tài liệu và tạo kiểm thử. 

dbt Copilot còn có thể dùng để hỗ trợ onboarding cho nhà phân tích mới bằng cách cung cấp tóm tắt ngắn gọn về dự án và mô hình.

Hãy dùng cả hai công cụ này để rút ngắn thời gian lên sản xuất và rút ngắn thời gian phát triển, giúp nhóm của bạn tập trung giải các bài toán dữ liệu khó hơn trong tổ chức. 

Tích hợp Machine Learning

Pipeline machine learning đòi hỏi dữ liệu luôn sạch và được thiết kế tốt. dbt là công cụ hoàn hảo cho pipeline biến đổi dữ liệu nuôi mô hình machine learning. Chúng ta có thể tận dụng tính linh hoạt và sức mạnh của dbt để tự động hóa biến đổi dữ liệu, tích hợp liền mạch vào pipeline ML.

Ví dụ, chúng ta có thể biến đổi dữ liệu trực tiếp vào một kho ML. Dữ liệu này sau đó có thể dùng với Cortex AI của Snowflake để khai thác hiểu biết sâu hơn. Nếu chúng ta có nhiều mô hình cần biến đổi tương tự, templating của dbt có thể đơn giản hóa cách làm sạch dữ liệu, mang lại tính nhất quán cao hơn và quản trị dữ liệu dễ dàng hơn. Để hiểu rõ hơn về công cụ AI của Snowflake, hãy đọc hướng dẫn về Snowflake Arctic, LLM của Snowflake.

Thực thi dạng container

Nhờ hỗ trợ Python gốc và Snowpark API for Python của Snowflake, chúng ta có thể chạy mã cục bộ mà không cần di chuyển dữ liệu ra khỏi Snowflake. Cấp độ tiếp theo là dùng Snowpark Containers, hiện (tại thời điểm viết) chỉ khả dụng ở các khu vực AWS và Azure, để chạy các phiên thực thi hoàn toàn tách biệt cho mã dbt của chúng ta. 

Để làm vậy, chúng ta đóng gói các mô hình dbt và môi trường vào một container, sau đó lưu trong image repository của Snowflake.

Khi đó, chúng ta có thể dùng dự án dbt dạng container này dễ dàng trong Snowpark. Lợi ích chính? Khả năng tận dụng tài nguyên của Snowflake dễ dàng hơn cho các biến đổi dữ liệu bằng Python phức tạp và tích hợp biến đổi dbt trong môi trường Snowflake lớn hơn. 

Nếu bạn tò mò muốn biết thêm về Snowpark, hãy xem thông tin mô tả Snowflake Snowpark chi tiết.

Kết luận

Tích hợp dbt với Snowflake giúp các nhóm dữ liệu xây dựng pipeline biến đổi có tính mô-đun, được quản trị và có khả năng mở rộng. Với các tính năng như kiểm thử tự động, quy trình CI/CD dựa trên Git và khả năng mở rộng liền mạch, bộ công cụ này lý tưởng cho vận hành dữ liệu hiện đại. 

Để duy trì lợi thế cạnh tranh, các nhóm dữ liệu nên ưu tiên:

  • Quản trị dữ liệu tốt hơn để duy trì vòng đời dữ liệu
  • Nâng cao khả năng hiển thị chi phí và giám sát hiệu năng liên tục để tối ưu kích cỡ warehouse
  • Container hóa để tái lập và hợp nhất quy trình cho phân tích và ML

Khi cả hai công cụ tiếp tục phát triển, tích hợp dbt + Snowflake sẽ ngày càng mạnh mẽ hơn cho các nhóm kỹ thuật dữ liệu. Nếu bạn quan tâm tìm hiểu thêm về dbt hoặc Snowflake, hãy xem các tài nguyên sau:

Câu hỏi thường gặp về dbt Snowflake

Materializations trong dbt là gì và chúng ảnh hưởng đến Snowflake như thế nào?

Materialization xác định cách dbt xây dựng models: dưới dạng views, tables hoặc incremental tables.

Dynamic tables trong Snowflake khác gì so với incremental models của dbt?

Các incremental model của dbt được quản lý và kích hoạt thủ công, trong khi dynamic tables của Snowflake được làm mới tự động dựa trên thay đổi phụ thuộc. Dùng dbt để tăng tính linh hoạt và kiểm soát điều phối; dùng dynamic tables cho độ tươi dữ liệu gần thời gian thực.

Các lựa chọn CI/CD cho dbt và Snowflake là gì?

dbt hỗ trợ CI/CD bằng GitHub Actions, GitLab CI hoặc Bitbucket Pipelines. Kết hợp quản lý phiên bản với kiểm thử tự động và chạy dbt khi merge hoặc pull request để có quy trình vững chắc.

Những xu hướng tương lai nào nên theo dõi trong hệ sinh thái dbt + Snowflake?

Những phát triển chính gồm:

  • Chỉnh sửa dbt gốc trong Snowsight,
  • Trợ lý dùng AI (ví dụ: Ask dbt),
  • Tích hợp sâu hơn với Snowpark và ML,
  • Hỗ trợ data mesh qua các dự án mô-đun,
  • Dynamic tables cho vận hành dữ liệu gần thời gian thực.
Tim Lu

Tác giả

Tim Lu

Tôi là một nhà khoa học dữ liệu có kinh nghiệm về phân tích không gian, học máy và đường ống dữ liệu. Tôi đã làm việc với GCP, Hadoop, Hive, Snowflake, Airflow và các quy trình khoa học/kỹ thuật dữ liệu khác.

Chủ đề

Liên quan