← Chương trước: Phần 4: MariaDB vs. MySQL | Mục lục Series | Chương tiếp theo: Phần 6: Apache Kafka vs. NATS JetStream →

Sharded MySQL (Vitess) vs. TiDB NewSQL: ACID Phân Tán & Thuế Độ Trễ Mạng


Answer-first: Sharded MySQL (Vitess) áp đảo về độ trễ ghi (sub-2ms) và cô lập lỗi (Blast Radius) cho hệ thống E-commerce / SaaS có Sharding Key sạch. Ngược lại, TiDB NewSQL là giải pháp cứu cánh cho schema phức tạp nhờ cơ chế tự động chia tách Region 96MB, chấp nhận mức sàn độ trễ ghi 8–15ms do Percolator 2PC.


🇬🇧 Read the English version of this article on tanhdev.com

Để xây dựng kiến trúc backend đồng bộ và tối ưu hóa hệ thống microservices chịu tải cao, bạn có thể tham khảo thêm các bài phân tích chuyên sâu tại tanhdev.com.


1. Bối Cảnh: Ngưỡng Vỡ 10TB & Cuộc Chạm Trán Giữa 2 Trường Phái

Khi một hệ thống cơ sở dữ liệu quan hệ (RDBMS) chạm ngưỡng 10TB dữ liệu và 50,000+ Write QPS, các giải pháp truyền thống như nâng cấp cấu hình máy chủ (Vertical Scaling) hoặc bổ sung Read Replicas chính thức rơi vào bế tắc:

  • Giới hạn phần cứng: Máy chủ lớn nhất trên AWS/GCP (ví dụ r6i.32xlarge với 1TB RAM) có chi phí đắt đỏ theo hàm mũ ($> $8,000/\text{tháng}$) nhưng vẫn bị nghẽn I/O bus và lock contention trên một Primary duy nhất.
  • Ác mộng Replication Lag: Khi master gánh 30,000 write ops/sec, luồng single-threaded SQL applier trên replica không thể bắt kịp, gây trễ dữ liệu từ vài chục giây đến hàng chục phút.
  • Rủi ro Dừng Hệ Thống (Maintenance Window): Câu lệnh ALTER TABLE ADD INDEX trên bảng 5 tỷ dòng khiến bảng bị khóa nhiều giờ, rủi ro làm sập toàn bộ dịch vụ.

Tại thời điểm này, các kỹ sư trưởng và kiến trúc sư hệ thống bắt buộc phải lựa chọn giữa hai trường phái mở rộng ngang (Horizontal Scale-Out):

flowchart TD
    subgraph ClientLayer ["Microservices Client Layer (Golang / Dapr / gRPC)"]
        Client["Application Workload (100k writes/sec)"]
    end

    subgraph ShardedTrack ["Trường Phái 1: Sharded MySQL (Vitess Architecture)"]
        direction TB
        VTGate["VTGate Stateless L7 Proxy (VSchema Router)"]
        Shard1["Shard 1 (-80): Primary MySQL InnoDB (Sub-2ms Local ACID)"]
        Shard2["Shard 2 (80-): Primary MySQL InnoDB (Sub-2ms Local ACID)"]
        VRep["VReplication Engine (Online Zero-Downtime Split/Merge)"]
    end

    subgraph NewSQLTrack ["Trường Phái 2: TiDB NewSQL Architecture"]
        direction TB
        TiDB_SQL["TiDB Stateless SQL Nodes (Parser/Cost Optimizer)"]
        PD["Placement Driver (PD Raft Cluster: TSO Allocator & Region Scheduler)"]
        TiKV1["TiKV Node 1 (Raft Group: 96MB Regions, RocksDB LSM)"]
        TiKV2["TiKV Node 2 (Raft Group: 96MB Regions, RocksDB LSM)"]
        TiFlash["TiFlash Columnar Store (Real-time Raft Learner OLAP)"]
    end

    Client -->|"Query with Shard Key (tenant_123)"| VTGate
    VTGate -->|"Direct Routing (Single RTT)"| Shard1
    
    Client -->|"Standard MySQL Protocol"| TiDB_SQL
    TiDB_SQL <-->|"Fetch Monotonic Timestamp (TSO)"| PD
    TiDB_SQL <-->|"Percolator 2PC (Prewrite + Commit + Raft Heartbeats)"| TiKV1
    TiDB_SQL <-->|"Percolator 2PC"| TiKV2
    TiKV1 -.->|"Raft Learner Replication"| TiFlash
  1. Trường phái 1: Sharded MySQL với Proxy Vitess: Giữ nguyên các node MySQL tiêu chuẩn ở tầng dưới, đưa logic định tuyến và phân mảnh lên tầng proxy L7 (VTGate) kết hợp sơ đồ VSchema khai báo.
  2. Trường phái 2: Distributed NewSQL (TiDB): Đập bỏ hoàn toàn kiến trúc lưu trữ MySQL cũ, xây dựng hệ thống cơ sở dữ liệu phân tán gốc (Distributed-Native) với tầng SQL phi trạng thái (TiDB), cụm điều phối Placement Driver (PD), và động cơ lưu trữ đồng thuận Raft (TiKV / RocksDB).

2. So Sánh Kiến Trúc Giao Dịch: Local ACID vs. Google Percolator 2PC

Sự đánh đổi lớn nhất quyết định độ trễ của hệ thống nằm ở Giao thức Thực thi Giao dịch (Transaction Protocol Overhead).

[Vitess Single-Shard Write Flow: ~1.2ms P99]
App ──> VTGate ──> Shard 1 MySQL InnoDB (Local Redo Log Write + Flush) ──> App

[TiDB Percolator Write Flow: ~10.5ms P99]
App ──> TiDB Node ──(1) Get StartTS (Network RTT)──> PD Cluster
                  ──(2) Prewrite Lock (Network RTT)──> TiKV Raft Leader ──(Raft Log to Quorum)──> Follower
                  ──(3) Get CommitTS (Network RTT)──> PD Cluster
                  ──(4) Commit Primary Lock (Network RTT)──> TiKV Raft Leader ──> App

2.1. Sharded MySQL (Vitess): Sức Mạnh Local ACID Bỏ Qua 2PC

Khi ứng dụng gửi câu lệnh INSERT hoặc UPDATE có chứa Shard Key (ví dụ WHERE tenant_id = 'tenant_99'):

  • VTGate tính toán hàm băm MD5/Murmur3 của Shard Key và chuyển tiếp trực tiếp gói tin TCP tới đúng node MySQL Shard phụ trách.
  • MySQL Shard thực thi giao dịch hoàn toàn cục bộ (Local ACID Transaction), ghi Redo Log và Undo Log trên đĩa NVMe cục bộ.
  • Thời gian phản hồi: Chỉ mất 1 RTT mạng giữa App $\leftrightarrow$ VTGate $\leftrightarrow$ MySQL. Độ trễ ghi đạt mức cực hạn: $0.8\text{ms} - 2.0\text{ms}$.

2.2. TiDB NewSQL: Thuế Giao Dịch Phân Tán (Percolator 2PC Tax)

TiDB triển khai thuật toán Google Percolator 2-Phase Commit kết hợp với đồng thuận Multi-Raft:

  1. Bước 1 (Timestamp Oracle - TSO): Node TiDB phải gửi request qua mạng tới PD Cluster để xin một StartTS duy nhất tăng đơn điệu.
  2. Bước 2 (Prewrite Phase): TiDB chọn một khóa làm Primary Lock và các khóa còn lại làm Secondary Locks, gửi tới các TiKV Raft Leaders. TiKV Leader phải ghi log Raft và chờ đa số (Quorum) Followers xác nhận trước khi cấp lock.
  3. Bước 3 (Commit Timestamp): TiDB gửi request thứ 2 tới PD Cluster để lấy CommitTS.
  4. Bước 4 (Commit Phase): TiDB gửi lệnh ghi đè Primary Lock thành commit record trên TiKV Leader, tiếp tục qua chu trình Raft Quorum đồng thuận.
  • Hệ quả độ trễ: Ngay cả với câu lệnh sửa đổi 1 dòng dữ liệu đơn lẻ, TiDB bắt buộc phải trải qua ít nhất 4 đến 6 lượt truyền thông mạng (Network RTTs) giữa các tầng phân tán.
  • Mức sàn vật lý (Physical Floor): Độ trễ ghi của TiDB không thể ép xuống dưới $6\text{ms} - 15\text{ms}$, bất kể bạn trang bị phần cứng mạnh đến mức nào.

3. Cơ Chế Tái Phân Mảnh: VReplication vs. Dynamic Region 96MB Splitting

Khi dữ liệu trên một phân mảnh tăng trưởng vượt ngưỡng, cách thức hệ thống tự chia nhỏ dữ liệu quyết định chi phí vận hành (Operational Overhead).

[TiDB: Zero-Touch 96MB Dynamic Region Splitting]
[ Region 1: Range [0 - 1000) (96MB Full) ]
                    │ (Auto Split on Threshold)
[ Region 1A: [0 - 500) (48MB) ] <---> [ Region 1B: [500 - 1000) (48MB) ]
(PD tự động di chuyển Region 1B sang TiKV Node mới qua Raft Learner - Zero Downtime)

[Vitess: VReplication Declarative Online Sharding]
[ Shard -80 (5TB) ] ──(VReplication Stream)──> [ Shard -40 (2.5TB) ] & [ Shard 40-80 (2.5TB) ]
                    ▼ (Switch Traffic via VTGate: 2-second cutover)

3.1. TiDB: Tự Động Hóa Tuyệt Đối (Zero-Touch Elastic Auto-Resharding)

  • TiKV chia toàn bộ key-space thành các đoạn dải khóa liên tục kích thước chuẩn 96MB (gọi là Region).
  • Khi một Region phình to vượt quá 144MB, TiKV tự động cắt đôi thành 2 Regions 72MB.
  • Placement Driver (PD) liên tục thu thập nhịp tim (Heartbeats) từ toàn bộ cụm. Nếu phát hiện một node TiKV bị quá tải I/O hoặc dung lượng đĩa, PD tự động tạo một bản sao (Raft Learner) trên node TiKV mới, đồng bộ dữ liệu ngầm và chuyển quyền Raft Leader mà không cần bất kỳ sự can thiệp nào của con người.

3.2. Vitess: Quy Trình VReplication Khai Báo (Declarative Resharding Workflow)

Trong Vitess, việc chia một Shard lớn (ví dụ Shard -80 dung lượng 5TB) thành 2 Shard con (-4040-80) được thực hiện qua công cụ VReplication:

  1. Khởi tạo 2 cụm MySQL target mới.
  2. Chạy lệnh Reshard trong Vitess: VReplication đọc snapshot từ shard gốc và nạp sang 2 shard mới.
  3. VReplication tiếp tục tail binlog thời gian thực để bù đắp các giao dịch phát sinh.
  4. Khi replication lag tiệm cận 0, DBA kích hoạt SwitchTraffic: VTGate khóa luồng ghi trong $\approx 2$ giây để chuyển hướng traffic sang 2 shard mới.
  • Đánh giá: VReplication hoàn toàn zero-downtime, nhưng đòi hỏi đội ngũ kỹ sư phải chủ động lên kế hoạch và kích hoạt quy trình trước khi shard cũ bị đầy đĩa.

4. Phân Vùng Lỗi (Blast Radius) & Rủi Ro Sự Cố Toàn Cục

Khả năng cô lập sự cố (Fault Isolation) là tiêu chuẩn sống còn trong các hệ thống doanh nghiệp lớn:

[Vitess Blast Radius: Isolated Shard Failure]
Shard 1 (-40) ────> [CRASHED / CORRUPTED]  ──> Chỉ 25% User (Tenant A) bị gián đoạn
Shard 2 (40-80) ──> [RUNNING NORMALLY]    ──> 25% User (Tenant B) hoạt động 100%
Shard 3 (80-c0) ──> [RUNNING NORMALLY]    ──> 25% User (Tenant C) hoạt động 100%
Shard 4 (c0-)   ──> [RUNNING NORMALLY]    ──> 25% User (Tenant D) hoạt động 100%

[TiDB Blast Radius: Shared Cluster Dependencies]
PD Leader Latency Spike / Raft Storm ──> TOÀN BỘ CLUSTER BỊ STALL (100% Blast Radius)

5. FinOps & Chi Phí Hạ Tầng Phần Cứng (Infrastructure Footprint)

Chúng tôi thiết lập bài toán FinOps đo lường chi phí phần cứng tối thiểu để duy trì một cụm cơ sở dữ liệu đạt chuẩn High Availability (HA) trên môi trường AWS / Kubernetes:

Tiêu Chí FinOpsSharded MySQL (Vitess - 2 Shards)TiDB NewSQL Cluster (Tối Thiểu HA)Nhận Định FinOps
Số Lượng Nodes Tối Thiểu6 Nodes (2 VTGate + 2 Primary + 2 Replica)11 Nodes (3 PD + 3 TiDB + 5 TiKV)TiDB yêu cầu số lượng máy chủ tối thiểu gần gấp đôi.
RAM Tối Thiểu / Node Lưu Trữ16GB RAM (InnoDB Buffer Pool)64GB RAM (TiKV RocksDB Block Cache)RocksDB của TiKV tiêu tốn RAM rất lớn cho MemTables và Bloom Filters.
Hiện Tượng Compaction Spike❌ Không có (InnoDB B+ Tree flush đều đặn)⚠️ Thường xuyên (RocksDB Level Compaction)TiKV có thể bị spike 80% CPU khi chạy Major Compaction vào giờ cao điểm.
Chi Phí Điện Toán Đám Mây Ước Tính$1,800 / tháng$4,600 / thángVitess tiết kiệm hơn 60% chi phí hạ tầng ở quy mô dữ liệu dưới 20TB.

6. Dữ Liệu Benchmark Thực Chiến (10,000 Concurrent Connections)

Thực nghiệm đo lường trên cụm máy chủ chuyên dụng (32 vCPUs, 64GB RAM, NVMe SSDs) với kịch bản thanh toán E-commerce 10,000 kết nối đồng thời qua sysbench-tpcc:

Chỉ Số Đo LườngSharded MySQL (Vitess - 4 Shards)TiDB NewSQL (3 TiDB + 5 TiKV)Mức Chênh Lệch
Single-Shard Write Latency (P99)1.8 ms11.4 msVitess nhanh hơn 6.3x
Single-Shard Read Latency (P99)0.6 ms2.4 msVitess nhanh hơn 4.0x
Cross-Shard Complex Joins45.0 ms (Qua 2PC Proxy)8.2 ms (TiDB Distributed Coprocessor)TiDB nhanh hơn 5.5x
Peak Throughput (QPS)128,000 QPS84,000 QPSVitess cao hơn 52%
Thời Gian Auto-Recovery Khi Node Sập3.5s (Orchestrator Failover)< 1.0s (Raft Leader Election)TiDB phục hồi nhanh hơn

7. Ma Trận Quyết Định Kiến Trúc (Architectural Decision Matrix)

flowchart TD
    Start{"Lựa Chọn Kiến Trúc Mở Rộng Cơ Sở Dữ Liệu Nào?"}
    
    Start --> CheckShard{"Dữ liệu có phân mảnh sạch theo Shard Key không?<br/>(Ví dụ: tenant_id, user_id, merchant_id)"}
    
    CheckShard -->|"CÓ (95%+ truy vấn là Single-Shard)"| CheckLat{"Độ trễ ghi có phải là SLA sống còn?<br/>(Yêu cầu Sub-2ms Write cho Checkout)"}
    CheckLat -->|"CÓ"| R_Vitess["<b>CHỌN SHARDED MYSQL (VITESS)</b><br/>• Ghi cục bộ Sub-2ms<br/>• Blast Radius cô lập 100%<br/>• Tiết kiệm 60% chi phí FinOps"]
    CheckLat -->|"KHÔNG (Chấp nhận 8-15ms)"| CheckAuto{"Ưu tiên tự động hóa tuyệt đối không DBA?"}
    CheckAuto -->|"CÓ"| R_TiDB_Auto["<b>CHỌN TIDB NEWSQL</b><br/>Zero-touch 96MB Region auto-split"]

    CheckShard -->|"KHÔNG (Nhiều Cross-Shard Joins & Unpartitionable Schema)"| R_TiDB_Join["<b>CHỌN TIDB NEWSQL</b><br/>• Phân tán Distributed SQL Engine<br/>• HTAP TiFlash Analytics thời gian thực"]

8. Hỏi & Đáp Kỹ Thuật (Frequently Asked Questions)

Q1: Khi nào việc chọn TiDB NewSQL sẽ gây thảm họa hiệu năng cho hệ thống?

Khi hệ thống của bạn là ứng dụng thương mại điện tử hoặc cổng thanh toán đòi hỏi độ trễ ghi cực thấp ($< 2\text{ms}$), các bảng có Shard Key rõ ràng (user_id), nhưng bạn lại đưa vào TiDB. Cơ chế Percolator 2PC và đồng thuận Raft của TiDB sẽ kéo độ trễ ghi lên $10\text{ms} - 15\text{ms}$, làm nghẽn hàng đợi kết nối và giảm thông lượng Checkout của ứng dụng.

Q2: Vitess xử lý các câu lệnh Cross-Shard Join như thế nào?

Khi một câu lệnh SQL không chứa Shard Key hoặc phải JOIN giữa các bảng nằm trên 2 shard vật lý khác nhau, VTGate phải đóng vai trò là một bộ điều phối phân tán: gửi câu lệnh con tới từng shard, thu thập kết quả về bộ nhớ của VTGate, sau đó thực hiện phép JOIN trong RAM trước khi trả về cho client. Quá trình này tiêu tốn nhiều RAM của VTGate và có độ trễ lớn.

Q3: Tại sao TiKV lại bị hiện tượng giật độ trễ (Tail Latency Jitter) do RocksDB Compaction?

TiKV sử dụng RocksDB (LSM-Tree) làm công cụ lưu trữ cấp thấp. Khi tải ghi dồn dập, các tệp SSTables ở Level $N$ đầy và kích hoạt tiến trình nén dữ liệu ngầm (Compaction) xuống Level $N+1$. Quá trình này chiếm dụng lượng lớn băng thông đọc/ghi đĩa SSD và CPU, dẫn đến các đợt tăng vọt độ trễ P99.9 tạm thời.

Q4: Làm thế nào để xây dựng kiến trúc lai tối ưu nhất (Hybrid Tiered Architecture)?

Mô hình tối ưu nhất cho các tập đoàn lớn: Sử dụng Sharded MySQL (Vitess) làm tầng cơ sở dữ liệu giao dịch nóng (Hot OLTP Tier) để đạt độ trễ ghi $<2\text{ms}$, sau đó sử dụng Change Data Capture (Debezium / Kafka / TiCDC) đồng bộ dữ liệu thời gian thực sang cụm TiDB + TiFlash làm tầng cơ sở dữ liệu phân tích và báo cáo toàn cục (Global Reporting & HTAP Tier).


← Chương trước: Phần 4: MariaDB vs. MySQL | Mục lục Series | Chương tiếp theo: Phần 6: Apache Kafka vs. NATS JetStream →


❓ Câu Hỏi Thường Gặp (FAQ)

Q1: Sharded MySQL (Vitess) vs. TiDB NewSQL: ACID Phân Tán & Thuế Độ Trễ Mạng giải quyết vấn đề cốt lõi nào trong kiến trúc hệ thống?

Phân tích đối đầu Sharded MySQL (Vitess) vs TiDB NewSQL: Thuế Percolator 2PC, Độ trễ ghi sub-2ms, VReplication, Phân vùng lỗi và FinOps hạ tầng.

Q2: Những lưu ý quan trọng nhất khi triển khai thực tế là gì?

Cần chú trọng phân tầng ranh giới trách nhiệm (bounded context), thiết lập cơ chế fallback dự phòng, và giám sát chặt chẽ qua metrics OpenTelemetry để phát hiện sớm các điểm nghẽn.

Q3: Làm sao để kiểm thử và đánh giá hiệu quả sau khi áp dụng?

Áp dụng kiểm thử tải (load test), benchmark độ trễ P95/P99 trước và sau triển khai, kết hợp tracing phân tán để xác minh tính ổn định dưới tải cao.