Tôi đã thấy nhiều kỹ sư rất giỏi “đốt” 30 phút trong một buổi design review để cãi nhau về “sharding” trong khi thứ họ thực sự muốn nói là “read replica”.
Cảm giác y chang việc lẫn lộn bits và bytes: từ nghe na ná nhau, xuất hiện trong cùng một cuộc hội thoại, và não bạn tự quyết định chúng có thể hoán đổi.
Không.
Bài này đưa cho bạn một mô hình tư duy rõ ràng + ví dụ thực tế để bạn nói cho đúng từ và chọn đúng công cụ.
Trước khi đi kỹ thuật, bắt đầu bằng phiên bản đời thường.
Mô hình đời thực
Hãy tưởng tượng bạn kinh doanh trà sữa.
- Bạn có một cuốn sổ công thức lớn (dữ liệu).
- Bạn có một bếp chính (database).
- Bạn cũng có nhiều cửa hàng trong thành phố (nhiều node).
Giờ map các buzzword:
- Partitioning: bạn chia cuốn sổ thành các chương (trà sữa, trà trái cây, topping) để nhân viên tìm nhanh hơn.
- Bucketing: trong từng chương, bạn bỏ công thức vào các bìa kẹp đánh số (1..32) để runner nhảy thẳng tới đúng bìa.
- Sharding: bạn mở thêm bếp và mỗi bếp “sở hữu” một phần menu hoặc một phần khách hàng.
- Replication: bạn photo cùng một cuốn sổ công thức cho mọi cửa hàng để nếu một cửa hàng cháy, business vẫn chạy.
- Edge computing: bạn chuẩn bị sẵn topping phổ biến tại từng cửa hàng để khách không phải chờ bếp chính.
Nếu bạn muốn mẹo nhớ đơn giản hơn, hãy nhớ theo động từ:
- Partitioning: chia nhỏ (bên trong một DB)
- Bucketing: băm/hash (vào các nhóm cố định)
- Sharding: chia nhỏ trên nhiều máy (nhiều DB)
- Replication: sao chép (cùng dữ liệu, nhiều node)
- Edge: đưa compute lại gần (nhiều vị trí)
Cheat sheet (mỗi khái niệm một câu)
- Partitioning: chia một bảng thành nhiều mảnh bên trong một database để query và vận hành dễ hơn.
- Bucketing: băm dữ liệu vào một số lượng bucket cố định (thường nằm trong partitions) để đọc/join có thể “prune” bớt việc.
- Sharding: chia dataset ra nhiều instance database để scale vượt giới hạn một máy.
- Replication: sao chép cùng dataset ra nhiều node để chịu lỗi tốt hơn và scale đọc.
- Edge computing: đưa compute lại gần người dùng; đây là topology triển khai, không phải cách chia dữ liệu.
Nếu bạn chỉ nhớ một câu, nhớ câu này:
Partitioning và bucketing là tổ chức dữ liệu. Sharding là phân phối dữ liệu. Replication là nhân bản dữ liệu. Edge là di chuyển compute.
Ý chính: hai lớp hoàn toàn khác nhau
Hầu hết nhầm lẫn đến từ việc trộn quyết định layout dữ liệu với quyết định nơi code chạy.
Đây là “diagram” mà tôi ước mọi người vẽ lên whiteboard:
| |
Giờ ta đi từng thuật ngữ theo kiểu “kỹ sư phải vận hành lúc 3 giờ sáng”.
Cây quyết định 30 giây
Khi ai đó nói “chúng ta cần sharding”, chạy checklist nhanh này:
| |
Không hoàn hảo, nhưng nó chặn được ~80% quyết định kiến trúc tệ.
Partitioning: “vẫn một database, nhưng chia thành mảnh nhỏ”
Partitioning là khi một bảng logic được chia thành nhiều phần nhỏ bên trong cùng một database (cùng logical cluster; trong RDBMS truyền thống thường vẫn là cùng một instance/host).
Vì sao làm:
- Bạn muốn partition pruning (chỉ scan các mảnh liên quan).
- Bạn muốn bảo trì rẻ (drop/archive partition cũ nhanh).
- Bạn muốn giảm phình index bằng cách giữ mỗi partition nhỏ hơn.
Ví dụ kinh điển: bảng events theo thời gian.
Ví dụ đời thường: đơn hôm nay để trên khay ngoài quầy, hóa đơn tháng trước để trong thùng phía sau. Vẫn một cửa hàng, chỉ là giấy tờ được tổ chức để bạn không phải bới toàn bộ.
| |
Khi bạn query tháng 1, planner có thể bỏ qua các tháng khác.
Partitioning không phải là gì:
- Nó không phải horizontal scaling. Bạn vẫn có “trần” CPU/RAM/I/O của một máy.
Bucketing: “hash dự đoán được để giảm việc phải làm”
Bucketing thường là một kỹ thuật ở data warehouse/lakehouse: bạn băm (hash) một hoặc vài cột vào một số lượng bucket cố định.
Vì sao làm:
- Join nhanh hơn (cùng key sẽ hash vào cùng bucket).
- Parallelism tốt hơn (mỗi bucket xử lý độc lập).
- Plan dự đoán được hơn (một số bucket cố định để scheduler/engine scan).
Mô hình dễ hình dung:
| |
Nếu bạn chủ yếu làm OLTP (web backend điển hình), có thể bạn sẽ không “đụng” bucketing trực tiếp. Nhưng bạn vẫn gặp nó gián tiếp trong Spark/Hive/Iceberg/BigQuery-style pipelines.
Ví dụ đời thường: bạn có 32 folder dán nhãn cho hóa đơn, dựa trên 5 bit cuối của mã hóa đơn. Bạn không mở hết, bạn mở đúng một folder.
Sharding: “giờ thì là nhiều database”
Sharding là khoảnh khắc bạn chấp nhận thực tế:
Một máy database không đủ nữa (kích thước dữ liệu, throughput ghi, giới hạn connection, hoặc I/O).
Và bạn chia dataset ra nhiều instance database.
Ví dụ đời thường: một bếp có hàng dài mỗi tối. Bạn có thể tối ưu menu (index), chuẩn bị trước (cache), hoặc nâng cấp bếp (scale up). Nhưng tới một điểm bạn cần bếp thứ hai (scale ngang).
Thứ người ta hay đánh giá thấp: routing
Khi shard, mỗi request phải tìm đúng shard.
Có thể làm bằng:
- App tự routing (app chọn shard).
- Một lớp proxy/router.
- Tính năng của database (một số hệ có, kèm trade-off).
Logic routing minh hoạ:
| |
Chọn shard key (bài toán thật sự)
Shard key tốt:
- Dàn đều tải.
- Khớp access pattern.
- Tránh “hot shard”.
Shard key tệ:
- Dồn tất cả writes vào một shard (ví dụ ID tăng dần + routing theo range).
- Khiến query phổ biến nhất phải “cross-shard”.
Các nỗi đau (bạn trả giá mãi)
- Join cross-shard: thường biến thành “fetch nhiều shard, merge ở app”.
- Transaction: khó cross-shard (two-phase commit, saga, hoặc “đừng làm vậy”).
- Rebalancing: thêm shard nghĩa là phải chuyển dữ liệu, an toàn.
Sharding mạnh, nhưng không phải “mẹo performance”. Nó là quyết định platform.
Ví dụ đời thường: Bếp A phục vụ nửa thành phố, Bếp B phục vụ nửa còn lại. Mỗi bếp ít order hơn, nhưng giờ bạn cần dispatcher route order tới đúng bếp.
Replication: “nhiều bản sao của cùng dữ liệu”
Replication nói về availability và scale đọc.
Mô hình rất đơn giản:
- Sharding: mỗi node có các row khác nhau.
- Replication: mỗi node có cùng các row.
Topology phổ biến nhất:
| |
Trade-off bạn chọn:
- Replication đồng bộ (synchronous): an toàn hơn, nhưng writes có thể chậm.
- Replication bất đồng bộ (asynchronous): writes nhanh, nhưng replica có thể lag (eventual consistency).
Về vận hành, replication cho bạn:
- Đường failover.
- Offload traffic đọc.
- Disaster recovery.
Nhưng nó không giảm kích thước dataset trên mỗi node (mỗi replica vẫn phải chứa tất cả).
Ví dụ đời thường: mọi cửa hàng đều có cùng một cuốn sổ công thức. Rất tốt cho resilience và training, nhưng in ra và cập nhật đồng loạt là một công việc.
Edge computing: “đưa code lại gần người dùng”
Edge computing không phải kỹ thuật layout dữ liệu trong database.
Nó là một mô hình triển khai compute, nơi code chạy ở rất nhiều vị trí gần user (CDN POPs, edge regions, gateway on-device).
Câu chuyện “edge” phổ biến nhất trong hệ thống thực:
- Request của user chạm edge cache.
- Nếu cache hit: trả ngay.
- Nếu miss: fetch từ origin (app theo region + database), rồi cache lại.
Luồng minh hoạ:
| |
Edge làm reads nhanh và rẻ. Nhưng nó không tự nhiên giải quyết write scaling hoặc strong consistency.
Ví dụ đời thường: topping phổ biến được chuẩn bị sẵn ở mỗi cửa hàng (edge) để pha nhanh. Nhưng hệ thống tồn kho trung tâm (origin) vẫn là nơi quyết định “thật sự còn bao nhiêu”.
Ghép tất cả lại: câu chuyện ecommerce đơn giản
Giả sử bạn vận hành một trang ecommerce.
- User xem trang sản phẩm (rất nhiều reads).
- User đặt hàng (writes).
- Bảng orders lớn dần mãi.
- Bạn bán toàn cầu.
Đây là kiến trúc “trưởng thành” bạn thường sẽ đi tới:
- Edge cho trang sản phẩm
- Trang sản phẩm và hình ảnh được cache gần user.
- Phần lớn traffic không chạm database.
- Replication cho các query đọc nặng
- Primary xử lý writes.
- Replica phục vụ dashboard/reporting và các endpoint đọc nặng.
- Partitioning cho bảng orders
- Partition
orderstheo tháng để query “7 ngày gần nhất” nhanh. - Archive partition cũ thành thao tác đơn giản.
- Chỉ shard khi thật sự vượt ngưỡng một primary
- Nếu writes quá cao, shard theo
customer_id(hoặc key khác khớp access pattern). - Giờ mọi request phải route đúng shard.
- Analytics cross-customer khó hơn, nên thường chuyển analytics sang hệ thống riêng.
Câu chuyện này là lý do “edge vs sharding” là sai category. Chúng giải quyết các nỗi đau khác nhau.
Vậy… nên làm gì trước?
Nếu bạn đang xây một sản phẩm “bình thường”, lộ trình “lớn lên” thường là:
- Schema + index + sửa query (đa số “vấn đề scale” chỉ là query tệ)
- Partitioning (khi bảng quá lớn và time slicing hợp lý)
- Replication (khi reads áp đảo)
- Caching / CDN / edge (khi latency và bandwidth quan trọng)
- Sharding (khi một máy thật sự không gánh nổi write/size)
Không phải hệ thống nào cũng tới bước 5. Nhiều hệ thống không nên.
Những lỗi phổ biến tôi hay gặp
Gọi read replica là “shard”
- Nếu mọi node có cùng dữ liệu, đó là replication.
Chọn shard key theo org chart thay vì theo traffic
- “Shard theo quốc gia” nghe gọn gàng cho tới khi một quốc gia chiếm 80% user.
Shard để sửa một query chậm
- Nếu một query chậm trên một node, nó thường cũng chậm trên mọi shard.
3.5. Dùng hàm shard tệ
- Hàm routing phải ổn định và nhất quán qua restart/deploy.
- “Chạy trên máy tôi ok” không phải sharding strategy.
Phớt lờ ngày rebalancing
- “Thêm shard sau cũng được” là cách bạn tự đẩy mình vào data migration trong lúc incident.
Tưởng edge = storage nhất quán
- Edge rất tốt cho caching, auth, personalization, routing.
- Nhưng source of truth vẫn nằm ở đâu đó (thường là regional).
Kết
Khi người ta nói “chúng ta nên shard”, thường họ đang muốn nói một trong bốn điều:
- “Query chậm” (thường là vấn đề index/query)
- “Reads quá cao” (replication/caching)
- “Latency toàn cầu quá cao” (edge)
- “Một database không gánh nổi writes/kích thước” (sharding thật)
Khác bài toán. Khác công cụ.
Nếu bạn muốn, hãy nói workload bạn nhắm tới (OLTP hay analytics, write-heavy hay read-heavy, global hay một region) và tôi sẽ giúp bạn chọn partitioning vs replicas vs sharding vs edge cho đúng scenario.
