Ngân hàng đề — Google Cloud Associate Data Practitioner

Tìm thấy 333 câu.

Câu 91 Data Analysis and Presentation

A data analyst needs to create a report that lists customer names and the total amount they have spent. The data exists in two BigQuery tables: customers (with columns id, name) and purchases (with columns purchase_id, customer_id, price).

Which combination of SQL clauses is required to produce the correct report?

  1. A JOIN and GROUP BY
  2. B WHERE and HAVING
  3. C UNION and ORDER BY
  4. D DISTINCT and LIMIT
Xem giải thích

Đáp án

A — JOIN và GROUP BY.

Vì sao đúng

Báo cáo cần tên khách hàng (nằm ở bảng customers) và tổng số tiền đã chi (tính từ bảng purchases). Lấy dữ liệu từ hai bảng cần JOIN; tính tổng cho từng khách cần GROUP BY.

⚠ Điểm mấu chốt — hai mệnh đề giải hai nửa của bài toán:

"tên khách hàng"        → ở bảng customers
"tổng số tiền đã chi"   → tính từ bảng purchases
        ↓
    Cần dữ liệu từ HAI bảng
        ↓
    → JOIN

"TỔNG cho TỪNG khách hàng"
        ↓
    → GROUP BY

⚠ Truy vấn hoàn chỉnh:

SELECT
  c.name,
  SUM(p.price) AS tong_chi_tieu
FROM `du_an.customers` AS c
JOIN `du_an.purchases` AS p
  ON p.customer_id = c.id
GROUP BY c.name;
        ↓
    ⚠ Mọi cột trong SELECT phải nằm trong
      GROUP BY hoặc trong hàm tổng hợp

⚠ Một chi tiết dễ sai — gom theo name hay theo id:

GROUP BY c.name
        ↓
    ⚠ Hai khách hàng TRÙNG TÊN
      sẽ bị GỘP làm một
        ↓
    An toàn hơn:
      SELECT c.id, c.name, SUM(p.price)
      ...
      GROUP BY c.id, c.name
        ↓
    → gom theo KHOÁ, hiển thị tên

⚠ Và khách hàng CHƯA mua gì thì sao:

JOIN (INNER)
    → chỉ khách CÓ giao dịch mới xuất hiện

LEFT JOIN
    → giữ MỌI khách hàng
    → khách chưa mua có SUM = NULL
        ↓
    Dùng IFNULL(SUM(p.price), 0)
    để hiện 0 thay vì NULL
        ↓
    ⚠ Chọn kiểu JOIN theo Ý ĐỊNH NGHIỆP VỤ
      của báo cáo

Xem thêm câu #12942 (lô 134): hỏi riêng về mệnh đề nối bảng → JOIN ... ON. Và #12938 (lô 134): hỏi riêng về tính tổng theo nhóm → GROUP BY. Câu này cần cả hai — ba câu nhất quán.

Vì sao các phương án khác sai

  • B (WHERE và HAVING) — đây là phương án gần nhất vì WHERE có thể nối bảng theo cú pháp cũ, nhưng cả hai đều là mệnh đề LỌC; không cái nào tạo ra phép tính tổng theo nhóm.

  • C (UNION và ORDER BY) — UNION chồng dòng theo chiều DỌC, không lấy được cột từ bảng kia.

  • D (DISTINCT và LIMIT) — loại trùng và cắt số dòng; không tính tổng, không nối bảng.

Ghi nhớ

⚠ Mệnh đề nào cho việc gì — bảng phải thuộc: | Nhu cầu | Mệnh đề | |---|---| | Lấy cột từ NHIỀU bảng | JOIN ... ON | | Tính tổng/đếm/trung bình theo nhóm | GROUP BY + hàm tổng hợp | | Lọc dòng | WHERE | | Lọc nhóm sau khi gom | HAVING | | Chồng dòng của hai tập kết quả | UNION ALL | | Loại dòng trùng | DISTINCT | | Xếp hạng trong nhóm | hàm cửa sổ |

Từ khoá nhận diện:

"tên từ bảng A, tổng từ bảng B" → JOIN + GROUP BY "chỉ lấy khách chi trên 10 triệu" → thêm HAVING "cả khách chưa mua gì" → LEFT JOIN "top 5 mỗi nhóm" → hàm cửa sổ "gộp dữ liệu hai năm" → UNION ALL

Ba cái bẫy của JOIN + GROUP BY Bẫy
Nhân bản dòng khoá bên phải không duy nhất → tổng bị THỔI PHỒNG
Mất khách hàng dùng INNER JOIN khi cần LEFT JOIN
Gom theo tên thay vì khoá trùng tên bị gộp
Cách phát hiện so tổng doanh thu với tổng của riêng bảng purchases
Kiểm khoá SELECT id, COUNT(*) FROM customers GROUP BY 1 HAVING COUNT(*)>1
Truy vấn đầy đủ hơn cho báo cáo thật Thành phần
LEFT JOIN giữ cả khách chưa mua
IFNULL(SUM(price), 0) hiện 0 thay vì NULL
GROUP BY c.id, c.name gom theo khoá
ORDER BY tong_chi_tieu DESC xếp hạng
WHERE p.ngay >= ... giới hạn kỳ báo cáo
HAVING SUM(p.price) > 0 lọc nhóm nếu cần
Hiệu năng trong BigQuery Cách
Bảng lớn JOIN bảng NHỎ BigQuery dùng broadcast join — rất nhanh
Lọc TRƯỚC khi join giảm dữ liệu phải trộn
Chọn ít cột lưu trữ theo cột
Cân nhắc bảng LỒNG ARRAY<STRUCT> — tránh join hẳn
Kiểm tra Execution details — xem bytes shuffled
Kiểm tra kết quả báo cáo Việc
Tổng chung có khớp không so với SELECT SUM(price) FROM purchases
Số khách có đúng không so với COUNT(DISTINCT id)
Có khách nào thiếu không thử LEFT JOIN và tìm NULL
Có giá trị âm hay bất thường MIN, MAX
Nguyên tắc luôn có một phép kiểm chứng độc lập

Ba việc kiểm chứng: | Việc | Cách | |---|---| | JOIN có nhân bản dòng không | so COUNT(*) trước và sau | | Tổng có khớp không | so với tổng của riêng bảng purchases | | Có khách bị bỏ sót không | LEFT JOIN + WHERE p.customer_id IS NULL |

Và một phép kiểm chứng nên gắn kèm mọi báo cáo dạng này: so tổng doanh thu trong báo cáo với tổng của riêng bảng giao dịch. Nếu con số trong báo cáo lớn hơn, phép JOIN đang nhân bản dòng ở đâu đó — và đó là loại lỗi cho ra một bảng số liệu trông hoàn toàn hợp lý, chỉ có điều mọi con số đều sai.

Câu 92 Data Preparation and Ingestion

You need to migrate a 5 TB on-premises PostgreSQL database to Cloud SQL for PostgreSQL. The business requires that the application using the database experiences minimal downtime during the migration process. You need a managed Google Cloud service that can replicate the data from the live on-premises database to the Cloud SQL instance.

Which service should you use?

  1. A Database Migration Service (DMS)
  2. B Cloud Data Fusion
  3. C BigQuery Data Transfer Service
  4. D Transfer Appliance
Xem giải thích

Đáp án

A — Database Migration Service (DMS).

Vì sao đúng

Đề nêu bốn điều: PostgreSQL tại chỗ → Cloud SQL for PostgreSQL, 5 TB, thời gian ngừng tối thiểu, và cần dịch vụ được quản lý có nhân bản từ CSDL đang chạy. DMS được thiết kế cho chính xác việc này.

⚠ Điểm mấu chốt — DMS làm di chuyển TRỰC TUYẾN:

1. FULL DUMP
    → sao chép 5 TB dữ liệu hiện có
    → CSDL nguồn VẪN PHỤC VỤ bình thường

2. CDC (change data capture)
    → đọc WAL của PostgreSQL
    → phát lại mọi thay đổi lên Cloud SQL
    → bám theo liên tục

3. CUTOVER
    → khi replication lag ≈ 0
    → dừng ghi vài phút, thăng cấp đích
        ↓
    ⚠ Thời gian ngừng: VÀI PHÚT
      thay vì nhiều giờ

⚠ Điều kiện phía nguồn PostgreSQL:

wal_level = logical
max_replication_slots  ≥ số cần dùng
max_wal_senders        ≥ số cần dùng
        ↓
    + extension pglogical (với một số phiên bản)
    + tài khoản có quyền REPLICATION
    + MỌI BẢNG PHẢI CÓ KHOÁ CHÍNH
        ↓
    ⚠ Bảng thiếu khoá chính là vấn đề
      hay chặn kế hoạch nhất

⚠ Vì sao DMS đáng chọn hơn tự dựng nhân bản:

- MIỄN PHÍ với chuyển đồng nhất
  (PostgreSQL → Cloud SQL for PostgreSQL)
- Kiểm tra tương thích TRƯỚC khi chạy
- Tự tạo instance đích
- Theo dõi replication lag trong console
- Thăng cấp bằng một thao tác
- Không phải tự vận hành slot và WAL

Xem thêm câu #12987 (cùng lô): cũng khoá DMS, ở đó là so sánh với Data Fusion. Và #12986 (cùng lô) về khái niệm online migration. Ba câu nhất quán — cùng một chủ đề nhìn từ ba góc.

Vì sao các phương án khác sai

  • B (Cloud Data Fusion) — đây là phương án gần nhất trong nhóm công cụ dữ liệu, nhưng nó là ETL cho phân tích: không tạo ra một CSDL vận hành thay thế, và không có CDC liên tục cho việc di chuyển.

  • C (BigQuery Data Transfer Service) — nạp dữ liệu vào BigQuery, không phải vào Cloud SQL.

  • D (Transfer Appliance) — thiết bị vật lý cho TỆP dung lượng rất lớn; 5 TB truyền qua mạng hoàn toàn khả thi, và thiết bị vật lý không có CDC nên không giảm được thời gian ngừng.

Ghi nhớ

⚠ Chọn dịch vụ theo NGUỒN và ĐÍCH — bảng phải thuộc: | Nguồn → Đích | Dịch vụ | |---|---| | CSDL → Cloud SQL / AlloyDB | Database Migration Service | | CSDL → BigQuery (CDC) | Datastream | | Nhiều nguồn → BigQuery, có biến đổi | Cloud Data Fusion, Dataflow | | SaaS → BigQuery | BigQuery Data Transfer Service | | Kho đối tượng → GCS | Storage Transfer Service | | Hàng trăm TB, băng thông kém | Transfer Appliance |

Từ khoá nhận diện:

"PostgreSQL tại chỗ → Cloud SQL, ít thời gian ngừng" → DMS "CSDL → BigQuery gần thời gian thực" → Datastream "cần biến đổi dữ liệu" → Data Fusion / Dataflow "5 TB qua mạng" → hoàn toàn khả thi, không cần thiết bị vật lý "hàng trăm TB, mạng chậm" → Transfer Appliance

Bốn giai đoạn của một job DMS Giai đoạn
Kiểm tra DMS tự chạy test kết nối và tương thích
Full dump sao chép dữ liệu hiện có
CDC bám theo thay đổi — theo dõi lag
Promote thăng cấp đích thành CSDL độc lập
Sau đó cấu hình HA, replica, sao lưu cho instance mới
Kết nối tới CSDL tại chỗ Cách
Cloud VPN phổ biến, dễ dựng
Dedicated / Partner Interconnect băng thông lớn
Reverse SSH tunnel DMS hỗ trợ cho trường hợp đơn giản
IP allowlist ít an toàn hơn
Băng thông 5 TB cần tính thời gian dump ban đầu
Kế hoạch cắt chuyển cho 5 TB Bước
1 Chạy full dump trước nhiều ngày
2 Theo dõi lag trong giai đoạn CDC
3 Kiểm thử ứng dụng trên bản sao
4 Đối chiếu số dòng và checksum
5 Đặt cửa sổ cắt chuyển ngắn, dừng ghi, đợi lag = 0
6 Thăng cấp, đổi chuỗi kết nối
7 GIỮ nguồn vài ngày để quay lui
Sau khi thăng cấp — đừng quên Việc
Bật HA instance mới chưa có
Bật sao lưu tự động và PITR
Tạo read replica nếu cần
Bật deletion protection
ANALYZE / cập nhật thống kê hiệu năng truy vấn
Đo lại hiệu năng so với hệ thống cũ

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Job đang ở giai đoạn nào | console → Database Migration → Migration jobs | | Độ trễ nhân bản | cùng màn hình, chỉ số replication delay | | Dữ liệu đã khớp chưa | so COUNT(*) từng bảng trước khi cắt chuyển |

Và một điều kiện kỹ thuật nên kiểm tra ngay ở giai đoạn khảo sát, trước khi hứa hẹn thời gian ngừng với bên nghiệp vụ: mọi bảng đã có khoá chính chưa. Nhân bản logic của PostgreSQL cần khoá để xác định dòng nào thay đổi, và một bảng lịch sử cũ không có khoá chính có thể buộc cả kế hoạch phải đổi cách tiếp cận — tốt hơn là biết điều đó từ tuần đầu tiên.

Câu 93 Data Pipeline Orchestration

A weekly machine learning workflow must be automated. The workflow has three sequential steps that all run in BigQuery:

1. Run a SQL script to preprocess data and create a training table.

2. Use the training table to train a BQML model.

3. After the model is trained, run an evaluation function. Each step must only start after the previous one has successfully completed.

Which service is designed to orchestrate this dependent sequence of tasks?

  1. A A single Cloud Function that runs all three jobs.
  2. B Three separate BigQuery scheduled queries set to run 10 minutes apart.
  3. C Cloud Composer
  4. D The BigQuery UI.
Xem giải thích

Đáp án

C — Cloud Composer.

Vì sao đúng

Đề mô tả ba bước TUẦN TỰ, mỗi bước chỉ được chạy khi bước trước THÀNH CÔNG. Đó chính là định nghĩa của điều phối có phụ thuộc.

⚠ Điểm mấu chốt — DAG diễn đạt chính xác luồng trong đề:

with DAG('ml_hang_tuan', schedule='0 2 * * 1') as dag:
    tien_xu_ly = BigQueryInsertJobOperator(
        task_id='tien_xu_ly',
        configuration={'query': {
            'query': 'CREATE OR REPLACE TABLE ...',
            'useLegacySql': False}})

    huan_luyen = BigQueryInsertJobOperator(
        task_id='huan_luyen',
        configuration={'query': {
            'query': 'CREATE OR REPLACE MODEL ...',
            'useLegacySql': False}})

    danh_gia = BigQueryInsertJobOperator(
        task_id='danh_gia',
        configuration={'query': {
            'query': 'SELECT * FROM ML.EVALUATE(...)',
            'useLegacySql': False}})

    tien_xu_ly >> huan_luyen >> danh_gia

⚠ ⚠ Vì sao "ba scheduled query cách nhau 10 phút" là bẫy chính:

Bước 1 mất 10 phút hôm nay
        ↓
    Tuần sau dữ liệu tăng gấp đôi
        ↓
    Bước 1 mất 25 phút
        ↓
    ⚠ Bước 2 vẫn khởi động sau 10 phút
    → huấn luyện trên bảng CHƯA XONG
      hoặc bảng của TUẦN TRƯỚC
        ↓
    ⚠ Bước 1 THẤT BẠI
    → bước 2 và 3 VẪN CHẠY
    → mô hình huấn luyện trên dữ liệu cũ
    → KHÔNG có lỗi nào báo ra
        ↓
    → "đợi 10 phút" là HY VỌNG,
      không phải PHỤ THUỘC

⚠ Điều Composer cho mà cách kia không có:

- Bước sau chỉ chạy khi bước trước THÀNH CÔNG
- Thử lại theo TỪNG bước
- Chạy lại từ đúng bước hỏng
- Một màn hình xem trạng thái cả luồng
- Cảnh báo khi luồng chậm (SLA)
- Backfill cho tuần đã lỡ

Xem thêm câu #12996 (cùng lô) và #12948 (lô 134): cùng khoá Cloud Composer, cùng lý do phụ thuộc nhiều bước. Và #13000 (cùng lô) khoá Cloud Scheduler vì chỉ có một job duy nhất. Bốn câu, một hệ quy tắc nhất quán.

Vì sao các phương án khác sai

  • B (ba scheduled query cách nhau 10 phút) — đây là phương án bẫy chính: thời gian chờ KHÔNG PHẢI phụ thuộc. Bước trước chậm hoặc hỏng thì bước sau vẫn chạy trên dữ liệu sai.

  • A (một Cloud Function chạy cả ba) — hàm phải tự chờ từng job BigQuery, dễ chạm giới hạn thời gian, và bạn phải tự viết lại toàn bộ logic thử lại và theo dõi.

  • D (giao diện BigQuery) — thủ công, không phải tự động hoá.

Ghi nhớ

⚠ Phụ thuộc thật ↔ thời gian chờ — bảng phải thuộc: | Cách | Bản chất | |---|---| | task_a >> task_b trong DAG | PHỤ THUỘC THẬT — chờ thành công | | Hai job cách nhau N phút | HY VỌNG — không kiểm tra gì | | Sensor chờ điều kiện | phụ thuộc theo trạng thái dữ liệu | | Trigger theo sự kiện | phụ thuộc theo sự kiện | | Nguyên tắc | đừng bao giờ dùng thời gian thay cho phụ thuộc |

Từ khoá nhận diện:

"chỉ chạy khi bước trước thành công" → Cloud Composer "cách nhau N phút" → bẫy kinh điển, luôn sai "một job theo lịch" → Cloud Scheduler "chỉ toàn SQL trong BigQuery, cần kiểm thử" → Dataform cũng là lựa chọn tốt "vài bước nhẹ, muốn rẻ" → Cloud Workflows

Với luồng TOÀN BỘ trong BigQuery — hai lựa chọn tốt Lựa chọn
Cloud Composer đáp án của đề — mạnh nhất, có DAG đầy đủ
Dataform quản lý phụ thuộc giữa các bước SQL, có kiểm thử, miễn phí
Chọn Composer khi luồng còn chạm tới dịch vụ khác
Chọn Dataform khi hoàn toàn trong BigQuery và muốn tiết kiệm
Cloud Workflows cũng làm được, khai bằng YAML, rẻ
Cấu hình DAG nên có Cấu hình
retries và retry_delay chịu lỗi tạm thời
trigger_rule mặc định all_success — đúng cho đề này
execution_timeout tránh treo mãi
SLA cảnh báo khi luồng CHẬM, không chỉ khi hỏng
BigQueryCheckOperator kiểm tra dữ liệu giữa các bước
catchup=False tránh chạy dồn khi mới bật DAG
Luồng ML hằng tuần nên thêm gì Bước
Kiểm tra chất lượng dữ liệu trước khi huấn luyện
So chỉ số mô hình MỚI với mô hình CŨ
Chỉ triển khai nếu tốt hơn rẽ nhánh trong DAG
Lưu lịch sử chỉ số phát hiện trôi theo thời gian
Cảnh báo khi chất lượng giảm
Vì sao "im lặng sai" nguy hiểm hơn "báo lỗi" Nội dung
Job thất bại có người biết, có người sửa
Job chạy trên dữ liệu cũ không ai biết trong nhiều tuần
Với mô hình ML dự đoán sai lệch dần mà không có tín hiệu
Vì vậy phụ thuộc tường minh + kiểm tra dữ liệu
Nguyên tắc thà dừng còn hơn chạy sai

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Bước nào hỏng | Airflow Graph view | | Bước trước có thật sự xong chưa | kiểm tra thời gian kết thúc của task | | Mô hình có được huấn luyện trên dữ liệu mới không | ML.TRAINING_INFO và thời điểm tạo bảng |

Và một lý do rất thực tế để không bao giờ dùng "cách nhau 10 phút" cho luồng huấn luyện mô hình: nó hỏng theo kiểu im lặng. Job vẫn xanh, mô hình vẫn được tạo, chỉ có điều nó học trên dữ liệu của tuần trước — và loại sai lệch đó tích tụ dần cho tới khi ai đó tình cờ so hai con số và phát hiện ra mọi thứ đã lệch từ lâu.

Câu 94 Data Management

What is the fundamental difference in how AEAD (Authenticated Encryption with Associated Data) functions and Dynamic Data Masking protect data in a BigQuery column?

  1. A AEAD is a table-level control, while masking is a column-level control.
  2. B AEAD is an older, legacy feature, while masking is a modern feature.
  3. C AEAD encrypts the data so it is stored as ciphertext at rest, while masking obscures plaintext data at query time.
  4. D AEAD is managed with IAM (Identity and Access Management) policies, while masking is managed with SQL (Structured Query Language) views.
Xem giải thích

Đáp án

C — AEAD MÃ HOÁ dữ liệu nên nó được lưu ở dạng BẢN MÃ trên đĩa, còn masking CHE dữ liệu nguyên văn NGAY LÚC TRUY VẤN.

Vì sao đúng

Khác biệt cơ bản nằm ở dữ liệu được lưu ở dạng nào và thời điểm phép bảo vệ xảy ra.

⚠ Điểm mấu chốt — hai trục phân biệt:

AEAD
        ↓
    Dữ liệu ghi vào bảng đã là BẢN MÃ
        ↓
    → nhìn thẳng vào bảng chỉ thấy chuỗi byte
    → muốn đọc phải GỌI HÀM GIẢI MÃ
      kèm KHOÁ
        ↓
    Bảo vệ xảy ra LÚC GHI

DYNAMIC DATA MASKING
        ↓
    Dữ liệu trên đĩa là NGUYÊN VĂN
        ↓
    → BigQuery che giá trị KHI TRẢ KẾT QUẢ,
      tuỳ vai trò người truy vấn
        ↓
    Bảo vệ xảy ra LÚC ĐỌC

⚠ AEAD trông thế nào trong SQL:

-- ghi
INSERT INTO t (email_ma)
SELECT AEAD.ENCRYPT(
  (SELECT keyset FROM khoa),
  email,
  'ngu_canh_bo_sung');

-- đọc
SELECT AEAD.DECRYPT_STRING(
  (SELECT keyset FROM khoa),
  email_ma,
  'ngu_canh_bo_sung');
        ↓
    ⚠ "Associated data" (ngữ cảnh bổ sung)
      được XÁC THỰC nhưng KHÔNG mã hoá
    → chống việc hoán đổi bản mã
      giữa các dòng

⚠ Hệ quả thực tế của việc lưu bản mã:

Cột đã mã hoá bằng AEAD
        ↓
    ⚠ KHÔNG lọc được: WHERE email = '...'
    ⚠ KHÔNG nối bảng theo cột đó
    ⚠ KHÔNG gom nhóm được
    ⚠ Nén kém hơn
        ↓
    → chỉ dùng khi THẬT SỰ cần
      dữ liệu ở dạng bản mã trong bảng

Xem thêm câu #12982 (cùng lô): hỏi chọn cơ chế nào cho tình huống che số điện thoại → dynamic data masking. Câu này hỏi khác biệt cơ bản giữa hai cơ chế. Và #12931 (lô 133) về CMEK — quản lý khoá, một tầng khác nữa. Ba câu nhất quán.

Vì sao các phương án khác sai

  • A (AEAD ở cấp bảng, masking ở cấp cột) — sai: cả hai đều áp ở cấp CỘT. AEAD là hàm SQL dùng trên một cột; masking gắn vào cột qua policy tag.

  • B (AEAD là tính năng cũ, masking là hiện đại) — sai; cả hai đều là tính năng hiện hành, phục vụ hai mục đích khác nhau.

  • D (AEAD quản lý bằng IAM, masking bằng view SQL) — sai cả hai vế: AEAD quản lý bằng khoá trong SQL, còn masking quản lý bằng policy tag và IAM.

Ghi nhớ

⚠ Ba cơ chế bảo vệ cột — bảng phải thuộc: | Cơ chế | Dữ liệu trên đĩa | Bảo vệ xảy ra khi | Vẫn lọc/join được? | |---|---|---|---| | Column-level security | nguyên văn | lúc đọc | có (nếu đủ quyền) | | Dynamic data masking | nguyên văn | lúc đọc | có (giá trị bị che) | | AEAD | BẢN MÃ | lúc ghi | KHÔNG |

Từ khoá nhận diện:

"dữ liệu phải là bản mã trong bảng" → AEAD "dữ liệu gốc nguyên vẹn, che khi truy vấn" → masking "chặn hẳn không cho đọc cột" → column-level security "ai giữ khoá mã hoá đĩa" → CMEK / GMEK — tầng khác hẳn "lọc dòng theo người dùng" → row-level security

Khi nào thật sự cần AEAD Trường hợp
Quy định bắt dữ liệu là bản mã ngay trong bảng
Mỗi khách hàng một khoá riêng cách ly tuyệt đối
Crypto-shredding xoá khoá = xoá dữ liệu của khách đó
Không tin cả quản trị viên BigQuery họ thấy bảng nhưng không giải mã được
Còn lại masking hoặc CLS đơn giản hơn nhiều
Quản lý khoá cho AEAD Cách
KEYS.NEW_KEYSET('AEAD_AES_GCM_256') tạo keyset
Lưu keyset ở đâu bảng riêng có quyền rất hẹp, hoặc Cloud KMS
KEYS.KEYSET_CHAIN bọc keyset bằng khoá KMS — cách an toàn nhất
Xoay khoá thêm khoá mới vào keyset, mã hoá lại dần
Mất keyset mất dữ liệu vĩnh viễn
Ba tầng mã hoá của BigQuery — đừng lẫn Tầng
Mã hoá đĩa mặc định GMEK — luôn bật, không tắt được
CMEK bạn quản khoá đĩa qua Cloud KMS
AEAD mã hoá Ở CẤP CỘT bằng SQL
Ba tầng độc lập, dùng chồng lên nhau được
Câu hỏi thường lẫn "mã hoá" ở đây là tầng nào
Chọn cơ chế theo yêu cầu Yêu cầu
"Người thường thấy bản che, người có quyền thấy đủ" masking
"Người thường không được đọc cột đó" column-level security
"Dữ liệu trong bảng phải là bản mã" AEAD
"Chúng tôi phải giữ khoá đĩa" CMEK
"Chỉ thấy dòng của mình" row-level security

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Cột đang lưu bản mã hay nguyên văn | truy vấn thử bằng tài khoản đặc quyền | | Quy tắc che là gì | Dataplex → Data policies | | Keyset AEAD ai truy cập được | quyền của bảng chứa keyset, hoặc IAM của khoá KMS |

Và một cái giá của AEAD cần cân nhắc rất kỹ trước khi chọn: cột đã mã hoá gần như không dùng được cho phân tích. Không lọc, không nối bảng, không gom nhóm theo cột đó — nên nếu mục tiêu chỉ là "người thường không nhìn thấy số điện thoại đầy đủ", masking cho cùng kết quả bảo mật mà giữ nguyên khả năng phân tích của kho dữ liệu.

Câu 95 Data Analysis and Presentation

An analyst frequently joins a 5 TB fact_sales table with a 500 MB dim_store table in BigQuery using the store_id column. These queries are running slower than desired. The fact_sales table is already partitioned by transaction_date.

What additional optimization should you apply to the fact_sales table to improve the performance of this specific join?

  1. A Recreate the fact_sales table and add clustering on the store_id column.
  2. B Enable BigQuery's long-term storage pricing.
  3. C Increase the number of slots in your reservation.
  4. D Export the dim_store table to a Google Sheet.
Xem giải thích

Đáp án

A — Tạo lại bảng fact_sales và thêm PHÂN CỤM (clustering) theo cột store_id.

Vì sao đúng

Bảng đã phân vùng theo transaction_date, nên phần tối ưu theo thời gian đã có. Nút thắt còn lại là phép JOIN theo store_id, và phân cụm theo chính cột đó là công cụ dành cho việc này.

⚠ Điểm mấu chốt — phân vùng và phân cụm giải hai bài toán khác nhau:

PARTITION BY transaction_date   (đã có)
        ↓
    → cắt bỏ hẳn những NGÀY không cần

CLUSTER BY store_id             (thêm vào)
        ↓
    → SẮP XẾP dữ liệu theo store_id
      BÊN TRONG mỗi phân vùng
        ↓
    → các dòng cùng store_id nằm CẠNH NHAU
    → BigQuery bỏ qua các KHỐI không chứa
      store_id đang cần
    → JOIN và lọc theo store_id nhanh hơn hẳn

⚠ Tạo lại bảng:

CREATE TABLE `du_an.fact_sales_moi`
PARTITION BY DATE(transaction_date)
CLUSTER BY store_id
AS SELECT * FROM `du_an.fact_sales`;
        ↓
    ⚠ Không đổi bảng đang có tại chỗ được
    → tạo bảng mới rồi chuyển sang

⚠ Vì sao JOIN 5 TB với 500 MB lại chậm dù đã có broadcast:

BigQuery thường BROADCAST bảng nhỏ
    (500 MB) tới mọi worker
        ↓
    → phần join đã khá tốt
        ↓
    Nhưng vẫn phải ĐỌC và XỬ LÝ
    toàn bộ phần fact_sales liên quan
        ↓
    Phân cụm theo store_id giúp:
      - lọc theo store_id rẻ hơn nhiều
      - dữ liệu cùng store gom lại
        → ít khối phải đọc

⚠ Bốn cột phân cụm — thứ tự có ý nghĩa:

CLUSTER BY a, b, c, d
        ↓
    Sắp xếp theo a, rồi trong a sắp theo b...
        ↓
    ⚠ Lọc theo `a` → rất hiệu quả
    ⚠ Lọc CHỈ theo `c` → gần như không lợi
        ↓
    → đặt cột LỌC NHIỀU NHẤT lên trước

Xem thêm câu #12979 (lô 134): cùng chủ đề tối ưu bảng lớn, nhưng ở đó bảng CHƯA phân vùng và truy vấn lọc theo NGÀY → khoá là phân vùng. Câu này bảng đã phân vùng theo ngày rồi, nút thắt là JOIN theo store_id → phân cụm. Hai khoá khác nhau vì tình huống khác nhau — hoàn toàn nhất quán.

Vì sao các phương án khác sai

  • C (mua thêm slot) — đây là phương án hay bị chọn khi truy vấn chậm, nhưng nó chỉ cấp thêm năng lực tính toán cho cùng một khối lượng dữ liệu phải quét; tốn tiền mà không sửa gốc rễ.

  • B (bật giá long-term storage) — long-term storage là TỰ ĐỘNG và chỉ ảnh hưởng giá lưu trữ, không liên quan tới hiệu năng truy vấn.

  • D (xuất dim_store sang Google Sheet) — làm chậm hơn nhiều: bảng ngoài trỏ vào Sheet chậm hơn hẳn bảng thường.

Ghi nhớ

⚠ Phân vùng ↔ phân cụm — bảng phải thuộc: | | Partitioning | Clustering | |---|---|---| | Cơ chế | chia bảng thành phần vật lý | sắp xếp trong phân vùng | | Số cột | MỘT | tối đa 4, CÓ THỨ TỰ | | Kiểu cột | DATE, TIMESTAMP, DATETIME, INT64 | hầu hết kiểu | | Giảm chi phí | đoán trước được | không đoán trước được | | Hợp với | lọc theo NGÀY | lọc/join theo cột có nhiều giá trị | | Nên dùng | CẢ HAI cùng lúc |

Từ khoá nhận diện:

"đã phân vùng rồi, join chậm" → thêm phân cụm theo cột join "luôn lọc theo ngày" → phân vùng "lọc theo nhiều cột khác nhau" → phân cụm "mua thêm slot" → giải pháp cuối cùng, không phải đầu tiên "truy vấn lặp lại tốn kém" → materialized view

Chọn cột phân cụm thế nào Nguyên tắc
Cột hay dùng trong WHERE và JOIN như store_id ở đây
Nhiều giá trị phân biệt (high cardinality) phân cụm mới có tác dụng
Đặt cột LỌC NHIỀU NHẤT lên TRƯỚC thứ tự quan trọng
Tối đa 4 cột thêm nữa không được
Cột ít giá trị (như giới tính) phân cụm gần như vô ích
Vì sao phân cụm không "đoán trước" được chi phí Nội dung
Ước tính trước truy vấn KHÔNG phản ánh phần cắt được nhờ phân cụm
Phần cắt thật chỉ biết SAU KHI chạy
Vì vậy --dry_run cho số byte cao hơn thực tế
Kiểm tra thật so total_bytes_billed trong INFORMATION_SCHEMA.JOBS
Phân vùng thì ngược lại cắt được biết trước
Các cách tối ưu JOIN trong BigQuery Cách
Phân cụm theo khoá join như đề này
Lọc TRƯỚC khi join giảm dữ liệu phải trộn
Bảng nhỏ để BigQuery broadcast tự động khi đủ nhỏ
Phi chuẩn hoá bằng ARRAY<STRUCT> tránh join hẳn
Materialized view cho truy vấn lặp lại
Kiểm tra Execution details → bytes shuffled
Bảo trì phân cụm Nội dung
BigQuery TỰ tái phân cụm miễn phí, chạy nền
Ghi mới liên tục dữ liệu mới chưa sắp ngay
Không cần làm gì thủ công khác với chỉ mục của CSDL truyền thống
Đổi cột phân cụm ALTER TABLE ... SET OPTIONS, chỉ áp cho dữ liệu mới
Muốn áp cho toàn bộ tạo lại bảng

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Bảng có phân cụm chưa | bq show <dataset>.<bảng> → Clustered By | | Truy vấn có nhanh hơn không | so total_bytes_billed và slot time trước/sau | | Bước nào tốn nhất | Execution details của job |

Và một thứ tự xử lý đáng nhớ khi một truy vấn BigQuery chạy chậm: giảm dữ liệu phải quét trước, mua thêm năng lực tính toán sau cùng. Phân vùng, phân cụm, chọn ít cột và materialized view đều tấn công vào lượng dữ liệu; thêm slot chỉ giúp xử lý cùng lượng dữ liệu ấy nhanh hơn — và gần như luôn đắt hơn.

Câu 96 Data Analysis and Presentation

A company has over 100 analysts organized into four different departments. All analysts frequently query the same set of large, multi-terabyte tables in BigQuery to build reports. Many of their queries perform similar complex aggregations and joins to calculate key business metrics, such as daily active users or monthly revenue.

This pattern of repeated, heavy queries is leading to high and unpredictable costs. The company needs a solution that can pre-calculate the results of these common, expensive queries. The solution should be largely transparent to the analysts, allowing them to continue querying the base tables while benefiting from reduced costs and faster performance, with the pre-calculated data being refreshed automatically.

Which BigQuery feature is the most effective solution to meet these requirements?

  1. A

    Materialized Views

  2. B

    Scheduled Queries writing to summary tables

  3. C

    Analytics Hub

  4. D

    BigQuery Caching

Xem giải thích

Đáp án

A — Materialized Views (khung nhìn được vật chất hoá).

Vì sao đúng

Đề nêu ba yêu cầu: tính trước kết quả của các truy vấn nặng hay lặp lại, trong suốt với người dùng (họ vẫn viết truy vấn như cũ), và giảm chi phí khó lường. Materialized view làm đúng cả ba.

⚠ Điểm mấu chốt — BigQuery TỰ dùng materialized view:

Tạo materialized view tính sẵn
    doanh thu theo ngày
        ↓
    Nhà phân tích viết truy vấn
    trên BẢNG GỐC như bình thường
        ↓
    ⚠ BigQuery TỰ NHẬN RA có thể trả lời
      từ materialized view
    → tự viết lại truy vấn (smart tuning)
        ↓
    → nhà phân tích KHÔNG PHẢI ĐỔI GÌ
    → chi phí và thời gian giảm mạnh
        ↓
    Đây chính là "trong suốt với người dùng"

⚠ Tạo materialized view:

CREATE MATERIALIZED VIEW `du_an.mv_doanh_thu_ngay`
PARTITION BY ngay
CLUSTER BY phong_ban
OPTIONS (
  enable_refresh = true,
  refresh_interval_minutes = 30
) AS
SELECT
  DATE(thoi_diem) AS ngay,
  phong_ban,
  COUNT(DISTINCT user_id) AS nguoi_dung,
  SUM(doanh_thu) AS tong_doanh_thu
FROM `du_an.su_kien`
GROUP BY ngay, phong_ban;

⚠ Làm mới GIA TĂNG — điểm mạnh nhất:

Bảng gốc có dữ liệu mới
        ↓
    ⚠ Materialized view KHÔNG tính lại
      từ đầu
    → chỉ xử lý PHẦN THAY ĐỔI
        ↓
    → luôn cập nhật, chi phí thấp
        ↓
    Và ngay cả khi chưa kịp làm mới,
    BigQuery vẫn cho kết quả ĐÚNG bằng
    cách kết hợp view với phần dữ liệu mới

Xem thêm câu #13005 (cùng lô): cũng về tối ưu truy vấn nặng, nhưng bằng phân cụm. Hai kỹ thuật bổ sung nhau: phân vùng và phân cụm giảm dữ liệu phải quét; materialized view tránh TÍNH LẠI.

Vì sao các phương án khác sai

  • B (scheduled query ghi vào bảng tổng hợp) — đây là phương án gần nhất và rất phổ biến trong thực tế, nhưng nó KHÔNG trong suốt: nhà phân tích phải biết và tự trỏ vào bảng tổng hợp. Nó cũng không tự làm mới gia tăng và dữ liệu cũ tới lần chạy kế tiếp.

  • D (BigQuery caching) — cache chỉ áp cho truy vấn GIỐNG HỆT NHAU của cùng người dùng, hết hạn sau 24 giờ và mất hiệu lực khi bảng thay đổi. Với 100 nhà phân tích viết các truy vấn hơi khác nhau, cache gần như không giúp gì.

  • C (Analytics Hub) — công cụ chia sẻ dataset, không tính trước gì cả.

Ghi nhớ

⚠ Bốn cách giảm chi phí truy vấn lặp lại — bảng phải thuộc: | Cách | Trong suốt? | Tự làm mới? | |---|---|---| | Materialized view | CÓ — BigQuery tự dùng | CÓ, gia tăng | | Bảng tổng hợp + scheduled query | không — phải tự trỏ vào | theo lịch, tính lại | | BigQuery cache | có | chỉ với truy vấn giống hệt | | BI Engine | CÓ — tăng tốc trong suốt | tự động | | Phân vùng + phân cụm | có | không áp dụng |

Từ khoá nhận diện:

"tính trước, trong suốt với người dùng" → materialized view "tăng tốc dashboard" → BI Engine "bảng tổng hợp theo lịch" → scheduled query — không trong suốt "cùng một truy vấn chạy lại" → cache — miễn phí nhưng hạn chế "chia sẻ dataset" → Analytics Hub

Materialized view — giới hạn cần biết Giới hạn
Chỉ hỗ trợ một tập SQL nhất định GROUP BY, phần lớn hàm tổng hợp
COUNT(DISTINCT) dùng APPROX_COUNT_DISTINCT hoặc HLL
Hạn chế với JOIN có hỗ trợ nhưng kèm điều kiện
Không có ORDER BY, LIMIT trong định nghĩa
Không dùng hàm không tất định CURRENT_TIMESTAMP()...
Tối đa 20 view trên một bảng gốc
Chi phí của materialized view Khoản
Lưu trữ như một bảng — thường nhỏ hơn nhiều bảng gốc
Làm mới tính theo byte xử lý của phần thay đổi
Truy vấn rẻ hơn hẳn so với quét bảng gốc
Tắt tự làm mới enable_refresh = false rồi làm mới thủ công
Cân nhắc bảng gốc thay đổi liên tục → chi phí làm mới cao
BI Engine — bổ sung rất mạnh cho dashboard Nội dung
Việc bộ nhớ đệm trong RAM cho BigQuery
Trong suốt không đổi truy vấn, không đổi công cụ
Hợp với Looker Studio, Connected Sheets, dashboard
Cấu hình mua dung lượng theo GB
Kết hợp materialized view + BI Engine cho hiệu quả cao nhất
Kiểm soát chi phí cho 100 nhà phân tích Cách
maximum_bytes_billed mặc định trần cho mỗi truy vấn
Custom quota theo người dùng trần theo ngày
Reservation với slot chi phí ĐOÁN TRƯỚC ĐƯỢC thay vì theo byte
Materialized view giảm khối lượng thật
Đào tạo tránh SELECT *, luôn lọc theo phân vùng
Theo dõi INFORMATION_SCHEMA.JOBS — ai tốn nhất

Ba việc kiểm chứng: | Việc | Cách | |---|---| | BigQuery có dùng view không | Execution details — xem có nhắc tới materialized view | | View còn tươi không | SELECT * FROM <dataset>.INFORMATION_SCHEMA.MATERIALIZED_VIEWS | | Chi phí làm mới bao nhiêu | INFORMATION_SCHEMA.JOBS, lọc job làm mới |

Và một hướng đáng cân nhắc song song với materialized view khi chi phí đã trở nên khó lường với 100 người dùng: chuyển sang mô hình slot (reservation). Nó biến hoá đơn từ "theo byte quét, phụ thuộc việc ai gõ gì" thành một con số cố định hằng tháng — và với quy mô bốn phòng ban truy vấn liên tục, đó thường vừa rẻ hơn vừa dễ lập ngân sách hơn.

Câu 97 Data Management

A new data engineer needs to be able to create and manage Dataproc jobs and clusters in a specific project. However, following the principle of least privilege, they should not have permissions to access or modify other Google Cloud resources like BigQuery datasets or Cloud SQL instances.

Which predefined IAM role should you grant them at the project level?

  1. A Dataproc Worker
  2. B Compute Admin
  3. C Dataproc Editor
  4. D Project Editor
Xem giải thích

Đáp án

C — Dataproc Editor (roles/dataproc.editor).

Vì sao đúng

Đề cần toàn quyền tạo và quản lý cụm cùng job Dataproc, nhưng KHÔNG có quyền trên BigQuery, Cloud SQL hay tài nguyên khác. Vai trò định sẵn của chính dịch vụ Dataproc là mức vừa đủ.

⚠ Điểm mấu chốt — vai trò theo DỊCH VỤ giới hạn phạm vi:

roles/dataproc.editor
        ↓
    CÓ:
      tạo, sửa, xoá CỤM
      nộp, huỷ, xem JOB
      quản lý workflow template
      autoscaling policy
        ↓
    KHÔNG CÓ:
      quyền nào trên BigQuery
      quyền nào trên Cloud SQL
      quyền IAM
        ↓
    ⚠ Đúng ranh giới đề yêu cầu

⚠ Các vai trò của Dataproc:

roles/dataproc.viewer
    → chỉ xem cụm và job

roles/dataproc.editor          ← đề này
    → tạo và quản lý cụm, job

roles/dataproc.admin
    → thêm quyền IAM trên tài nguyên Dataproc

roles/dataproc.worker
    → ⚠ dành cho SERVICE ACCOUNT của VM
      trong cụm, KHÔNG dành cho người

⚠ Nhưng để cụm chạy được, cần thêm hai thứ:

1. roles/iam.serviceAccountUser
    → trên service account mà CỤM sẽ chạy dưới
    → thiếu là KHÔNG TẠO ĐƯỢC cụm

2. Quyền trên DỮ LIỆU
    → job Spark đọc GCS → storage.objectViewer
    → ghi BigQuery → bigquery.dataEditor
        ↓
    ⚠ Nhưng đề nói rõ KHÔNG cho quyền
      BigQuery → nên trong phạm vi câu hỏi,
      dataproc.editor là đáp án

Xem thêm câu #12995 (cùng lô) và #12952, #12956, #12957, #12975 (lô 134): cùng họ câu hỏi quyền tối thiểu. Quy tắc chung: vai trò ĐỊNH SẴN của chính dịch vụ, cấp ở PHẠM VI hẹp nhất.

Vì sao các phương án khác sai

  • B (Compute Admin) — đây là phương án gần nhất vì cụm Dataproc chạy trên VM Compute Engine, nhưng nó cho toàn quyền trên MỌI VM trong project, kể cả những máy không liên quan tới Dataproc — quá rộng.

  • A (Dataproc Worker) — vai trò dành cho service account của chính các VM trong cụm, không phải cho người dùng; nó không cho phép tạo cụm.

  • D (Project Editor) — rộng một cách nguy hiểm: sửa được gần như mọi tài nguyên, kể cả BigQuery và Cloud SQL mà đề cấm.

Ghi nhớ

⚠ Các vai trò Dataproc — bảng phải thuộc: | Vai trò | Dành cho | |---|---| | roles/dataproc.viewer | chỉ xem | | roles/dataproc.editor | tạo và quản lý cụm, job | | roles/dataproc.admin | + quản lý IAM của tài nguyên Dataproc | | roles/dataproc.worker | SERVICE ACCOUNT của VM trong cụm | | Bẫy | worker không phải vai trò cho người dùng |

Từ khoá nhận diện:

"quản lý cụm và job Dataproc, không đụng gì khác" → dataproc.editor "service account của VM trong cụm" → dataproc.worker "toàn quyền VM" → compute.admin — quá rộng "Project Editor cho nhanh" → luôn sai trong câu hỏi quyền tối thiểu "gắn service account cho cụm" → iam.serviceAccountUser

Hai bộ quyền mà cụm Dataproc cần Bộ
Quyền của NGƯỜI tạo cụm dataproc.editor + iam.serviceAccountUser
Quyền của SERVICE ACCOUNT cụm chạy dưới dataproc.worker + quyền trên dữ liệu
Ví dụ quyền dữ liệu storage.objectViewer, bigquery.dataEditor
Bẫy thường gặp cấp đủ cho người, quên cấp cho service account của cụm
Triệu chứng cụm tạo được nhưng job thất bại vì thiếu quyền đọc dữ liệu
Vì sao không nên dùng service account mặc định Nội dung
Compute Engine default SA có roles/editor
Nghĩa là job Spark chạy với quyền sửa gần như mọi thứ
Nên tạo service account riêng cho cụm
Cấp dataproc.worker + đúng quyền dữ liệu cần
Chặn mặc định Organization Policy automaticIamGrantsForDefaultServiceAccounts
Nguyên tắc chọn vai trò trong câu hỏi thi Nguyên tắc
Ưu tiên vai trò ĐỊNH SẴN của chính dịch vụ dataproc.*, bigquery.*, storage.*
Tránh vai trò cơ bản Owner, Editor, Viewer
Tránh vai trò của dịch vụ KHÁC compute.admin cho Dataproc
Chú ý PHẠM VI project, dataset, bucket, hay tài nguyên đơn lẻ
Nhận diện vai trò dành cho MÁY *.worker, *.agent
Rà soát quyền định kỳ Công cụ
IAM Recommender gợi ý hạ vai trò không dùng tới
Policy Analyzer ai có quyền gì ở đâu
Cloud Asset Inventory ảnh chụp toàn bộ
Audit log ai thực sự làm gì
Nhịp độ mỗi quý và khi có thay đổi nhân sự

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Người này có vai trò gì | gcloud projects get-iam-policy <id> | | Vai trò gồm permission nào | gcloud iam roles describe roles/dataproc.editor | | Vì sao tạo cụm thất bại | Policy Troubleshooter — thường thiếu serviceAccountUser |

Và một lỗi cấu hình gần như chắc chắn sẽ gặp trong lần tạo cụm đầu tiên: thiếu roles/iam.serviceAccountUser. Kỹ sư có đủ quyền Dataproc nhưng vẫn không tạo được cụm, và thông báo lỗi nói về service account chứ không nói về Dataproc — nên rất dễ dẫn người ta đi cấp thêm quyền Dataproc mà mãi không hết lỗi.

Câu 98 Data Preparation and Ingestion

A team is building an analytical data pipeline that processes terabytes of structured data. The final output will be stored in Cloud Storage and queried frequently by BigQuery.

To optimize query performance and minimize the amount of data scanned by BigQuery, which data format should they choose for the output files?

  1. A JSON
  2. B Apache Parquet
  3. C CSV
  4. D XML
Xem giải thích

Đáp án

B — Apache Parquet.

Vì sao đúng

Đề nêu hai mục tiêu: tối ưu hiệu năng truy vấn và giảm tối đa lượng dữ liệu BigQuery phải QUÉT. Định dạng lưu theo CỘT là cách trực tiếp nhất để đạt cả hai.

⚠ Điểm mấu chốt — lưu theo cột nghĩa là đọc ít hơn:

Bảng có 50 cột, truy vấn cần 3 cột
        ↓
    LƯU THEO DÒNG (CSV, JSON, Avro)
        ↓
    → phải đọc CẢ 50 cột của mọi dòng
      rồi mới bỏ đi 47 cột

    LƯU THEO CỘT (Parquet)
        ↓
    → chỉ đọc ĐÚNG 3 cột
        ↓
    ⚠ BigQuery tính tiền theo BYTE QUÉT
    → đọc ít hơn = RẺ HƠN và NHANH HƠN

⚠ Parquet còn có hai cơ chế cắt dữ liệu nữa:

ROW GROUP + THỐNG KÊ min/max
        ↓
    Mỗi row group ghi sẵn min/max của từng cột
        ↓
    WHERE gia > 1000000
        ↓
    → bỏ qua HẲN row group có max < 1000000
    → gọi là PREDICATE PUSHDOWN

NÉN THEO CỘT
        ↓
    Cùng một cột = cùng kiểu, giá trị lặp nhiều
        ↓
    → mã hoá từ điển, run-length rất hiệu quả
    → tệp nhỏ hơn nhiều lần so với CSV/JSON

⚠ So bốn định dạng cho đúng bài toán này:

PARQUET  → cột, nén tốt, pushdown   ← tối ưu nhất
ORC      → cũng theo cột, tương đương
AVRO     → theo DÒNG, tốt cho NẠP và truyền tin,
           kém hơn cho quét chọn lọc
JSON     → văn bản, cồng kềnh, phân tích chậm
CSV      → tệ nhất: không kiểu, không nén,
           không pushdown
XML      → còn cồng kềnh hơn JSON

Xem thêm câu #12950 (lô 134): khoá Avro vì đề ở đó mô tả theo DÒNG, lược đồ nhúng, tiến hoá lược đồ. Và #12960 (lô 134): khoá JSON vì mô tả {} lồng nhau. Ba câu, ba khoá, phân biệt bằng chính đặc điểm được mô tả — hoàn toàn nhất quán.

Vì sao các phương án khác sai

  • A (JSON) — đây là phương án gần nhất trong nhóm còn lại vì giữ được cấu trúc lồng nhau, nhưng nó là văn bản, lưu theo dòng, cồng kềnh (lặp tên khoá mọi bản ghi) và không có predicate pushdown.

  • C (CSV) — không có kiểu dữ liệu, nén kém, không pushdown; định dạng tệ nhất cho phân tích quy mô lớn.

  • D (XML) — cồng kềnh hơn cả JSON, và BigQuery không hỗ trợ nạp trực tiếp.

Ghi nhớ

⚠ Định dạng theo mục đích — bảng phải thuộc: | Mục đích | Định dạng | |---|---| | PHÂN TÍCH, đọc chọn lọc cột | Parquet, ORC | | NẠP dữ liệu, truyền tin, tiến hoá lược đồ | Avro | | Trao đổi với API, dữ liệu lồng linh hoạt | JSON | | Trao đổi đơn giản, phổ biến | CSV | | Bảng có ACID trên data lake | Iceberg, Delta, Hudi |

Từ khoá nhận diện:

"BigQuery truy vấn tệp trong GCS, giảm byte quét" → Parquet "theo dòng, lược đồ nhúng, tiến hoá" → Avro "{} lồng nhau, đọc được bằng mắt" → JSON "mở bằng Excel" → CSV "nạp nhanh nhất vào BigQuery" → Avro hoặc Parquet

Ba cơ chế giúp Parquet quét ít Cơ chế
Column pruning chỉ đọc cột cần
Predicate pushdown bỏ qua row group nhờ thống kê min/max
Nén theo cột từ điển, run-length, delta
Kết quả quét ít hơn CSV nhiều lần
Với BigQuery external/BigLake table tiết kiệm trực tiếp thành tiền
Thiết kế tệp Parquet cho tốt Thói quen
Kích thước tệp 128 MB – 1 GB tránh hàng vạn tệp nhỏ
Row group vài trăm MB cân bằng giữa pushdown và chi phí
SẮP XẾP theo cột hay lọc thống kê min/max mới hiệu quả
Phân vùng theo thư mục nam=2026/thang=09/ — Hive partitioning
Nén Snappy hoặc ZSTD cân bằng tốc độ và tỉ lệ nén
Vấn đề "quá nhiều tệp nhỏ" Nội dung
Triệu chứng truy vấn chậm bất thường dù dữ liệu không lớn
Nguyên nhân chi phí liệt kê và mở tệp lớn hơn chi phí đọc
Khắc phục gộp tệp định kỳ (compaction)
Với BigLake bật metadata caching
Phòng ngừa ngưỡng dung lượng khi ghi, không ghi theo micro-batch quá nhỏ
Nếu dữ liệu truy vấn RẤT thường xuyên Cân nhắc
NẠP hẳn vào bảng BigQuery hiệu năng tốt nhất
BigLake table trên Parquet tại chỗ, có bảo mật chi tiết
External table thường đơn giản nhất, ít tính năng nhất
So sánh bảng quản lý > BigLake > external về hiệu năng
Đề này giữ ở GCS nhưng truy vấn nhiều → Parquet là bắt buộc

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Truy vấn quét bao nhiêu | --dry_run, và total_bytes_billed | | Tệp có quá nhỏ không | gcloud storage ls -l xem phân bố kích thước | | Lược đồ Parquet thế nào | parquet-tools schema, hoặc bq show trên external table |

Và một chi tiết ảnh hưởng tới hiệu năng nhiều hơn người ta tưởng: sắp xếp dữ liệu theo cột hay lọc trước khi ghi Parquet. Thống kê min/max của mỗi row group chỉ giúp bỏ qua dữ liệu khi các giá trị gần nhau nằm cùng chỗ — với dữ liệu ghi theo thứ tự ngẫu nhiên, mọi row group đều chứa đủ dải giá trị, và predicate pushdown gần như mất tác dụng.

Câu 99 Data Management

You are building an application on Compute Engine that needs to read data from a Cloud Storage bucket. You want to follow Google's recommended best practice for authenticating the application to the Cloud Storage API securely, without managing and distributing static credential files.

What should you do?

  1. A Assign the required IAM roles directly to the Compute Engine VM's service account.
  2. B Store a service account key in Cloud Storage and have the application download it on startup.
  3. C Create a service account, download its JSON key, and embed it in the application's source code.
  4. D Allow unauthenticated access to the Cloud Storage bucket.
Xem giải thích

Đáp án

A — Gán các vai trò IAM cần thiết TRỰC TIẾP cho service account của VM Compute Engine.

Vì sao đúng

Đây là thực hành được Google khuyến nghị: VM có sẵn một danh tính, và ứng dụng lấy token qua metadata server — không cần tệp khoá nào.

⚠ Điểm mấu chốt — token đến từ metadata server, không từ tệp:

VM chạy dưới một SERVICE ACCOUNT
        ↓
    Ứng dụng gọi thư viện client
    (không cấu hình gì thêm)
        ↓
    Thư viện tự hỏi METADATA SERVER
      metadata.google.internal
        ↓
    Nhận ACCESS TOKEN ngắn hạn
        ↓
    ⚠ Token TỰ HẾT HẠN và TỰ LÀM MỚI
    ⚠ KHÔNG có tệp khoá nào trên đĩa
    ⚠ KHÔNG có gì để rò rỉ

⚠ Application Default Credentials — vì sao mã không phải đổi:

Thư viện client tìm thông tin xác thực
theo thứ tự:
    1. GOOGLE_APPLICATION_CREDENTIALS
    2. Thông tin của gcloud (máy dev)
    3. METADATA SERVER (trên GCP)   ← ở đây
        ↓
    → cùng một đoạn mã chạy được
      trên máy dev lẫn trên VM
    → không có nhánh if nào cho xác thực

⚠ Vì sao khoá JSON là thứ nên tránh:

Khoá service account dạng JSON
        ↓
    ⚠ KHÔNG TỰ HẾT HẠN
    ⚠ Dễ lọt vào Git, ảnh container, log
    ⚠ Sao chép được, không truy vết được
    ⚠ Rò rỉ = kẻ khác dùng vô thời hạn
        ↓
    Nhúng khoá vào MÃ NGUỒN là tệ nhất
    → khoá đi theo mọi bản sao kho mã
        ↓
    Organization Policy có ràng buộc
      disableServiceAccountKeyCreation
    để CHẶN HẲN việc tạo khoá

Xem thêm câu #12568 (lô 133) về gắn service account cho VM, và #12975 (lô 134) về cấp quyền tối thiểu cho service account. Ba câu mô tả ba phần của cùng một thực hành.

Vì sao các phương án khác sai

  • B (lưu khoá trong Cloud Storage rồi tải về lúc khởi động) — đây là phương án gần nhất vì ít tệ hơn việc nhúng vào mã, nhưng nó vẫn tạo ra một tệp khoá tồn tại lâu dài, và còn thêm bài toán "ai được đọc bucket chứa khoá". Hoàn toàn không cần thiết khi VM đã có danh tính.

  • C (nhúng khoá JSON vào mã nguồn) — tệ nhất: khoá vào Git, vào mọi bản sao, vào ảnh container.

  • D (mở quyền truy cập công khai cho bucket) — lỗ hổng bảo mật nghiêm trọng; ai trên Internet cũng đọc được.

Ghi nhớ

⚠ Xác thực trên Google Cloud — thứ tự ưu tiên: | Môi trường | Cách xác thực | |---|---| | Chạy TRÊN Google Cloud | service account gắn sẵn + metadata server | | Chạy ngoài GCP (AWS, on-prem, CI) | Workload Identity Federation | | Trong GKE | Workload Identity cho pod | | Máy dev cá nhân | gcloud auth application-default login | | Khoá JSON | PHƯƠNG ÁN CUỐI CÙNG, nên tránh hẳn |

Từ khoá nhận diện:

"ứng dụng trên VM gọi API Google" → service account gắn cho VM "ứng dụng chạy ngoài GCP" → Workload Identity Federation "pod GKE gọi API Google" → Workload Identity "tải khoá JSON về" → gần như luôn là phương án SAI "mở công khai cho tiện" → luôn sai

Workload Identity Federation — thay thế khoá JSON Nội dung
Việc cho phép danh tính NGOÀI GCP mạo danh service account
Nguồn hỗ trợ AWS, Azure, GitHub Actions, OIDC bất kỳ
Lợi ích KHÔNG có khoá dài hạn nào
Dùng cho CI/CD, ứng dụng đa đám mây
Khuyến nghị thay thế mọi khoá JSON còn lại
Scope ↔ IAM trên VM — bẫy kinh điển Nội dung
Scope lớp CŨ, giới hạn ở mức VM
IAM role lớp quyết định quyền thật
Quyền hiệu lực GIAO của hai lớp
Khuyến nghị --scopes=cloud-platform rồi siết bằng IAM
Triệu chứng khi sai 403 dù IAM đã đủ — vì scope hẹp
Thực hành tốt với service account của VM Thói quen
KHÔNG dùng Compute Engine default SA nó mang roles/editor
Mỗi ứng dụng một service account riêng
Cấp vai trò hẹp nhất, ở phạm vi hẹp nhất bucket, không phải project
--scopes=cloud-platform rồi siết bằng IAM
Chặn tạo khoá Organization Policy
Rà soát IAM Recommender
Nếu buộc phải dùng khoá JSON Biện pháp
Lưu trong Secret Manager, không trong Git
Đặt hạn xoay khoá và thực sự xoay
Giới hạn quyền tối đa khoá lộ thì thiệt hại nhỏ
Theo dõi việc sử dụng audit log
Có kế hoạch chuyển sang WIF đây chỉ là giải pháp tạm

Ba việc kiểm chứng: | Việc | Cách | |---|---| | VM đang chạy dưới SA nào | gcloud compute instances describe <vm> --format="value(serviceAccounts)" | | Trong VM lấy được token không | curl -H "Metadata-Flavor: Google" metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | | Có khoá JSON nào còn tồn tại | gcloud iam service-accounts keys list --iam-account=<sa> |

Và một việc rà soát nên làm ngay trong tuần này ở bất kỳ project nào đã chạy được vài năm: liệt kê toàn bộ khoá service account đang tồn tại. Những khoá tạo ra để "thử cho nhanh" rồi bị quên là loại tài sản nguy hiểm nhất trong một dự án đám mây — chúng không hết hạn, không ai theo dõi, và thường vẫn còn đủ quyền để làm rất nhiều việc.

Câu 100 Data Preparation and Ingestion

A manufacturing company needs to collect daily production logs from an on-premises SFTP server and store them in a Cloud Storage bucket located in europe-west3 (Frankfurt). Due to data residency requirements, the data processing and transfer management must also occur within the European Union.

Which solution meets all these requirements?

  1. A Use Transfer Appliance to ship the data from the data center to Google Cloud.
  2. B Use gsutil on the on-premises server to run a nightly script to copy the files.
  3. C Use Storage Transfer Service with its default settings to transfer from the SFTP server.
  4. D Use Storage Transfer Service, configuring it to use a transfer agent pool located in an EU region.
Xem giải thích

Đáp án

D — Dùng Storage Transfer Service, cấu hình transfer agent pool đặt tại một Region của EU.

Vì sao đúng

Đề có hai ràng buộc chồng lên nhau: lấy dữ liệu từ SFTP tại chỗ (nên phải dùng agent), và cả việc XỬ LÝ lẫn QUẢN LÝ truyền tải cũng phải nằm trong EU.

⚠ Điểm mấu chốt — agent pool có VỊ TRÍ, và vị trí đó quan trọng:

Storage Transfer Service cho nguồn TẠI CHỖ
        ↓
    Cần AGENT chạy gần hệ thống nguồn
    (container Docker trên máy chủ của bạn)
        ↓
    Agent thuộc một AGENT POOL
        ↓
    ⚠ Agent pool có REGION
    → quyết định dữ liệu được ĐIỀU PHỐI
      và XỬ LÝ ở đâu
        ↓
    Đặt pool ở EU → toàn bộ luồng
    nằm trong EU

⚠ Vì sao "cấu hình mặc định" chưa đủ:

Storage Transfer Service mặc định
        ↓
    ⚠ Có thể dùng tài nguyên điều phối
      ngoài EU
        ↓
    → dữ liệu đích ở europe-west3 thì đúng,
      nhưng phần XỬ LÝ và QUẢN LÝ
      có thể vượt ranh giới
        ↓
    ⚠ Chính sách trong đề nói rõ
      cả hai phần đó cũng phải trong EU

⚠ Kiến trúc đầy đủ để tuân thủ:

Agent pool ở EU
    + Bucket đích ở europe-west3
    + Organization Policy gcp.resourceLocations
      giới hạn ở các Region EU/Đức
    + VPC Service Controls (nếu cần vành đai)
        ↓
    → dữ liệu và mọi thao tác quản lý
      đều nằm trong EU

Xem thêm câu #12933 (lô 134): cũng khoá Storage Transfer Service, nhưng nguồn là Amazon S3 nên không cần agent. Và #12964 (lô 134): chọn region cụ thể cho chủ quyền dữ liệu. Ba câu bổ sung nhau — nhất quán.

Vì sao các phương án khác sai

  • C (Storage Transfer Service với cấu hình mặc định) — đây là phương án gần nhất và đúng dịch vụ, nhưng nó không bảo đảm phần điều phối nằm trong EU — chính điều mà chính sách trong đề đòi hỏi.

  • B (chạy gsutil bằng script hằng đêm) — không phải dịch vụ được quản lý: không tự thử lại, không kiểm tra toàn vẹn, không báo cáo, phải tự vận hành.

  • A (Transfer Appliance) — thiết bị vật lý cho khối lượng rất lớn một lần; nhật ký sản xuất hằng ngày cần một luồng liên tục, không phải gửi ổ cứng qua bưu điện.

Ghi nhớ

⚠ Storage Transfer Service — hai chế độ nguồn: | Nguồn | Cần agent? | |---|---| | Amazon S3, Azure Blob, HTTP/HTTPS | KHÔNG — Google kéo trực tiếp | | Cloud Storage khác | KHÔNG | | Hệ thống tệp tại chỗ, SFTP/POSIX | CÓ — cần agent pool | | Agent chạy bằng | container Docker trên máy chủ của bạn | | Agent pool có REGION | quyết định nơi điều phối |

Từ khoá nhận diện:

"nguồn tại chỗ + ràng buộc vùng" → STS với agent pool đúng Region "S3 → GCS" → STS, không cần agent "hàng trăm TB, mạng kém" → Transfer Appliance "dữ liệu phải ở trong nước" → region cụ thể + Organization Policy "script gsutil hằng đêm" → không phải giải pháp được quản lý

Agent pool — điều cần nhớ Nội dung
Nhóm các agent làm việc cùng nhau
Có REGION ảnh hưởng nơi điều phối và tuân thủ
Nhiều agent trong một pool tăng thông lượng, chịu lỗi
Giới hạn băng thông đặt được để không nghẽn mạng văn phòng
Chạy agent docker run với thông tin xác thực service account
Theo dõi trạng thái agent trong console
Ba lớp bảo đảm chủ quyền dữ liệu Lớp
Chọn Region cụ thể cho mọi tài nguyên bucket, dataset, agent pool
Organization Policy gcp.resourceLocations CHẶN tạo tài nguyên ngoài vùng
VPC Service Controls vành đai chống dữ liệu ra ngoài
CMEK với key ring trong vùng nếu cần tự quản khoá
Assured Workloads gói tuân thủ có sẵn cho EU
Đừng quên các dịch vụ phụ trợ Dịch vụ
Cloud Logging log bucket cũng có Region
Cloud Monitoring dữ liệu chỉ số
Sao lưu --backup-location
Dịch vụ xử lý Dataflow, Dataproc, Cloud Run — đều phải khai Region
Rà soát Cloud Asset Inventory, lọc theo vị trí
STS — tính năng đáng dùng Tính năng
Chạy theo LỊCH đồng bộ hằng ngày
Chỉ chuyển tệp MỚI hoặc ĐÃ ĐỔI so theo thời gian sửa và checksum
Xoá ở nguồn sau khi chuyển tuỳ chọn
Lọc theo tiền tố chuyển một phần
Thông báo qua Pub/Sub tự động hoá bước tiếp theo
Báo cáo lỗi biết tệp nào không chuyển được

Ba việc kiểm chứng: | Việc | Cách | |---|---| | Agent pool ở Region nào | console → Storage Transfer → Agent pools | | Agent có đang chạy không | trạng thái agent, và docker ps trên máy chủ | | Tệp đã sang đủ chưa | so số tệp và dung lượng hai bên |

Và một chi tiết dễ bị bỏ qua khi lập kế hoạch tuân thủ: vị trí của agent pool là một quyết định về chủ quyền dữ liệu, không chỉ là một tuỳ chọn kỹ thuật. Bucket đích đặt đúng ở Frankfurt vẫn có thể không đủ nếu phần điều phối truyền tải diễn ra ở nơi khác — và đó chính là chi tiết phân biệt hai phương án gần giống nhau trong câu hỏi này.