Solutions
🔁 1. Resharding (Tái phân phối dữ liệu khi thay đổi số lượng shard)
🎯 Vấn đề:
Khi thêm/bớt shard (ví dụ: mở rộng từ 4 lên 6 shard), hashing hoặc phân vùng cũ không còn chính xác, dẫn đến cần di chuyển nhiều dữ liệu giữa các node.
Ảnh hưởng performance, downtime, consistency.
✅ Cách giải quyết:
➤ Hashing with consistent hashing:
Thay vì
hash(key) % number_of_shards
, dùng Consistent Hashing để giới hạn lượng dữ liệu cần di chuyển khi thêm shard.Lợi ích: Giảm dữ liệu phải migrate ~
1/N
.
➤ Use middleware hỗ trợ Resharding tự động:
Ví dụ: sử dụng Vitess, CockroachDB, Citus, hoặc dùng Sharding Manager Layer tự viết để track vị trí key.
Có thể hỗ trợ online resharding với background replication & sync.
➤ Pre-split ranges (range-based sharding):
Với Range sharding, nên thiết kế trước các khoảng giá trị để dễ scale. Sau đó gộp/tách các range theo nhu cầu.
🔥 2. Celebrity Problem / Hotspot Key Problem
🎯 Vấn đề:
Một số key quá phổ biến (VD: user_id = 0 là admin, hoặc product_id = 100 là flash sale) → mọi request đổ dồn vào 1 shard → bottleneck, overload.
✅ Cách giải quyết:
➤ Data replication cho hotspot:
Replicate dữ liệu "hot" ra nhiều shard (read replica).
Load balancing qua cache layer (Redis cluster) hoặc Read-Only replicas.
➤ Key diversification (key suffixing hoặc salting):
Thay vì lưu vào key
hotKey
, lưu vàohotKey_1
,hotKey_2
,... và client/app layer random hoặc chia hash để truy cập.Sau đó aggregate lại nếu cần (chấp nhận eventual consistency).
➤ Đẩy hot data vào cache layer (Redis, Memcached):
Đặc biệt hiệu quả nếu data đọc nhiều, ghi ít.
Đặt TTL ngắn hoặc sử dụng cache-aside pattern.
➤ Thay đổi chiến lược partitioning:
Nếu Hotspot là do Range Sharding thì cân nhắc chuyển sang Hash-based sharding.
🔗 3. Join Across Shards (Cross-shard join)
🎯 Vấn đề:
Khi cần join dữ liệu giữa 2 table nhưng chúng ở 2 shard khác nhau → rất tốn tài nguyên hoặc không thực hiện được native trong SQL.
✅ Cách giải quyết:
➤ Denormalization (Tái thiết kế dữ liệu):
Tối ưu nhất: tránh join bằng cách copy dữ liệu cần thiết (tức là lưu trùng), nhất là khi dữ liệu ít thay đổi.
➤ Co-locating related data:
Đặt các bảng liên quan vào cùng 1 shard theo khóa chung (composite sharding key).
Ví dụ:
user
vàuser_orders
nên shard theouser_id
→ join được nội bộ trong shard.
➤ Application-level join:
Tách query và thực hiện join ở tầng service:
Query shard A → lấy ID list → query shard B → xử lý join logic.
Có thể kết hợp với async hoặc parallel query để giảm độ trễ.
➤ Use a distributed SQL engine:
Ví dụ: Vitess, TiDB, Citus, Presto/Trino: hỗ trợ join phân tán hiệu quả.
📌 Tổng kết bảng:
Resharding
Consistent Hashing, Middleware (Vitess, Citus), Pre-split ranges
Hotspot Key
Replication, Cache, Key salting, Hashing, Load balance
Cross-shard Join
Denormalization, Co-location, App-level join, Distributed SQL engine
Nếu bạn đang dùng Java + Spring + MySQL/PostgreSQL, bạn có thể cân nhắc:
Redis Cluster cho cache + load balancing hotspot.
Apache ShardingSphere hoặc Vitess nếu cần abstract sharding logic.
Hibernate custom sharding logic nếu muốn kiểm soát cao.
Last updated