Ngân hàng đề — Google Cloud Associate Data Practitioner
Tìm thấy 333 câu.
You are querying a customer_list table in BigQuery that accidentally contains many duplicate entries. You need to produce a list of customers where each customer appears only once.
Which SQL keyword would you add to your SELECT statement to accomplish this?
- A UNIQUE
- B FIRST
- C SINGLE
- D DISTINCT
Xem giải thích
Đáp án
D — DISTINCT
Vì sao đúng
DISTINCT là từ khoá chuẩn của SQL để loại bỏ các dòng trùng lặp trong kết quả trả về.
⚠ Điểm mấu chốt — cú pháp và phạm vi tác dụng:
SELECT DISTINCT customer_id, customer_name
FROM `du_an.customer_list`;
↓
⚠ DISTINCT áp cho TOÀN BỘ TỔ HỢP CỘT
trong SELECT, không phải riêng cột đầu
↓
Hai dòng chỉ bị coi là trùng khi
MỌI cột được chọn đều giống nhau
⚠ Cái bẫy lớn nhất — thêm một cột là thay đổi kết quả:
SELECT DISTINCT customer_id
→ mỗi khách hàng đúng MỘT dòng
SELECT DISTINCT customer_id, ngay_dat_hang
→ mỗi khách hàng có thể ra NHIỀU dòng
(một dòng cho mỗi ngày khác nhau)
↓
⚠ Rất hay gây "sao vẫn còn trùng?"
⚠ Khi bản ghi trùng nhưng KHÔNG giống hệt:
Cùng một khách hàng, hai dòng khác nhau
ở một cột phụ (ví dụ thời điểm cập nhật)
↓
DISTINCT KHÔNG gộp được
↓
Dùng hàm cửa sổ để giữ bản MỚI NHẤT:
SELECT * EXCEPT(rn) FROM (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY cap_nhat_luc DESC) AS rn
FROM `du_an.customer_list`
) WHERE rn = 1;
Vì sao các phương án khác sai
-
A (
UNIQUE) — đây là phương án gần nhất về mặt ngữ nghĩa tiếng Anh, nhưngUNIQUEtrong SQL là RÀNG BUỘC trên cột khi định nghĩa bảng, không phải từ khoá lọc trùng trongSELECT. (BigQuery cũng không cưỡng chế ràng buộc này.) -
B (
FIRST) và C (SINGLE) — không phải từ khoá SQL cho việc này.
Ghi nhớ
⚠ Loại trùng trong SQL — bảng phải thuộc: | Cách | Dùng khi | |---|---| | SELECT DISTINCT | các dòng trùng HOÀN TOÀN ở mọi cột chọn | | GROUP BY mọi cột | tương đương DISTINCT | | ROW_NUMBER() OVER (PARTITION BY ...) | giữ MỘT dòng theo tiêu chí | | ARRAY_AGG(... LIMIT 1)[OFFSET(0)] | cách viết gọn của BigQuery | | COUNT(DISTINCT x) | đếm số giá trị duy nhất |
Từ khoá nhận diện:
"mỗi khách hàng xuất hiện một lần" →
DISTINCT"giữ bản ghi MỚI NHẤT của mỗi khách" →ROW_NUMBER()"đếm số khách hàng khác nhau" →COUNT(DISTINCT customer_id)"ghép hai bảng, bỏ trùng" →UNION(khácUNION ALL) "UNIQUEđể lọc trùng" → SAI — đó là ràng buộc bảng
UNION ↔ UNION ALL |
Nội dung |
|---|---|
UNION DISTINCT |
ghép và LOẠI TRÙNG |
UNION ALL |
ghép, GIỮ NGUYÊN mọi dòng |
| Hiệu năng | UNION ALL nhanh hơn nhiều |
| Trong BigQuery | phải viết rõ UNION ALL hoặc UNION DISTINCT |
| Lời khuyên | dùng UNION ALL trừ khi thật sự cần loại trùng |
Chi phí của DISTINCT trên dữ liệu lớn |
Nội dung |
|---|---|
| Phải so sánh và sắp xếp | tốn tài nguyên |
COUNT(DISTINCT x) chính xác |
rất nặng trên hàng tỉ dòng |
APPROX_COUNT_DISTINCT(x) |
nhanh hơn nhiều, sai số nhỏ |
| Khi nào chấp nhận xấp xỉ | đếm người dùng, đếm phiên — sai số vài phần nghìn không đổi quyết định |
| Khi nào cần chính xác | đối soát tài chính |
| Vì sao dữ liệu bị trùng ngay từ đầu | Nguyên nhân |
|---|---|
| Nạp lại cùng một tệp hai lần | thiếu kiểm soát |
| Pub/Sub at-least-once | thông điệp lặp |
| Không có khoá nghiệp vụ rõ ràng | |
| JOIN sai | một dòng khớp nhiều dòng → nhân bản |
| Cách chữa gốc | xử lý bất biến + khoá nghiệp vụ + kiểm tra chất lượng khi nạp |
| Ngăn trùng thay vì dọn trùng | Cách |
|---|---|
| Khoá nghiệp vụ tường minh | id đơn hàng, id giao dịch |
MERGE thay vì INSERT |
cập nhật nếu đã có |
| Kiểm tra chất lượng khi nạp | Dataform test, Dataplex |
| Bảng phân vùng + ghi đè phân vùng | nạp lại an toàn |
| Nguyên tắc | dọn trùng là chữa triệu chứng, không phải chữa bệnh |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Có bao nhiêu dòng trùng | SELECT COUNT(*) - COUNT(DISTINCT customer_id) FROM ... | | Khách nào bị trùng nhiều nhất | GROUP BY customer_id HAVING COUNT(*) > 1 ORDER BY 2 DESC | | Các dòng trùng khác nhau ở đâu | so từng cột của một customer_id cụ thể |
Và một việc nên làm trước khi vội thêm DISTINCT vào truy vấn: tìm hiểu vì sao có bản trùng. Rất thường xuyên, "dữ liệu trùng" thực ra là hệ quả của một phép JOIN nhân bản dòng — và trong trường hợp đó, DISTINCT che mất triệu chứng trong khi các con số tổng hợp vẫn sai.
You are working with two tables in BigQuery: customers (with columns customer_id, customer_name) and orders (with columns order_id, customer_id, amount). You need to create a list that shows each order_id and its corresponding customer_name.
Which SQL clause is required to link these two tables together on the customer_id field?
- A UNION ALL
- B WHERE customers.customer_id = orders.customer_id
- C JOIN customers ON customers.customer_id = orders.customer_id
- D GROUP BY customer_id
Xem giải thích
Đáp án
C — JOIN customers ON customers.customer_id = orders.customer_id
Vì sao đúng
Việc cần làm là nối hai bảng theo một cột chung để lấy tên khách hàng cho mỗi đơn hàng. JOIN ... ON là cú pháp chuẩn cho việc đó.
⚠ Điểm mấu chốt — truy vấn hoàn chỉnh:
SELECT o.order_id, c.customer_name
FROM `du_an.orders` AS o
JOIN `du_an.customers` AS c
ON c.customer_id = o.customer_id;
↓
JOIN nối theo CHIỀU NGANG:
lấy cột từ CẢ HAI bảng,
ghép lại theo điều kiện ON
⚠ JOIN ↔ UNION — hai phép hoàn toàn khác nhau:
JOIN — ghép theo CHIỀU NGANG
Bảng A: id, ten
Bảng B: id, so_tien
↓
Kết quả: id, ten, so_tien
→ NHIỀU CỘT hơn
UNION — ghép theo CHIỀU DỌC
Bảng A: id, ten (100 dòng)
Bảng B: id, ten (50 dòng)
↓
Kết quả: id, ten (150 dòng)
→ NHIỀU DÒNG hơn
⚠ Đòi hỏi hai bảng CÙNG số cột, cùng kiểu
⚠ Vì sao WHERE cũng "chạy được" nhưng không phải câu trả lời:
FROM orders, customers
WHERE customers.customer_id = orders.customer_id
↓
Đây là cú pháp JOIN KIỂU CŨ (implicit join)
↓
→ cho kết quả giống INNER JOIN
→ NHƯNG:
⚠ quên điều kiện WHERE = TÍCH ĐỀ-CÁC
(mọi dòng nhân với mọi dòng)
⚠ không viết được LEFT/RIGHT/FULL JOIN
⚠ khó đọc khi có nhiều bảng
↓
→ cú pháp JOIN ... ON là chuẩn hiện đại
→ và là mệnh đề mà đề hỏi
⚠ Bốn kiểu JOIN — chọn theo ý nghĩa nghiệp vụ:
INNER JOIN → chỉ giữ dòng KHỚP ở CẢ HAI bên
LEFT JOIN → giữ TOÀN BỘ bảng trái,
bên phải thiếu thì NULL
RIGHT JOIN → ngược lại
FULL JOIN → giữ tất cả hai bên
CROSS JOIN → tích đề-các, mọi tổ hợp
Vì sao các phương án khác sai
-
B (
WHERE customers.customer_id = orders.customer_id) — đây là phương án gần nhất và cho kết quả tương đương INNER JOIN khi hai bảng đã được liệt kê trongFROM, nhưng đó là cú pháp cũ: không diễn đạt đượcLEFT JOIN, và quên điều kiện là sinh tích đề-các. Mệnh đề dùng để liên kết bảng vẫn làJOIN ... ON. -
A (
UNION ALL) — ghép theo chiều DỌC, chồng dòng của hai bảng lên nhau; không lấy được cột từ bảng kia. -
D (
GROUP BY customer_id) — gom nhóm, không liên kết bảng nào.
Ghi nhớ
⚠ Các kiểu JOIN — bảng phải thuộc: | Kiểu | Giữ lại gì | |---|---| | INNER JOIN | chỉ dòng KHỚP ở cả hai bên | | LEFT JOIN | toàn bộ bảng TRÁI, phải thiếu thì NULL | | RIGHT JOIN | toàn bộ bảng phải | | FULL OUTER JOIN | tất cả, hai bên | | CROSS JOIN | mọi tổ hợp — cẩn thận | | Mặc định | JOIN = INNER JOIN |
Từ khoá nhận diện:
"nối hai bảng theo cột chung" →
JOIN ... ON"giữ cả những đơn KHÔNG có khách hàng khớp" →LEFT JOIN"chồng dòng của hai bảng" →UNION ALL"tìm dòng không khớp" →LEFT JOIN+WHERE b.id IS NULL"mọi tổ hợp" →CROSS JOIN
| Ba cái bẫy của JOIN | Bẫy |
|---|---|
| Nhân bản dòng | khoá bên phải KHÔNG duy nhất → mỗi dòng trái ra nhiều dòng |
| Mất dòng | dùng INNER JOIN khi lẽ ra cần LEFT JOIN |
| Tích đề-các | quên điều kiện ON |
| Cách phát hiện | so COUNT(*) trước và sau khi JOIN |
| Kiểm tra khoá | SELECT id, COUNT(*) ... GROUP BY 1 HAVING COUNT(*) > 1 |
| Hiệu năng JOIN trong BigQuery | Nội dung |
|---|---|
| Bảng lớn JOIN bảng NHỎ | BigQuery dùng broadcast join — rất nhanh |
| Bảng lớn JOIN bảng lớn | shuffle join — tốn hơn |
| Lọc TRƯỚC khi JOIN | giảm dữ liệu phải trộn |
| Dữ liệu lệch (skew) | một khoá chiếm quá nhiều → chậm hẳn |
| Phi chuẩn hoá | BigQuery ưa bảng lồng (nested/repeated) hơn nhiều JOIN |
| Xem chi tiết | Execution details của job |
| Cấu trúc lồng — cách của BigQuery | Nội dung |
|---|---|
STRUCT |
nhóm các trường liên quan |
ARRAY |
nhiều giá trị trong một dòng |
UNNEST |
trải mảng thành dòng |
| Lợi ích | tránh JOIN, dữ liệu nằm cạnh nhau |
| Ví dụ | một khách hàng kèm mảng đơn hàng |
| Viết JOIN cho dễ đọc | Thói quen |
|---|---|
| Luôn đặt bí danh | AS o, AS c |
| Ghi rõ bảng cho mọi cột | o.order_id, không để trống |
| Ghi rõ kiểu JOIN | INNER JOIN thay vì JOIN |
| Điều kiện ON chỉ chứa điều kiện NỐI | điều kiện lọc để ở WHERE |
| Ngoại lệ | với LEFT JOIN, điều kiện lọc bảng phải phải nằm trong ON |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | JOIN có nhân bản dòng không | so COUNT(*) của orders với kết quả | | Có đơn nào không tìm được khách | LEFT JOIN + WHERE c.customer_id IS NULL | | Truy vấn tốn bao nhiêu | --dry_run và Execution details |
Và một phép kiểm tra rất đáng làm ngay sau khi viết xong bất kỳ JOIN nào: đếm số dòng trước và sau. Nếu kết quả nhiều dòng hơn bảng đơn hàng ban đầu, khoá bên phải không duy nhất và mọi con số tổng hợp phía sau đều đang bị thổi phồng — một lỗi im lặng và rất khó phát hiện qua mắt thường.
As a first step in a data cleaning process, you need to verify that the incoming data conforms to basic business rules before loading it into a production system. This includes checking that columns are not empty, that dates are in a valid format, and that certain numeric fields are within an expected range.
What is this fundamental data preparation step called?
- A Data Orchestration
- B Data Ingestion
- C Data Transformation
- D Assessing data quality
Xem giải thích
Đáp án
D — Assessing data quality (đánh giá chất lượng dữ liệu).
Vì sao đúng
Đề mô tả việc kiểm tra dữ liệu có tuân thủ các quy tắc nghiệp vụ cơ bản hay không: cột không được rỗng, ngày phải đúng định dạng, số phải nằm trong khoảng cho phép. Đó chính là đánh giá chất lượng dữ liệu.
⚠ Điểm mấu chốt — sáu chiều của chất lượng dữ liệu:
ĐẦY ĐỦ (completeness)
→ cột không rỗng ← đề này
HỢP LỆ (validity)
→ đúng định dạng, đúng khoảng ← đề này
CHÍNH XÁC (accuracy)
→ khớp với thực tế
NHẤT QUÁN (consistency)
→ không mâu thuẫn giữa các hệ thống
DUY NHẤT (uniqueness)
→ không trùng lặp
KỊP THỜI (timeliness)
→ đủ mới để dùng
⚠ Vì sao đây là bước TRƯỚC khi biến đổi:
Đánh giá chất lượng
↓
Trả lời: dữ liệu này có DÙNG ĐƯỢC không
↓
Nếu KHÔNG → chặn lại, cảnh báo,
đưa vào khu cách ly
↓
Nếu CÓ → mới sang bước BIẾN ĐỔI
↓
⚠ Biến đổi dữ liệu rác chỉ cho ra
kết quả rác một cách có tổ chức hơn
⚠ Kiểm tra chất lượng bằng SQL:
SELECT
COUNTIF(email IS NULL) AS thieu_email,
COUNTIF(NOT REGEXP_CONTAINS(
ngay, r'^\d{4}-\d{2}-\d{2}$')) AS ngay_sai,
COUNTIF(tuoi < 0 OR tuoi > 120) AS tuoi_vo_ly,
COUNT(*) AS tong_dong
FROM `du_an.du_lieu_thô`;
Vì sao các phương án khác sai
-
C (Data Transformation) — đây là phương án gần nhất và là bước NGAY SAU, nhưng biến đổi là thay đổi hình dạng dữ liệu (đổi kiểu, gộp, tính toán). Việc kiểm tra xem dữ liệu có hợp lệ không là đánh giá chất lượng.
-
B (Data Ingestion) — đưa dữ liệu vào hệ thống, xảy ra trước.
-
A (Data Orchestration) — điều phối thứ tự các bước trong pipeline (Composer, Workflows), không phải bản thân việc kiểm tra.
Ghi nhớ
⚠ Các bước của một pipeline dữ liệu — bảng phải thuộc: | Bước | Việc | |---|---| | Ingestion | đưa dữ liệu vào hệ thống | | Assessing data quality | kiểm tra dữ liệu có dùng được không | | Transformation | làm sạch, đổi kiểu, gộp, tính toán | | Loading | nạp vào kho đích | | Orchestration | điều phối thứ tự và phụ thuộc các bước | | Monitoring | theo dõi và cảnh báo |
Từ khoá nhận diện:
"kiểm tra rỗng, định dạng, khoảng giá trị" → đánh giá chất lượng dữ liệu "đổi kiểu, gộp cột, tính toán" → biến đổi "đưa dữ liệu vào" → nạp / ingestion "chạy bước A xong mới chạy bước B" → điều phối "tìm và che PII" → Sensitive Data Protection
| Sáu chiều chất lượng dữ liệu — nhắc lại | Chiều |
|---|---|
| Completeness | đầy đủ, không thiếu giá trị |
| Validity | đúng định dạng và khoảng |
| Accuracy | đúng so với thực tế |
| Consistency | không mâu thuẫn |
| Uniqueness | không trùng |
| Timeliness | đủ mới |
| Công cụ kiểm tra chất lượng trên Google Cloud | Công cụ |
|---|---|
| Dataplex data quality | quy tắc khai báo, chạy theo lịch, có điểm số |
| Dataform assertions | kiểm thử ngay trong pipeline SQL |
| Dataflow | kiểm tra trong lúc xử lý luồng |
| Cloud Data Fusion (Wrangler) | kiểm tra trực quan |
| Truy vấn SQL tự viết | đơn giản nhất, luôn dùng được |
| Sensitive Data Protection | phát hiện PII |
| Xử lý bản ghi hỏng thế nào | Cách |
|---|---|
| Chặn cả lô | khi tỉ lệ lỗi vượt ngưỡng |
| Khu cách ly (quarantine) | đẩy bản ghi hỏng ra bảng riêng |
| Dead-letter | với pipeline luồng |
--max_bad_records |
với bq load |
| Cảnh báo | báo người phụ trách nguồn dữ liệu |
| Sai lầm | âm thầm bỏ qua bản ghi hỏng |
| Đặt quy tắc chất lượng ở đâu | Nơi |
|---|---|
| Càng GẦN NGUỒN càng tốt | phát hiện sớm, sửa rẻ |
| Tại điểm nạp | chặn trước khi vào kho |
| Trong lớp biến đổi | kiểm tra sau mỗi bước |
| Trước khi công bố cho người dùng | cổng cuối cùng |
| Nguyên tắc | lỗi phát hiện muộn tốn kém gấp nhiều lần |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tỉ lệ thiếu dữ liệu | COUNTIF(x IS NULL) / COUNT(*) | | Giá trị ngoại lai | phân vị: APPROX_QUANTILES(x, 100) | | Định dạng có đúng không | REGEXP_CONTAINS |
Và một nguyên tắc đáng nhớ khi thiết kế bước này: đừng chỉ đếm lỗi, hãy giữ lại bản ghi hỏng. Một con số "3% bản ghi không hợp lệ" chỉ nói lên có vấn đề; một bảng cách ly chứa đúng những dòng đó cho phép người phụ trách nguồn nhìn thấy mẫu lỗi và sửa từ gốc — thứ mà không báo cáo tổng hợp nào thay thế được.
A table in BigQuery contains user activity data that is actively queried for the first 90 days. After 90 consecutive days of not being edited, the table is kept for compliance but is no longer queried. You have not configured any special lifecycle policies.
What happens to the cost of storing this data in BigQuery after the 90th day of inactivity?
- A The data is automatically moved to Cloud Storage Nearline class.
- B The storage cost is automatically reduced by approximately 50%.
- C The storage cost remains the same unless you manually export it.
- D The data is automatically deleted to save costs.
Xem giải thích
Đáp án
B — Chi phí lưu trữ tự động giảm khoảng 50%.
Vì sao đúng
BigQuery có sẵn cơ chế long-term storage: bảng hoặc phân vùng không bị SỬA trong 90 ngày liên tiếp sẽ tự chuyển sang giá lưu trữ dài hạn, rẻ hơn khoảng một nửa.
⚠ Điểm mấu chốt — hoàn toàn tự động, không phải làm gì:
Bảng không bị SỬA ĐỔI trong 90 ngày
↓
BigQuery TỰ chuyển sang
long-term storage
↓
Giá lưu ≈ 50% giá active storage
↓
⚠ KHÔNG cần cấu hình
⚠ KHÔNG cần chính sách vòng đời
⚠ KHÔNG có thay đổi nào về hiệu năng
⚠ ⚠ Điều dễ hiểu lầm nhất — TRUY VẤN không làm mất ưu đãi:
Đồng hồ 90 ngày đếm từ lần SỬA ĐỔI cuối
↓
Sửa đổi = thêm dòng, xoá, cập nhật,
nạp dữ liệu, ghi đè
↓
⚠ TRUY VẤN (SELECT) KHÔNG phải sửa đổi
⚠ Sao chép bảng, xuất dữ liệu:
cũng KHÔNG làm mất ưu đãi
↓
→ bảng lưu trữ vẫn đọc thoải mái
mà vẫn giữ giá rẻ
⚠ Tính theo TỪNG PHÂN VÙNG, không theo cả bảng:
Bảng phân vùng theo ngày
↓
Phân vùng tháng 1 không đổi → giá rẻ
Phân vùng hôm nay đang ghi → giá thường
↓
⚠ Đây là lý do rất mạnh để
PHÂN VÙNG bảng lớn
↓
Bảng KHÔNG phân vùng mà thêm một dòng
→ RESET đồng hồ cho TOÀN BỘ bảng
⚠ Hai mô hình tính tiền lưu trữ:
LOGICAL (mặc định cũ)
→ tính theo dung lượng dữ liệu logic
PHYSICAL
→ tính theo dung lượng ĐÃ NÉN
→ thường RẺ HƠN NHIỀU với dữ liệu nén tốt
→ nhưng tính cả time travel và fail-safe
↓
Đổi ở cấp DATASET, cân nhắc theo số liệu thật
Vì sao các phương án khác sai
-
C (chi phí giữ nguyên trừ khi tự xuất đi) — đây là phương án dễ chọn nhầm nếu không biết về long-term storage, nhưng BigQuery tự động giảm giá, không cần bạn làm gì.
-
A (tự chuyển sang Cloud Storage Nearline) — không có cơ chế nào như vậy; dữ liệu vẫn nằm trong BigQuery.
-
D (tự xoá) — BigQuery KHÔNG BAO GIỜ tự xoá dữ liệu, trừ khi bạn đặt thời gian hết hạn cho bảng hoặc phân vùng.
Ghi nhớ
⚠ Chi phí lưu trữ BigQuery — bảng phải thuộc: | Điểm | Nội dung | |---|---| | Active storage | giá đầy đủ | | Long-term storage | ≈ 50% giá, sau 90 ngày KHÔNG SỬA ĐỔI | | Tự động | không cần cấu hình gì | | Truy vấn KHÔNG reset đồng hồ | chỉ sửa đổi mới reset | | Tính theo PHÂN VÙNG | với bảng có phân vùng | | 10 GiB đầu mỗi tháng | miễn phí |
Từ khoá nhận diện:
"90 ngày không sửa, chi phí lưu" → long-term storage, giảm ~50% "tự động xoá dữ liệu cũ" → table/partition expiration — phải tự đặt "quay lại dữ liệu 5 ngày trước" → time travel "tính theo dung lượng nén" → physical storage billing "chuyển sang Cloud Storage" → phải tự
bq extract
| Những gì RESET đồng hồ 90 ngày | Thao tác |
|---|---|
INSERT, UPDATE, DELETE, MERGE |
có |
bq load vào bảng |
có |
| Streaming insert | có |
SELECT (truy vấn) |
KHÔNG |
bq extract (xuất) |
KHÔNG |
| Sao chép bảng đi nơi khác | KHÔNG (bảng nguồn giữ nguyên) |
| Time travel và fail-safe | Nội dung |
|---|---|
| Time travel | truy vấn dữ liệu tới 7 ngày trước |
| Cú pháp | FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(...) |
| Khôi phục bảng vừa xoá | bq cp <bảng>@<timestamp> |
| Fail-safe | thêm 7 ngày nữa, chỉ Google truy cập được |
| Ảnh hưởng chi phí | có, với physical storage billing |
| Rút ngắn được | max_time_travel_hours (48–168 giờ) |
| Cách giảm chi phí lưu trữ BigQuery | Cách |
|---|---|
| Phân vùng bảng | từng phân vùng cũ được giá rẻ riêng |
| Đặt hạn dùng cho phân vùng | --time_partitioning_expiration |
| Cân nhắc physical billing | với dữ liệu nén tốt |
| Xoá bảng trung gian | nhiều bảng tạm bị bỏ quên |
| Xuất dữ liệu lạnh sang GCS Archive | nếu thật sự không truy vấn nữa |
| Rút ngắn time travel | với bảng rất lớn |
| Khi nào nên đưa dữ liệu ra khỏi BigQuery | Dấu hiệu |
|---|---|
| Không truy vấn nữa, chỉ giữ để tuân thủ | → GCS Archive rẻ hơn nhiều |
| Vẫn thỉnh thoảng truy vấn | → để nguyên trong BigQuery |
| Lưu ý | truy vấn dữ liệu ở GCS phải qua external table — chậm hơn |
| Cân nhắc | công sức đưa dữ liệu quay lại khi cần |
| Với đề này | để nguyên là đúng — giá đã tự giảm một nửa |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Bảng lần cuối sửa khi nào | bq show <dataset>.<bảng> → Last modified | | Bảng đang tốn bao nhiêu | INFORMATION_SCHEMA.TABLE_STORAGE | | Bao nhiêu ở long-term | cùng view trên, cột LONG_TERM_LOGICAL_BYTES |
Và một lý do nữa để phân vùng mọi bảng lớn theo ngày: một dòng thêm vào bảng không phân vùng sẽ reset đồng hồ 90 ngày cho toàn bộ bảng. Với bảng vài chục TB chỉ có phần dữ liệu mới thay đổi, phân vùng biến ưu đãi long-term từ chuyện "gần như không bao giờ đạt được" thành mặc định cho mọi phân vùng cũ.
A research organization wants to share several of its large, curated BigQuery datasets with other universities for collaboration. They need a solution that allows them to share the data securely and efficiently without creating and managing multiple copies of the data. The solution should also allow them to manage subscriptions and track usage.
Which Google Cloud service is designed for this purpose?
- A Analytics Hub
- B Looker
- C Identity and Access Management (IAM)
- D Cloud Storage
Xem giải thích
Đáp án
A — Analytics Hub.
Vì sao đúng
Đề nêu bốn yêu cầu: chia sẻ dataset BigQuery cho tổ chức ngoài, an toàn, KHÔNG tạo nhiều bản sao, và quản lý đăng ký cùng theo dõi mức sử dụng. Analytics Hub được thiết kế cho đúng bộ yêu cầu đó.
⚠ Điểm mấu chốt — chia sẻ mà không sao chép:
Cách CŨ: xuất dữ liệu rồi gửi bản sao
↓
⚠ Mỗi bên một bản → tốn lưu trữ
⚠ Bản sao LỖI THỜI ngay khi gửi
⚠ Không thu hồi được
⚠ Không biết ai đang dùng
ANALYTICS HUB
↓
Người chia sẻ tạo LISTING trong EXCHANGE
↓
Người nhận ĐĂNG KÝ → nhận
LINKED DATASET trong project của họ
↓
⚠ Linked dataset chỉ là CON TRỎ
→ dữ liệu vẫn nằm ở một chỗ duy nhất
→ cập nhật ở nguồn là thấy ngay
→ THU HỒI được bất cứ lúc nào
⚠ Ba khái niệm của Analytics Hub:
EXCHANGE (sàn trao đổi)
→ nơi chứa các listing
→ công khai, hoặc riêng cho một nhóm
LISTING (mục chia sẻ)
→ một dataset được công bố,
kèm mô tả và điều kiện
SUBSCRIPTION (đăng ký)
→ bên nhận đăng ký một listing
→ sinh ra LINKED DATASET
⚠ Ai trả tiền cho gì:
NGƯỜI CHIA SẺ
→ trả phí LƯU TRỮ dữ liệu
NGƯỜI ĐĂNG KÝ
→ trả phí TRUY VẤN của chính họ
↓
⚠ Đây là điểm rất hợp lý cho hợp tác
giữa các trường đại học:
chia sẻ không làm tăng chi phí
truy vấn của bên cung cấp
Vì sao các phương án khác sai
-
C (IAM) — đây là phương án gần nhất và về kỹ thuật thì cấp quyền đọc dataset cho tài khoản bên ngoài là làm được, nhưng IAM không có cơ chế quản lý ĐĂNG KÝ, danh mục, mô tả, hay theo dõi mức sử dụng — đúng những thứ đề yêu cầu. Analytics Hub dùng IAM bên dưới và bổ sung lớp quản trị đó.
-
B (Looker) — nền tảng BI và trực quan hoá, không phải cơ chế chia sẻ dataset.
-
D (Cloud Storage) — chia sẻ tệp, và cách làm đó buộc phải tạo bản sao — trái yêu cầu.
Ghi nhớ
⚠ Các cách chia sẻ dữ liệu BigQuery — bảng phải thuộc: | Cách | Dùng khi | |---|---| | Analytics Hub | chia sẻ dataset ra ngoài, có quản trị và theo dõi | | IAM trên dataset | chia sẻ đơn giản trong nội bộ | | Authorized view | chia sẻ MỘT PHẦN dữ liệu qua view | | Authorized dataset / routine | mở rộng của cơ chế trên | | bq extract sang GCS | khi bên nhận không dùng BigQuery | | Row/column-level security | giới hạn theo dòng và cột |
Từ khoá nhận diện:
"chia sẻ không tạo bản sao, quản lý đăng ký" → Analytics Hub "chỉ cho xem vài cột" → authorized view hoặc column-level security "mỗi phòng ban chỉ thấy dòng của mình" → row-level security "bên nhận không dùng BigQuery" → xuất ra Cloud Storage "dữ liệu công khai của Google" → BigQuery public datasets, cũng qua Analytics Hub
| Analytics Hub — lợi ích cụ thể | Lợi ích |
|---|---|
| Không nhân bản dữ liệu | tiết kiệm lưu trữ, luôn mới |
| Thu hồi tức thì | huỷ listing là mất quyền |
| Theo dõi mức sử dụng | biết ai truy vấn bao nhiêu |
| Danh mục có mô tả | bên nhận tự tìm được |
| Chia sẻ xuyên tổ chức | không cần cùng project |
| Chia sẻ cả VIEW và bảng | kiểm soát được phần lộ ra |
| Authorized view — công cụ bổ sung quan trọng | Nội dung |
|---|---|
| Vấn đề | muốn chia sẻ kết quả chứ không phải bảng gốc |
| Cách làm | tạo view ở dataset khác, cấp quyền cho view |
| Bên nhận truy vấn view được, nhưng KHÔNG đọc được bảng gốc | |
| Kết hợp | Analytics Hub chia sẻ chính view đó |
| Lợi ích | lọc dòng, ẩn cột, tổng hợp trước khi chia sẻ |
| Kiểm soát dữ liệu nhạy cảm trước khi chia sẻ | Cách |
|---|---|
| Column-level security | policy tag của Dataplex/Data Catalog |
| Row-level security | lọc dòng theo người truy cập |
| Dynamic data masking | che giá trị theo vai trò |
| Sensitive Data Protection | quét tìm PII còn sót |
| VPC Service Controls | vành đai chống rò rỉ |
| Với hợp tác nghiên cứu | thường chia sẻ dữ liệu đã ẩn danh |
| Trước khi công bố một listing | Việc |
|---|---|
| Quét PII | Sensitive Data Protection |
| Quyết định chia sẻ bảng hay view | view an toàn hơn |
| Viết mô tả rõ ràng | lược đồ, tần suất cập nhật, giấy phép |
| Chọn phạm vi exchange | riêng hay công khai |
| Thoả thuận sử dụng | ghi trong mô tả listing |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Ai đang đăng ký | console → Analytics Hub → listing → Subscriptions | | Họ truy vấn bao nhiêu | INFORMATION_SCHEMA.JOBS phía người chia sẻ, và số liệu của Hub | | Dataset có lộ cột nhạy cảm không | kiểm tra policy tag và định nghĩa view |
Và một quyết định nên cân nhắc kỹ trước khi công bố: chia sẻ bảng gốc hay chia sẻ một view. View cho phép bạn lọc dòng, ẩn cột và tổng hợp trước khi dữ liệu ra khỏi tổ chức — và về sau, khi cần đổi cấu trúc bảng bên dưới, người đăng ký sẽ không bị ảnh hưởng gì.
An enterprise company needs a business intelligence (BI) solution that enforces consistency. They want to define key business metrics (like 'Annual Recurring Revenue') once in a central modeling layer and have every report and dashboard across the company use that exact definition.
Which BI tool's core feature set is best aligned with this requirement?
- A Jupyter Notebooks, because of their flexibility with Python.
- B BigQuery, because it is a single source of truth for data.
- C Looker Studio, because it has many connectors.
- D Looker, because of its LookML modeling layer.
Xem giải thích
Đáp án
D — Looker, nhờ lớp mô hình hoá LookML.
Vì sao đúng
Yêu cầu cốt lõi là định nghĩa chỉ số nghiệp vụ MỘT LẦN ở một lớp mô hình tập trung, rồi mọi báo cáo trong công ty đều dùng đúng định nghĩa đó. Đó chính là lý do LookML tồn tại.
⚠ Điểm mấu chốt — chỉ số định nghĩa một lần trong mã:
measure: annual_recurring_revenue {
type: sum
sql: ${TABLE}.mrr * 12 ;;
filters: [subscription_status: "active"]
value_format_name: usd
description: "ARR = MRR hoạt động × 12"
}
↓
Mọi dashboard, mọi báo cáo, mọi
người dùng đều lấy TỪ ĐÂY
↓
→ không còn chuyện hai phòng ban
báo hai con số ARR khác nhau
⚠ Vấn đề mà lớp ngữ nghĩa giải quyết:
KHÔNG có lớp mô hình
↓
Mỗi người tự viết SQL trong báo cáo
↓
Người A: SUM(mrr) * 12
Người B: SUM(mrr) * 12 nhưng lọc khác
Người C: quên loại khách đã huỷ
↓
⚠ Ba con số ARR khác nhau trong
cùng một cuộc họp
↓
→ mất niềm tin vào toàn bộ dữ liệu
⚠ LookML còn mang lại điều mà công cụ kéo thả không có:
- LƯU TRONG GIT → có phiên bản, có review
- KIỂM THỬ được
- MÔI TRƯỜNG dev / production
- Quyền theo trường và theo dòng
định nghĩa ngay trong mô hình
- Truy vấn sinh ra ĐẨY XUỐNG kho
(BigQuery), không sao chép dữ liệu
Xem thêm câu #12947 (cùng lô): cùng chủ đề công cụ BI nhưng yêu cầu là dashboard đơn giản, MIỄN PHÍ, kéo thả → khoá là Looker Studio. Hai khoá khác nhau vì quy mô và yêu cầu quản trị khác nhau, không mâu thuẫn.
Vì sao các phương án khác sai
-
C (Looker Studio, vì có nhiều trình kết nối) — đây là phương án gần nhất về tên gọi, nhưng Looker Studio không có lớp mô hình hoá tập trung: mỗi báo cáo tự định nghĩa trường tính toán của nó, đúng vấn đề mà đề muốn tránh.
-
B (BigQuery, vì là nguồn sự thật duy nhất) — BigQuery thống nhất dữ liệu, nhưng không thống nhất ĐỊNH NGHĨA CHỈ SỐ; mỗi người vẫn viết SQL theo cách riêng. (Có thể tiến gần bằng view hoặc Dataform, nhưng đó không phải lớp ngữ nghĩa cho BI.)
-
A (Jupyter Notebook) — môi trường phân tích tuỳ hứng, hoàn toàn ngược với yêu cầu nhất quán toàn công ty.
Ghi nhớ
⚠ Looker ↔ Looker Studio — bảng phải thuộc: | | Looker | Looker Studio | |---|---|---| | Lớp mô hình | LookML — tập trung | không có | | Nhất quán chỉ số | được bảo đảm | mỗi báo cáo tự định nghĩa | | Quản lý phiên bản | Git | không | | Chi phí | có phí, theo nền tảng và người dùng | bản cơ bản MIỄN PHÍ | | Đối tượng | doanh nghiệp, quản trị chặt | đội nhỏ, báo cáo nhanh | | Nhúng và API | mạnh | hạn chế hơn |
Từ khoá nhận diện:
"định nghĩa chỉ số một lần, dùng chung toàn công ty" → Looker + LookML "dashboard nhanh, miễn phí" → Looker Studio "phân tích tuỳ hứng bằng Python" → Vertex AI Notebooks "chuỗi biến đổi SQL có kiểm thử" → Dataform "giám sát hạ tầng" → Cloud Monitoring dashboard
| LookML — các khái niệm chính | Khái niệm |
|---|---|
view |
ánh xạ tới một bảng, khai dimension và measure |
dimension |
thuộc tính để cắt lớp |
measure |
chỉ số tổng hợp — nơi định nghĩa ARR |
explore |
điểm vào cho người dùng, khai các join |
model |
gom explore, khai kết nối tới kho |
derived table |
bảng dẫn xuất, có thể materialize |
| Vì sao "một định nghĩa" lại quan trọng đến thế | Nội dung |
|---|---|
| Quyết định dựa trên số | số khác nhau → tranh cãi thay vì quyết định |
| Kiểm toán và báo cáo tài chính | cần định nghĩa nhất quán, truy vết được |
| Người mới vào | không phải hỏi "ARR tính thế nào" |
| Đổi định nghĩa | sửa một chỗ, mọi báo cáo cập nhật |
| Cái giá | cần đội duy trì mô hình |
| Looker và BigQuery làm việc với nhau thế nào | Nội dung |
|---|---|
| Looker KHÔNG lưu dữ liệu | sinh SQL và đẩy xuống BigQuery |
| Aggregate awareness | tự dùng bảng tổng hợp khi có thể |
| PDT (persistent derived table) | vật chất hoá kết quả nặng |
| Caching | giảm số truy vấn |
| Lưu ý chi phí | mỗi lượt xem dashboard có thể là một truy vấn tính tiền |
| Khi nào Looker Studio là đủ | Dấu hiệu |
|---|---|
| Đội nhỏ, ít báo cáo | không có vấn đề nhất quán |
| Ngân sách hạn chế | bản cơ bản miễn phí |
| Báo cáo tạm thời | không cần quản trị |
| Khi nào cần Looker | nhiều phòng ban, chỉ số phải thống nhất, cần kiểm toán |
| Nhiều tổ chức | dùng cả hai cho hai mục đích |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Chỉ số định nghĩa ở đâu | tìm measure trong kho LookML | | Ai đổi định nghĩa gần đây | lịch sử Git của dự án LookML | | Dashboard tốn bao nhiêu | INFORMATION_SCHEMA.JOBS của BigQuery |
Và một cái giá phải trả cho sự nhất quán mà nên nói rõ từ đầu: LookML là mã, và mã thì cần người bảo trì. Đổi lại một định nghĩa chỉ số duy nhất cho cả công ty, bạn cần ai đó review pull request và quản lý môi trường — với tổ chức nhỏ, cái giá đó thường lớn hơn vấn đề mà nó giải quyết.
An operations team needs to build a simple, no-cost dashboard to visualize key metrics from a BigQuery table. The dashboard will be shared with internal stakeholders who have Google accounts. They need a tool that is easy to use and allows for creating charts and graphs with a drag-and-drop interface.
Which Google Cloud tool should they use?
- A Cloud Monitoring Dashboards
- B Looker Studio
- C Jupyter Notebooks on Vertex AI
- D Looker
Xem giải thích
Đáp án
B — Looker Studio.
Vì sao đúng
Đề nêu bốn điều: dashboard đơn giản, KHÔNG TỐN CHI PHÍ, kéo thả dễ dùng, chia sẻ cho người có tài khoản Google. Looker Studio khớp cả bốn.
⚠ Điểm mấu chốt — miễn phí là điều kiện quyết định:
Looker Studio
↓
Bản cơ bản MIỄN PHÍ hoàn toàn
↓
- Kết nối BigQuery bằng vài cú bấm
- Kéo thả để dựng biểu đồ
- Chia sẻ như Google Docs
(theo tài khoản Google)
↓
⚠ Chỉ trả tiền cho các TRUY VẤN
mà nó chạy trên BigQuery
⚠ Chia sẻ hoạt động y hệt Google Drive:
Chia sẻ báo cáo
↓
Nhập email Google của người xem
↓
Quyền: Viewer hoặc Editor
↓
⚠ Chọn "Viewer's credentials" hay
"Owner's credentials" cho nguồn dữ liệu
↓
Owner's credentials
→ người xem KHÔNG cần quyền BigQuery
→ nhưng truy vấn tính vào project của CHỦ
⚠ Điều phải cẩn thận về chi phí:
Looker Studio miễn phí
↓
NHƯNG mỗi lần làm mới biểu đồ
= một TRUY VẤN BIGQUERY
↓
Dashboard 10 biểu đồ × 50 người xem
× nhiều lần mỗi ngày
↓
⚠ Hoá đơn BigQuery có thể lớn
↓
Cách giảm:
- BẬT CACHE của Looker Studio
- dựng BẢNG TỔNG HỢP nhỏ để báo cáo đọc
- dùng BI Engine
- đặt maximum_bytes_billed
Xem thêm câu #12946 (cùng lô): yêu cầu ở đó là lớp mô hình tập trung để thống nhất định nghĩa chỉ số → khoá là Looker. Câu này chỉ cần dashboard đơn giản và miễn phí → Looker Studio. Quy tắc: cần quản trị chỉ số toàn công ty → Looker; cần biểu đồ nhanh và rẻ → Looker Studio.
Vì sao các phương án khác sai
-
D (Looker) — đây là phương án gần nhất về tên và mạnh hơn về tính năng, nhưng nó có phí đáng kể và cần đội duy trì LookML. Đề nói rõ không tốn chi phí và đơn giản, dễ dùng.
-
A (Cloud Monitoring Dashboards) — dành cho chỉ số hạ tầng và ứng dụng (CPU, độ trễ, lỗi), không phải công cụ BI đọc bảng BigQuery.
-
C (Jupyter Notebook trên Vertex AI) — môi trường viết mã Python, không phải công cụ kéo thả cho người dùng nghiệp vụ, và có chi phí instance.
Ghi nhớ
⚠ Chọn công cụ hiển thị dữ liệu — bảng phải thuộc: | Nhu cầu | Công cụ | |---|---| | Dashboard nhanh, miễn phí, kéo thả | Looker Studio | | Chỉ số thống nhất toàn công ty | Looker + LookML | | Phân tích tuỳ hứng bằng Python | Vertex AI Notebooks | | Khám phá bằng SQL | BigQuery UI | | Giám sát HẠ TẦNG | Cloud Monitoring dashboard | | Bảng tính quen thuộc | Connected Sheets |
Từ khoá nhận diện:
"miễn phí, kéo thả, chia sẻ nội bộ" → Looker Studio "LookML, chỉ số dùng chung" → Looker "CPU, độ trễ, cảnh báo" → Cloud Monitoring "phân tích trong Google Sheets trên dữ liệu BigQuery" → Connected Sheets "pandas, seaborn" → Vertex AI Notebooks
| Looker Studio — điều cần nhớ | Nội dung |
|---|---|
| Miễn phí | bản cơ bản; Looker Studio Pro có phí, thêm quản trị và hỗ trợ |
| Trình kết nối | BigQuery, Sheets, Cloud SQL, hàng trăm nguồn khác |
| Chia sẻ | như Google Docs, theo tài khoản Google |
| Nhúng | vào trang web nội bộ |
| Cache | rất quan trọng để giảm chi phí truy vấn |
| Làm mới theo lịch | đặt được tần suất |
| Hai chế độ thông tin xác thực | Chế độ |
|---|---|
| Owner's credentials | người xem KHÔNG cần quyền BigQuery; truy vấn tính cho chủ |
| Viewer's credentials | mỗi người dùng quyền của chính mình |
| Dùng owner khi | chia sẻ rộng cho người không có quyền dữ liệu |
| Dùng viewer khi | cần row-level security theo từng người |
| ⚠ Cẩn thận | owner's credentials có thể lộ dữ liệu cho người không đủ quyền |
| Giảm chi phí BigQuery cho dashboard | Cách |
|---|---|
| Bật và kéo dài cache | ít truy vấn lặp |
| Bảng tổng hợp nhỏ | báo cáo đọc bảng đã gộp sẵn |
| Materialized view | tự làm mới, tự tối ưu |
| BI Engine | bộ nhớ đệm trong RAM cho BigQuery — rất nhanh |
| Lọc theo cột phân vùng | giảm byte quét |
maximum_bytes_billed |
trần an toàn |
| Khi nào nên chuyển từ Looker Studio sang Looker | Dấu hiệu |
|---|---|
| Nhiều báo cáo cùng chỉ số nhưng ra số khác nhau | dấu hiệu rõ nhất |
| Cần kiểm toán và quản lý phiên bản | |
| Cần phân quyền theo dòng phức tạp | |
| Số lượng báo cáo vượt tầm kiểm soát | |
| Nếu chưa có dấu hiệu nào | Looker Studio là đủ và rẻ hơn nhiều |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Dashboard tốn bao nhiêu | INFORMATION_SCHEMA.JOBS, lọc theo nhãn của Looker Studio | | Cache có hoạt động không | thử làm mới nhiều lần, xem số job phát sinh | | Ai xem được báo cáo | menu chia sẻ của chính báo cáo |
Và một cấu hình nên kiểm tra ngay sau khi chia sẻ báo cáo lần đầu: chế độ thông tin xác thực của nguồn dữ liệu. Với "owner's credentials", mọi người xem báo cáo đều đọc dữ liệu bằng quyền của bạn — tiện cho việc chia sẻ, nhưng cũng có nghĩa là một biểu đồ thêm vào sau này có thể vô tình phơi bày dữ liệu mà người xem lẽ ra không được thấy.
A company has a complex daily data processing workflow. The workflow involves running a Dataproc job to process files in Cloud Storage, then loading the results into BigQuery, and finally triggering a Cloud Function to send a notification. This multi-step process must be managed as a single, cohesive pipeline with clear dependency management and retry logic.
Which Google Cloud service is designed for orchestrating such workflows?
- A Cloud Functions
- B Cloud Composer
- C Dataflow
- D Cloud Scheduler
Xem giải thích
Đáp án
B — Cloud Composer.
Vì sao đúng
Đề mô tả một luồng nhiều bước, nhiều dịch vụ, có thứ tự phụ thuộc và cần logic thử lại, phải quản lý như MỘT pipeline thống nhất. Đó chính xác là bài toán điều phối (orchestration).
⚠ Điểm mấu chốt — ba đặc điểm bắt buộc phải có điều phối:
1. NHIỀU BƯỚC qua NHIỀU DỊCH VỤ
Dataproc → BigQuery → Cloud Function
2. PHỤ THUỘC RÕ RÀNG
bước sau chỉ chạy khi bước trước THÀNH CÔNG
3. LOGIC THỬ LẠI và theo dõi
một bước hỏng → thử lại, cảnh báo,
chạy lại từ đúng chỗ đó
↓
→ Cloud Composer (Apache Airflow)
⚠ DAG mô tả đúng luồng trong đề:
with DAG('xu_ly_hang_ngay', schedule='0 2 * * *') as dag:
xu_ly = DataprocSubmitJobOperator(task_id='dataproc')
nap = GCSToBigQueryOperator(task_id='nap_bigquery')
bao = CloudFunctionInvokeFunctionOperator(
task_id='gui_thong_bao')
xu_ly >> nap >> bao
↓
⚠ Dấu >> chính là PHỤ THUỘC
→ nap chỉ chạy khi xu_ly xong
→ bao chỉ chạy khi nap xong
⚠ Những gì Composer cho mà Scheduler không có:
- Đồ thị phụ thuộc (DAG), có thể rẽ nhánh
- Thử lại theo TỪNG TÁC VỤ, có backoff
- Chạy lại (backfill) cho ngày quá khứ
- Giao diện xem trạng thái từng bước
- Truyền dữ liệu giữa các bước (XCom)
- Hàng trăm OPERATOR dựng sẵn
cho các dịch vụ GCP và bên thứ ba
- SLA và cảnh báo theo tác vụ
Xem thêm câu #12934 (cùng lô): chỉ cần gọi MỘT endpoint đúng giờ → khoá là Cloud Scheduler. Và #12912 (lô 133): chỉ cần một đoạn mã phản ứng theo sự kiện → Cloud Run function. Ba khoá khác nhau theo độ phức tạp của luồng — hoàn toàn nhất quán.
Vì sao các phương án khác sai
-
D (Cloud Scheduler) — đây là phương án gần nhất vì cũng chạy theo lịch, nhưng nó chỉ kích hoạt MỘT đích; không quản lý phụ thuộc giữa nhiều bước, không có DAG, không chạy lại được một bước cụ thể.
-
C (Dataflow) — công cụ XỬ LÝ dữ liệu (Apache Beam), là một bước bên trong pipeline chứ không phải thứ điều phối các bước.
-
A (Cloud Functions) — chạy một đoạn mã; ghép nhiều hàm gọi nhau tay là tự dựng lại một bộ điều phối tồi.
Ghi nhớ
⚠ Chọn công cụ theo ĐỘ PHỨC TẠP — bảng phải thuộc: | Nhu cầu | Công cụ | |---|---| | Một đoạn mã theo sự kiện | Cloud Run function | | Gọi một endpoint theo lịch | Cloud Scheduler | | Chuỗi vài lời gọi API, ít bước | Workflows | | Nhiều bước, nhiều dịch vụ, phụ thuộc phức tạp | Cloud Composer | | Biến đổi dữ liệu quy mô lớn | Dataflow | | Chuỗi biến đổi SQL trong BigQuery | Dataform |
Từ khoá nhận diện:
"nhiều bước, phụ thuộc, thử lại, một pipeline thống nhất" → Cloud Composer "DAG, Airflow" → Cloud Composer "một lời gọi đúng giờ" → Cloud Scheduler "vài bước nhẹ, không cần Airflow" → Workflows "xử lý dữ liệu luồng/lô" → Dataflow
| Cloud Composer — điều cần nhớ | Nội dung |
|---|---|
| Bản chất | Apache Airflow được quản lý |
| DAG | viết bằng Python, đặt trong bucket của môi trường |
| Operator | hàng trăm cái dựng sẵn cho GCP và bên thứ ba |
| ⚠ Chi phí | môi trường THƯỜNG TRỰC — chi phí nền đáng kể |
| Composer 2/3 | chạy trên GKE Autopilot, co giãn tốt hơn |
| Backfill | chạy lại cho khoảng thời gian quá khứ |
| Workflows — lựa chọn nhẹ hơn Composer | Nội dung |
|---|---|
| Không có môi trường thường trực | trả tiền theo BƯỚC thực hiện |
| Khai bằng | YAML hoặc JSON |
| Hợp với | chuỗi lời gọi API, ít bước, ít phụ thuộc |
| Không có | giao diện DAG phong phú, backfill, XCom |
| Chọn Workflows khi | luồng đơn giản và muốn rẻ |
| Chọn Composer khi | phụ thuộc phức tạp, nhiều đội dùng chung |
| Thiết kế DAG cho tốt | Thói quen |
|---|---|
| Tác vụ BẤT BIẾN (idempotent) | chạy lại phải an toàn |
| Tác vụ nhỏ, một việc | dễ chạy lại đúng chỗ hỏng |
| Không xử lý dữ liệu TRONG Airflow | giao cho Dataproc/Dataflow/BigQuery |
Đặt retries và retry_delay |
|
| Đặt SLA và cảnh báo | biết khi luồng chậm |
| Tham số hoá theo ngày chạy | {{ ds }} |
| Sai lầm hay gặp với Composer | Sai lầm |
|---|---|
| Xử lý dữ liệu lớn ngay trong Airflow worker | worker không phải công cụ xử lý dữ liệu |
| DAG quá to, một tác vụ làm tất cả | không chạy lại từng phần được |
| Dùng Composer cho một job đơn giản | chi phí nền không đáng |
| Không đặt thử lại | lỗi mạng tạm thời làm hỏng cả luồng |
| Quên múi giờ | schedule chạy theo UTC nếu không khai |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Bước nào hỏng | giao diện Airflow → Graph view, ô màu đỏ | | Vì sao hỏng | log của chính task trong Airflow, và log của dịch vụ tương ứng | | Luồng có chậm dần không | Gantt view và chỉ số thời lượng |
Và một quy tắc thiết kế đáng giữ khi dùng Composer: Airflow điều phối, không xử lý. Mọi phép tính nặng nên chạy trên Dataproc, Dataflow hoặc BigQuery, còn DAG chỉ ra lệnh và chờ kết quả — worker của Airflow được cấp tài nguyên cho việc điều phối, và nhét xử lý dữ liệu vào đó là cách nhanh nhất để làm sập cả môi trường.
An application publishes thousands of small JSON messages per second. You need a solution that can ingest this high-volume stream of messages and reliably deliver each message to two different, independent downstream systems: one is a Dataflow pipeline for real-time analytics, and the other is a Cloud Function that archives the raw messages to Cloud Storage.
Which service is designed to act as this scalable, serverless messaging buffer that decouples the producer from the consumers?
- A BigQuery
- B Pub/Sub
- C Cloud SQL
- D Cloud Storage
Xem giải thích
Đáp án
B — Pub/Sub.
Vì sao đúng
Đề mô tả đúng một hệ thống hàng đợi thông điệp: hàng nghìn thông điệp mỗi giây, cần giao đáng tin cậy tới HAI hệ thống hạ nguồn ĐỘC LẬP, và phải tách rời bên gửi khỏi bên nhận.
⚠ Điểm mấu chốt — một topic, nhiều subscription độc lập:
Ứng dụng (publisher)
↓
TOPIC "su-kien-json"
↓
├─ Subscription A ──→ Dataflow
│ (phân tích thời gian thực)
│
└─ Subscription B ──→ Cloud Run function
(lưu trữ vào GCS)
↓
⚠ MỖI subscription nhận MỘT BẢN
của MỌI thông điệp
⚠ Hai bên nhận HOÀN TOÀN ĐỘC LẬP:
một bên chậm hay hỏng KHÔNG
ảnh hưởng bên kia
⚠ "Tách rời" (decouple) nghĩa là gì trong thực tế:
KHÔNG có Pub/Sub
↓
Ứng dụng phải gọi thẳng cả hai hệ thống
↓
⚠ Một hệ thống chết → ứng dụng lỗi
⚠ Thêm hệ thống thứ ba → SỬA MÃ ứng dụng
⚠ Bên nhận chậm → ứng dụng bị chặn
CÓ Pub/Sub
↓
Ứng dụng chỉ publish rồi thôi
↓
→ bên nhận chết: thông điệp NẰM CHỜ
trong subscription (tới 7 ngày)
→ thêm bên nhận thứ ba: chỉ cần
tạo subscription mới, KHÔNG sửa mã
⚠ Hai kiểu subscription:
PULL
→ bên nhận tự lấy về
→ Dataflow dùng kiểu này
PUSH
→ Pub/Sub gọi HTTP tới endpoint
→ Cloud Run function dùng kiểu này
↓
Đề có đúng hai kiểu này, mỗi bên một kiểu
⚠ Bảo đảm giao nhận — điều phải thiết kế theo:
Pub/Sub bảo đảm AT-LEAST-ONCE
↓
⚠ Một thông điệp CÓ THỂ tới nhiều lần
↓
→ xử lý phải BẤT BIẾN (idempotent)
↓
Có EXACTLY-ONCE cho pull subscription
trong cùng một Region, nhưng
thiết kế bất biến vẫn là cách an toàn nhất
Vì sao các phương án khác sai
-
D (Cloud Storage) — đây là phương án gần nhất về mặt "nơi chứa tạm", nhưng nó là kho đối tượng, không phải hàng đợi thông điệp: không có subscription, không có bảo đảm giao nhận, không có xác nhận (ack).
-
A (BigQuery) — kho phân tích; đích đến của dữ liệu, không phải bộ đệm truyền tin.
-
C (Cloud SQL) — CSDL giao dịch; dùng nó làm hàng đợi là mẫu phản mẫu kinh điển, và không kham nổi hàng nghìn thông điệp mỗi giây.
Ghi nhớ
⚠ Pub/Sub — điều cần thuộc: | Điểm | Nội dung | |---|---| | Mô hình | publish/subscribe, một topic nhiều subscription | | Bảo đảm | at-least-once (có exactly-once cho pull cùng Region) | | Giữ thông điệp | mặc định 7 ngày, tối đa 31 ngày | | Hai kiểu subscription | pull và push | | Thứ tự | không bảo đảm, trừ khi bật ordering key | | Mở rộng | không cần cấu hình — hoàn toàn không máy chủ |
Từ khoá nhận diện:
"nhiều bên nhận độc lập, tách rời" → Pub/Sub "hàng đợi, bộ đệm, không máy chủ" → Pub/Sub "nạp thẳng vào BigQuery không cần mã" → BigQuery subscription của Pub/Sub "sự kiện từ dịch vụ GCP" → Eventarc (dùng Pub/Sub bên dưới) "hàng đợi tác vụ có kiểm soát tốc độ" → Cloud Tasks
| Pub/Sub ↔ Cloud Tasks — dễ lẫn | Nội dung |
|---|---|
| Pub/Sub | phát tán sự kiện tới NHIỀU bên nhận |
| Cloud Tasks | hàng đợi TÁC VỤ tới MỘT đích, kiểm soát tốc độ |
| Pub/Sub | nhiều subscriber, thông lượng rất cao |
| Cloud Tasks | lên lịch từng tác vụ, giới hạn tốc độ, chống quá tải hệ thống đích |
| Chọn Pub/Sub khi | fan-out như đề này |
| Các loại subscription hữu ích | Loại |
|---|---|
| Pull | bên nhận tự lấy — Dataflow, worker |
| Push | Pub/Sub gọi HTTP — Cloud Run, Functions |
| BigQuery subscription | ghi THẲNG vào BigQuery, không cần mã |
| Cloud Storage subscription | ghi thẳng thành tệp trong GCS |
| Với đề này | hai subscription cuối có thể thay thế cả Dataflow lẫn Cloud Function trong một số kịch bản |
| Cấu hình quan trọng của subscription | Cấu hình |
|---|---|
ackDeadlineSeconds |
phải dài hơn thời gian xử lý — tối đa 600s |
messageRetentionDuration |
giữ bao lâu |
| Dead-letter topic | thông điệp thất bại nhiều lần đi đâu |
maxDeliveryAttempts |
ngưỡng chuyển sang dead-letter |
| Retry policy | backoff giữa các lần thử |
| Ordering key | bảo đảm thứ tự trong cùng một khoá |
| Theo dõi Pub/Sub | Chỉ số |
|---|---|
num_undelivered_messages |
backlog — chỉ số quan trọng nhất |
oldest_unacked_message_age |
thông điệp cũ nhất chờ bao lâu |
| Số thông điệp vào dead-letter | dấu hiệu dữ liệu hỏng |
| Tỉ lệ ack | bên nhận có theo kịp không |
| Cảnh báo nên đặt | backlog và tuổi thông điệp cũ nhất |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Có bao nhiêu thông điệp tồn | Monitoring → num_undelivered_messages | | Bên nhận có theo kịp không | oldest_unacked_message_age | | Có thông điệp hỏng không | kiểm tra dead-letter topic |
Và một điều phải thiết kế theo ngay từ đầu, chứ không thể vá về sau: Pub/Sub giao ít nhất một lần, nên cùng một thông điệp có thể tới hai lần. Với nhánh lưu trữ vào Cloud Storage, hãy đặt tên tệp theo một id ổn định lấy từ chính thông điệp thay vì theo thời điểm nhận — ghi đè cùng một tệp là vô hại, còn tạo hai tệp cho cùng một sự kiện thì âm thầm làm hỏng mọi phép đếm về sau.
You are designing a data ingestion pipeline. You receive data files that contain their schema definition embedded within the file itself. The format is binary, row-based, and is well-known for its excellent support for schema evolution, allowing you to add or remove fields from the schema over time without breaking downstream consumers.
Which data format is being described?
- A Apache Avro
- B JSON
- C CSV
- D Apache Parquet
Xem giải thích
Đáp án
A — Apache Avro.
Vì sao đúng
Đề nêu bốn đặc điểm, và cả bốn cùng chỉ về Avro: lược đồ nhúng ngay trong tệp, nhị phân, theo DÒNG, và hỗ trợ tiến hoá lược đồ rất tốt.
⚠ Điểm mấu chốt — bốn đặc điểm ánh xạ thẳng vào Avro:
"lược đồ nhúng trong tệp"
→ Avro ghi schema JSON ở ĐẦU TỆP
→ đọc tệp là biết cấu trúc, không cần
tệp mô tả riêng
"nhị phân"
→ gọn hơn JSON/CSV rất nhiều
"theo DÒNG (row-based)"
→ ⚠ điểm phân biệt với Parquet
"tiến hoá lược đồ"
→ thêm/bớt trường mà không phá
bên đọc cũ
⚠ ⚠ Avro ↔ Parquet — cặp phân biệt quan trọng nhất:
AVRO — theo DÒNG
↓
Cả một bản ghi nằm liền nhau
↓
→ GHI nhanh, nối thêm dễ
→ đọc TOÀN BỘ bản ghi hiệu quả
→ hợp với NẠP DỮ LIỆU, truyền tin,
lưu dữ liệu thô
PARQUET — theo CỘT
↓
Cùng một cột nằm liền nhau
↓
→ ĐỌC vài cột trên rất nhiều dòng
cực hiệu quả
→ nén tốt hơn hẳn
→ hợp với PHÂN TÍCH
⚠ Tiến hoá lược đồ hoạt động thế nào:
Thêm trường mới CÓ GIÁ TRỊ MẶC ĐỊNH
↓
Bên đọc dùng schema CŨ → bỏ qua trường mới
Bên đọc dùng schema MỚI đọc tệp CŨ
→ lấy giá trị mặc định
↓
→ không bên nào vỡ
↓
⚠ Quy tắc an toàn:
- thêm trường phải có default
- xoá trường chỉ khi trường đó có default
- ĐỔI KIỂU là thay đổi PHÁ VỠ
Vì sao các phương án khác sai
-
D (Apache Parquet) — đây là phương án gần nhất và cũng là định dạng nhị phân có lược đồ, nhưng nó theo CỘT chứ không theo DÒNG, và tiến hoá lược đồ hạn chế hơn Avro. Đề nói rõ "row-based".
-
B (JSON) — văn bản, không phải nhị phân, và không nhúng lược đồ một cách hình thức.
-
C (CSV) — văn bản, không có kiểu dữ liệu, không có lược đồ; đây là định dạng yếu nhất trong bốn phương án.
Ghi nhớ
⚠ Bốn định dạng dữ liệu — bảng phải thuộc: | Định dạng | Kiểu | Lược đồ | Hợp với | |---|---|---|---| | Avro | nhị phân, theo DÒNG | nhúng trong tệp | nạp dữ liệu, truyền tin, tiến hoá lược đồ | | Parquet | nhị phân, theo CỘT | nhúng | PHÂN TÍCH, đọc ít cột | | ORC | nhị phân, theo cột | nhúng | tương tự Parquet, phổ biến trong Hive | | JSON | văn bản | không hình thức | trao đổi dữ liệu, linh hoạt | | CSV | văn bản | không có | đơn giản, phổ biến, dễ hỏng |
Từ khoá nhận diện:
"lược đồ nhúng, theo dòng, tiến hoá lược đồ" → Avro "theo cột, phân tích, nén tốt" → Parquet "lồng nhau, linh hoạt, API" → JSON "bảng đơn giản, mở bằng Excel" → CSV "vừa cột vừa có ACID trên data lake" → Iceberg, Delta, Hudi
| Vì sao lưu theo cột lại nén tốt hơn | Nội dung |
|---|---|
| Cùng một cột | cùng KIỂU, giá trị GIỐNG NHAU nhiều |
| Nén | mã hoá từ điển, run-length rất hiệu quả |
| Đọc | chỉ đọc cột cần — bỏ qua phần còn lại |
| Predicate pushdown | bỏ qua cả row group không thoả điều kiện |
| Kết quả | quét ít byte hơn → truy vấn rẻ hơn |
| Dùng định dạng nào ở đâu | Vị trí |
|---|---|
| Nguồn phát sự kiện, truyền tin | Avro (hoặc JSON) |
| Vùng dữ liệu thô (raw zone) | Avro hoặc định dạng gốc |
| Vùng đã xử lý (curated zone) | Parquet |
| Bảng ngoài của BigQuery | Parquet — hiệu quả nhất |
| Trao đổi với hệ thống ngoài | CSV hoặc JSON — vì tính phổ biến |
| Nạp vào BigQuery — định dạng nào tốt nhất | Nội dung |
|---|---|
| Avro | nhanh nhất, đọc song song tốt, giữ kiểu chính xác |
| Parquet, ORC | cũng rất tốt |
| JSON dòng (NDJSON) | chấp nhận được, chậm hơn |
| CSV | chậm nhất, dễ sai kiểu |
| Nén | Avro và Parquet nạp song song được kể cả khi nén |
| CSV nén gzip | KHÔNG chia nhỏ được → chậm hẳn |
| Vì sao CSV hay gây lỗi | Nguyên nhân |
|---|---|
| Không có kiểu | mọi thứ là chuỗi, phải đoán |
| Dấu phẩy trong giá trị | phải trích dẫn đúng |
| Xuống dòng trong ô | phá cấu trúc |
| Mã hoá ký tự | UTF-8 hay không |
| Số 0 đầu bị mất | mã bưu chính thành số |
| Lời khuyên | dùng CSV để trao đổi, không dùng để lưu trữ |
Ba việc kiểm chứng: | Việc | Cách | |---|---| | Tệp Avro có lược đồ gì | công cụ avro-tools getschema | | Parquet có bao nhiêu row group | parquet-tools meta | | BigQuery hiểu lược đồ thế nào | bq show --schema sau khi nạp |
Và một quy tắc đáng theo khi thiết kế kho dữ liệu nhiều tầng: Avro ở tầng thu nhận, Parquet ở tầng phân tích. Dữ liệu đến theo dòng và lược đồ hay thay đổi thì Avro chịu được; khi đã ổn định và mục đích là truy vấn vài cột trên hàng tỉ dòng, chuyển sang Parquet cắt chi phí quét xuống một phần rất nhỏ.