SingleStore 2 — Kiến trúc cluster (Aggregator & Leaf)

15 thg 7, 2026 6 lượt xem
#sql
#distributed
#high-availability
#singlestore
#htap

SingleStore 2 — Kiến trúc cluster (Aggregator & Leaf)

Ở bài Tổng quan ta đã biết SingleStore (tiền thân là MemSQL) là một relational database phân tán, HTAP, tương thích giao thức MySQL. Câu hỏi đọng lại là: bằng cách nào một cluster nhiều máy lại trông như một database duy nhất trước mắt ứng dụng — bạn kết nối bằng một driver MySQL bình thường, gõ SELECT, và không cần biết dữ liệu nằm ở đâu?

Câu trả lời nằm ở kiến trúc shared-nothing hai tầng: một tầng Aggregator làm bộ não điều phối, và một tầng Leaf làm nơi chứa dữ liệu thật. Mọi thứ khác — sharding, HA, thực thi song song — đều mọc ra từ sự phân vai này. Hiểu được hai loại node và luồng một query đi qua chúng là hiểu bộ khung của toàn bộ SingleStore.

Bài viết xây "mô hình tinh thần" trước, rồi mới đi vào HA. Toàn bộ SQL dùng ví dụ ngân hàng (transactions, accounts) và ghi (minh hoạ) vì cú pháp cluster của SingleStore cần chạy trên chính cluster đó.

Shared-nothing: hai loại node, một database

Shared-nothing nghĩa là mỗi node có CPU, RAM và đĩa riêng, không chia sẻ trạng thái vật lý với node khác; chúng chỉ trao đổi qua mạng. Đây là nền tảng để scale ngang (thêm máy = thêm năng lực) thay vì scale dọc (mua máy to hơn). SingleStore chia các node thành đúng hai vai:

Loại nodeVai tròChứa dữ liệu người dùng?
Master AggregatorBộ não duy nhất: giữ metadata cluster (danh mục node, bảng, partition), điều phối DDL, giám sát sức khoẻ, quyết định failoverKhông (chỉ metadata)
Child AggregatorAggregator phụ: nhận kết nối client, phân tích & route query, gộp kết quả — để scale số kết nối / thông lượng queryKhông
Leaf nodeNơi chứa dữ liệu thật, được chia thành các partition; thực thi phần query được đẩy xuống

Điểm cốt lõi cần nhớ:

  • Aggregator là tầng điều phối, không lưu dữ liệu người dùng. Client chỉ nói chuyện với aggregator, không bao giờ kết nối thẳng vào leaf.
  • Leaf là tầng lưu trữ + tính toán cục bộ. Dữ liệu bảng nằm ở đây, trải đều thành partition.
  • đúng một Master Aggregator tại một thời điểm (là quyền lực metadata); Child Aggregator có thể có nhiều để chia tải kết nối và bước gộp (aggregation) khi số client hoặc số query lớn.

Ký hiệu: P0(m) = partition 0 bản master, P0(r) = partition 0 bản replica. Lưu ý master và replica của cùng một partition luôn nằm trên hai leaf khác nhau — nền tảng của HA, bàn ở cuối bài.

Partition: đơn vị chia dữ liệu trên leaf

Khi tạo một bảng phân tán, SingleStore không đặt cả bảng lên một leaf. Nó băm dữ liệu thành nhiều partition theo SHARD KEY (cơ chế băm chi tiết ở bài sharding) rồi rải các partition đó lên các leaf. Mỗi leaf giữ một số partition; mỗi partition là một mảnh dữ liệu độc lập với storage riêng.

Số partition được cố định lúc khởi tạo database (thường là bội số của số core/leaf để song song hoá tốt). Ứng dụng không thấy partition — nó chỉ thấy một bảng transactions duy nhất; chính aggregator dịch câu query người dùng thành công việc trên từng partition.

-- (minh hoạ, chạy trên SingleStore)
-- Bảng phân tán: dữ liệu băm theo SHARD KEY và rải partition lên các leaf
CREATE TABLE transactions (
    txn_id      BIGINT       NOT NULL,
    account_id  BIGINT       NOT NULL,
    amount      DECIMAL(18,2) NOT NULL,
    txn_time    DATETIME     NOT NULL,
    SHARD KEY (account_id),                 -- quyết định partition
    SORT KEY (txn_time),
    KEY (account_id) USING CLUSTERED COLUMNSTORE
);

-- Xem partition đang nằm ở leaf nào (management view có thật)
SELECT * FROM information_schema.DISTRIBUTED_PARTITIONS;

Cách partition được lưu bên trong mỗi leaf — rowstore trong RAM hay columnstore trên đĩa — là chủ đề của bài Universal Storage. Ở tầng kiến trúc này chỉ cần nắm: leaf = tập hợp partition, partition = mảnh dữ liệu độc lập.

Luồng một query: nhận → pushdown → gather

Đây là cơ chế biến một cluster nhiều máy thành "một database". Xét câu tổng hợp quen thuộc trong ngân hàng:

-- (minh hoạ)
SELECT account_id, SUM(amount) AS total
FROM transactions
WHERE txn_time >= '2026-07-01'
GROUP BY account_id;

Vòng đời của nó qua cluster:

  1. Nhận & phân tích. Client gửi query tới một aggregator (Master hoặc Child). Aggregator parse, tối ưu, và lập kế hoạch phân tán — biết bảng có bao nhiêu partition và chúng nằm ở leaf nào (nhờ metadata).
  2. Pushdown xuống leaf. Aggregator không kéo dữ liệu thô về. Nó đẩy phần công việc làm được cục bộ — lọc WHERE, và tổng hợp một phần (partial SUM ... GROUP BY) — xuống mọi leaf giữ partition liên quan, chạy song song (MPP). Đây là query pushdown: mang phép tính đến gần dữ liệu, thay vì mang dữ liệu đến phép tính.
  3. Leaf tính cục bộ. Mỗi leaf xử lý các partition của mình, trả về kết quả trung gian đã co nhỏ (partial aggregate), không phải hàng triệu dòng thô.
  4. Gather & gộp. Aggregator thu (gather) các kết quả trung gian rồi gộp (merge/final aggregate) thành kết quả cuối, và trả về cho client.

Vì bước tốn kém (quét, lọc, tổng hợp) chạy song song sát dữ liệu và chỉ truyền phần đã co nhỏ qua mạng, cluster trả lời nhanh dù dữ liệu nằm rải rác. Cách một query được biên dịch và thực thi bên trong leaf (SingleStore compile query ra mã máy + MPP) là nội dung của bài query execution.

Không phải query nào cũng pushdown gọn như vậy. Một số phép — nhất là join giữa hai bảng phân tán không cùng shard key — buộc dữ liệu phải di chuyển giữa các leaf (reshuffle) hoặc nhân bản (broadcast) trước khi tính. Tránh những cú di chuyển đắt này chính là nghệ thuật chọn shard key, xem bài sharding & distribution.

High Availability: master, replica và failover

Rải dữ liệu lên nhiều leaf làm nảy sinh rủi ro hiển nhiên: một leaf chết thì mất luôn các partition trên đó. SingleStore chống lại bằng redundancy ở cấp partition.

Khi database chạy ở redundancy level 2 (mức có HA), mỗi partition tồn tại hai bản:

  • Partition master — bản đang phục vụ đọc/ghi.
  • Partition replica — bản dự phòng trên một leaf khác, liên tục nhận thay đổi từ master (nhân bản log).

Ràng buộc bố trí: master và replica của cùng một partition không bao giờ ở chung một leaf. SingleStore còn dùng khái niệm availability group (nhóm bản sao đối xứng) để đảm bảo có thể mất trọn một nửa số leaf mà vẫn còn đủ bản của mọi partition.

Khi một leaf gặp sự cố, Master Aggregator phát hiện (qua giám sát/heartbeat) và kích hoạt failover: các partition replica trên những leaf còn sống được thăng cấp thành master, tiếp tục phục vụ. Cluster tự cân bằng lại, và khi leaf hỏng quay lại (hoặc được thay), dữ liệu được đồng bộ lại để khôi phục mức dự phòng.

Cần phân biệt hai vai "master" để khỏi nhầm:

  • Master Aggregator — node điều phối/metadata cấp cluster (chỉ có một).
  • Partition master — bản đang-hoạt-động của một partition trên leaf.

Bản thân Master Aggregator cũng là điểm chết đơn (single point) cho DDL/metadata; môi trường production thường cấu hình một aggregator dự phòng có thể được thăng làm Master Aggregator khi cần. Chi tiết về nhân bản đồng bộ/bất đồng bộ, transaction log, snapshot và DR nằm ở bài transactions, HA & DR.

Bức tranh gộp: vì sao kiến trúc này hợp HTAP

Ghép các mảnh lại: aggregator che giấu sự phân tán và scale được số kết nối bằng child aggregator; leaf chứa partition và chạy tính toán song song sát dữ liệu; pushdown + gather giữ lưu lượng mạng nhỏ; redundancy master/replica cho HA. Kết quả là một hệ vừa nuốt được ghi giao dịch (OLTP) vừa quét tổng hợp (OLAP) trên cùng cluster, cùng dữ liệu — chính là lời hứa HTAP. Hai tầng lưu trữ (rowstore/columnstore) bên trong leaf là mảnh cuối cần để hiểu vì sao cả hai loại tải cùng sống được: xem Universal Storage.

Use case thực tế

Bối cảnh (số liệu minh hoạ). NCB dựng một cluster SingleStore phục vụ vừa ghi giao dịch thẻ thời gian thực vừa báo cáo tức thời cho đội chống gian lận. Cấu hình: 1 Master Aggregator + 2 Child Aggregator + 6 Leaf, redundancy level 2. Bảng card_txnSHARD KEY (card_id), chia 48 partition rải đều 6 leaf (8 partition master/leaf, cộng các replica).

Ghi giao dịch (OLTP). Cổng thanh toán mở kết nối tới các Child Aggregator; mỗi INSERT được route thẳng tới đúng partition (theo card_id) trên leaf tương ứng, ghi độ trễ thấp. Nhờ 2 child aggregator chia tải, cluster giữ được hàng chục nghìn kết nối đồng thời mà Master Aggregator không thành nút cổ chai.

-- (minh hoạ) báo cáo gian lận: tổng chi tiêu 24h theo thẻ nghi ngờ
SELECT card_id, COUNT(*) AS n, SUM(amount) AS total
FROM card_txn
WHERE txn_time >= NOW() - INTERVAL 24 HOUR
  AND card_id IN ( /* danh sách thẻ nghi ngờ */ )
GROUP BY card_id;

Đọc phân tích (OLAP). Câu trên được aggregator pushdown xuống cả 6 leaf; mỗi leaf lọc + gộp cục bộ 8 partition song song, chỉ trả partial aggregate; aggregator gộp lại. Quét vài chục triệu dòng phân tán trả về trong ~0,2 giây (minh hoạ) — nhanh vì tính song song sát dữ liệu và mạng chỉ truyền phần đã co.

Sự cố leaf. Trong một đợt bảo trì, Leaf 4 mất kết nối. Master Aggregator phát hiện, thăng các partition replica của Leaf 4 (nằm trên Leaf 1 và Leaf 5) thành master; ứng dụng chỉ thấy một nhịp trễ ngắn, không mất dữ liệu, không ngừng phục vụ. Khi Leaf 4 trở lại, cluster đồng bộ lại để khôi phục redundancy 2.

Ghi nhớ

  • SingleStore theo kiến trúc shared-nothing hai tầng: Aggregator (điều phối) và Leaf (chứa dữ liệu). Client chỉ nói chuyện với aggregator, không kết nối thẳng vào leaf.
  • Master Aggregator (đúng một) giữ metadata cluster, điều phối DDL và giám sát/failover. Child Aggregator (nhiều được) nhận kết nối, route query và gộp kết quả — để scale số kết nối và thông lượng.
  • Leaf chứa dữ liệu thật, chia thành partition theo SHARD KEY và rải trên nhiều leaf; ứng dụng chỉ thấy một bảng duy nhất.
  • Luồng query: aggregator nhận → pushdown phần lọc/gộp một phần xuống leaf (song song, MPP) → leaf tính cục bộ trả partial → aggregator gather + gộp thành kết quả cuối. Mạng chỉ truyền phần đã co nhỏ.
  • Join giữa bảng không cùng shard key có thể gây reshuffle/broadcast đắt — chọn shard key khéo (xem bài sharding).
  • High Availability: ở redundancy level 2, mỗi partition có master + replica trên hai leaf khác nhau; leaf chết thì replica failover lên master, không mất dữ liệu. Đừng lẫn Master Aggregator (metadata cluster) với partition master (bản hoạt động của partition).

Nguồn tham khảo

  • SingleStore Documentation — Cluster Architecture / How Distributed SQL Works (Master Aggregator, Child Aggregator, Leaf node, partition, query pushdown & gather)
  • SingleStore Documentation — "Managing High Availability" (redundancy level, partition master/replica, availability group, failover)
  • SingleStore Documentation — "Distributed SQL" / SHARD KEY (cách partition được rải trên leaf, reshuffle vs broadcast)
  • SingleStore Documentation — information_schema management views (DISTRIBUTED_PARTITIONS, MV_*) để quan sát bố trí partition
  • SingleStore Engineering Blog — bài giới thiệu kiến trúc phân tán MemSQL/SingleStore (aggregator–leaf, MPP)
  • MySQL Documentation (dev.mysql.com) — giao thức/kết nối client, cho phần SingleStore tương thích wire-protocol MySQL

Bài viết liên quan

Điểm khác biệt lớn nhất của SingleStore: nó BIÊN DỊCH truy vấn ra mã máy (code generation) rồi chạy song song MPP trên leaf, thay vì diễn giải từng dòng. Bài dựng luồng SQL → tối ưu → sinh mã → plan biên dịch, giải thích plan cache tái dùng (biên dịch 1 lần), query pushdown xuống leaf và aggregator gộp; cách đọc EXPLAIN/PROFILE (thời gian, rows, bộ nhớ, network/reshuffle) và SHOW PLANCACHE để nhận diện reshuffle/broadcast, tối ưu truy vấn.

15 thg 7, 2026 5

Khoá chính/ngoại/tổng hợp, ràng buộc (NOT NULL, UNIQUE, CHECK, FK) và cách mô hình hoá quan hệ 1:1, 1:n, n:n cho hệ khách hàng — tài khoản — giao dịch. Đi qua chuẩn hoá 1NF/2NF/3NF bằng ví dụ trước/sau cụ thể, rồi bàn khi nào nên cố tình phi chuẩn hoá để đọc nhanh — giúp thiết kế lược đồ đúng ngay từ đầu.

13 thg 7, 2026 5

SingleStore (tiền thân MemSQL) là database quan hệ phân tán HTAP, tương thích giao thức MySQL, gộp OLTP và OLAP trong một hệ thống. Bài mở màn dựng mô hình tinh thần về HTAP, giải thích vấn đề nó giải quyết (tránh ETL sang warehouse riêng), chỉ rõ khi nào NÊN và KHÔNG NÊN dùng, định vị so với PostgreSQL, ClickHouse, BigQuery, TiDB/CockroachDB, và vẽ bản đồ toàn series 10 bài.

15 thg 7, 2026 5
SQL & Databases
Nổi bật

Index (B-Tree) giúp database tìm dữ liệu theo O(log n) thay vì quét tuần tự O(n). Bài giải thích cấu trúc B-Tree, các loại index (hash, composite, partial, covering), khi nào optimizer bỏ index, cách đọc EXPLAIN/EXPLAIN ANALYZE (seq vs index scan, cost, rows, kiểu join), selectivity, leftmost prefix và các mẫu tối ưu: SARGable, keyset pagination, diệt N+1.

13 thg 7, 2026 5

Cảm nhận của bạn

Bình luận

Bạn cần để viết bình luận.

Chưa có bình luận. Hãy là người đầu tiên chia sẻ!