system-design

Database Sharding: Chiến lược mở rộng quy mô dữ liệu hàng triệu dòng

Khi Database quá tải, Indexing hay Partitioning không còn đủ. Đã đến lúc nói về Sharding - kỹ thuật chia để trị cực mạnh trong System Design.

newspaper

BlogDev Team

24 tháng 12, 2024
Database Server Room
Featured Image

Bạn đã bao giờ gặp tình huống câu query SQL đơn giản tốn tới 10 giây để chạy? Bạn đã thêm Index, tối ưu câu lệnh, nâng cấp RAM server lên mức tối đa (Vertical Scaling) nhưng Database vẫn “thở dốc” vì lượng dữ liệu quá lớn (Big Data)?

Đó là lúc bạn cần nghĩ đến Database Sharding.

Sharding là gì?

Tưởng tượng bạn có cuốn danh bạ điện thoại dày 10.000 trang tên là “Danh bạ toàn quốc”. Mỗi lần tìm số điện thoại của “Nguyễn Văn A”, bạn phải lật tung cả cuốn sách.

Sharding giống như việc bạn xé cuốn danh bạ đó ra làm 2 cuốn nhỏ:

  • Cuốn 1: Chứa tên bắt đầu từ A-M.
  • Cuốn 2: Chứa tên bắt đầu từ N-Z.

Mỗi cuốn sách này gọi là một Shard. Trong thế giới Database, Sharding là việc chia nhỏ một Database khổng lồ ra thành nhiều Database nhỏ hơn nằm trên các server vật lý khác nhau (Horizontal Scaling).

Tại sao cần Sharding?

1. Vượt giới hạn phần cứng

Một server đơn lẻ luôn có giới hạn vật lý (RAM 128GB, CPU 64 cores). Khi dữ liệu của bạn lên tới hàng Terabytes, không một server nào chứa nổi. Sharding giúp chia tải ra 10, 100 server thường.

2. Tăng tốc độ Query

Thay vì tìm kiếm trên 1 bảng có 1 tỷ dòng, bạn chỉ cần tìm trên shard tương ứng có 100 triệu dòng. Index b-tree nhỏ hơn, vừa vặn với RAM hơn -> Query nhanh hơn.

3. Tăng độ tin cậy (Reliability)

Nếu 1 shard bị sập, chỉ một phần user bị ảnh hưởng (ví dụ user tên N-Z). Các user khác vẫn dùng bình thường.

Các chiến lược Sharding phổ biến

Làm sao để biết user nào nằm ở shard nào? Chúng ta cần Sharding Key.

1. Key Based Sharding (Hash Sharding)

Dùng hàm hash (như CRC32, MD5) trên ID của dữ liệu (ví dụ UserID). Shard_ID = Hash(UserID) % Number_Of_Shards

  • Ưu điểm: Phân bố dữ liệu rất đều.
  • Nhược điểm: Khó thêm bớt Shard. Khi thêm server mới, công thức modulo thay đổi, bạn phải migrate lại toàn bộ dữ liệu (Resharding).

2. Range Based Sharding

Chia theo khoảng giá trị.

  • Shard 1: UserID 1 - 1.000.000

  • Shard 2: UserID 1.000.001 - 2.000.000

  • Ưu điểm: Dễ dàng thêm shard mới (chỉ cần tạo Shard 3 cho dải tiếp theo). Dễ query theo range.

  • Nhược điểm: Data Hotspot. Ví dụ Shard chứa user mới nhất có thể chịu toàn bộ traffic ghi, trong khi Shard cũ thì ngồi chơi xơi nước.

3. Directory Based Sharding (Lookup Table)

Tạo hẳn một bảng riêng (Lookup Table) để lưu map: UserID 123 -> Shard A.

  • Ưu điểm: Cực kỳ linh hoạt. Bạn có thể move user bất kỳ sang shard khác.
  • Nhược điểm: Lookup Table trở thành điểm nghẽn (Single Point of Failure) và cần cache/scale riêng.

Những nỗi đau khi dùng Sharding

“Sharding should be your last resort” (Sharding nên là giải pháp cuối cùng). Tại sao?

  1. Joins & Complex Queries: Bạn không thể JOIN 2 bảng nằm trên 2 server khác nhau. Bạn phải join trong Application code, điều này chậm và phức tạp.
  2. Global ACID Transaction: Transaction xuyên qua nhiều shard (Distributed Transaction) cực khó và chậm.
  3. Resharding data: Việc di chuyển dữ liệu giữa các shard khi hệ thống đang live là một cơn ác mộng về vận hành.

Lời khuyên cho Developer

Trước khi nghĩ đến Sharding, hãy vắt kiệt sức các giải pháp khác:

  1. Caching: Dùng Redis/Memcached để giảm tải đọc.
  2. Read Replicas: Tách server Master (Ghi) và Slave (Đọc).
  3. Partitioning: Chia bảng nhỏ logic nhưng vẫn nằm trên cùng 1 server.
  4. Dọn dẹp dữ liệu: Archive dữ liệu cũ sang kho lạnh (Data Warehouse).

Chỉ khi dữ liệu quá lớn (vài TB) và write traffic quá cao, hãy dùng Sharding. Và nếu có thể, hãy xem xét các NewSQL Database hỗ trợ sharding tự động như CockroachDB, TiDB hay Vitess.

history_edu Góc học tập & giải trí

Thử Thách Kiến Thức Lịch Sử?

Khám phá hàng trăm câu hỏi trắc nghiệm lịch sử thú vị tại HistoQuiz. Vừa học vừa chơi, nâng cao kiến thức ngay hôm nay!

Chơi Ngay arrow_forward