MySQL sharding at Quora

Bài tóm tắt Quora 2020 3. Quy mô lớn Độ khó: Nâng cao

Quora · 2020 · 3. Quy mô lớn · Độ khó: Nâng cao — bài gốc

Quora chặn crawler; đọc toàn văn qua trình duyệt ngày 2026-10-21, Wayback lúc đó offline.

Bối cảnh

  • MySQL giữ câu hỏi, câu trả lời, upvote, comment: hàng chục TB (chưa kể replica), hàng trăm nghìn QPS; thêm Memcache và Redis cho đọc. Dữ liệu và QPS ghi tăng nên phải shard.
  • Vài năm trước đó đã có vertical sharding: chuyển bảng sang host khác (mysqldump trong một transaction kèm vị trí binlog → restore → replay binlog của bảng → cutover bằng rename bảng nguồn rồi cập nhật vị trí trong ZooKeeper). Nghiêng về nhất quán: có cửa sổ ngắn lỗi "table not found"; undo bằng replay ngược. Join trong MySQL bị cấm gần hết để tự do chuyển bảng.

Thay đổi chính

  • Bảng lớn vẫn có vấn đề: pt-online-schema-change cần gấp đôi dung lượng, chạy hàng giờ tới hơn một ngày, khoá X lúc tạo trigger, trigger nhân đôi ghi; chọn sai index trên bảng 1 TB tai hại hơn 100 GB; bảng lớn không chuyển được bằng cách trên.
  • Tự làm thay vì dùng bên thứ ba: dưới 10 bảng (trong vài trăm) cần shard; dùng lại hạ tầng vertical sharding; API DB đã nhận tham số tường minh (do đội security bỏ SQL text để chống injection) nên không phải parse SQL; ít join; dự định dùng graph API kiểu TAO nên không muốn thêm một lớp middleware.
  • Shard theo bảng, không theo database, vì codebase dựa nhiều vào secondary index; range-based vì dùng nhiều range query; dải ghi trong tên bảng T_shard_x_y, metadata trong ZooKeeper.
  • API sharded_select() nhận cột shard và một khoá, danh sách khoá, khoảng khoá hoặc None (quét mọi shard); không hỗ trợ join, group by, offset. Chọn cột shard theo QPS và độ nhạy latency của các query không theo cột đó; cross-shard index là bảng riêng, không cập nhật nguyên tử.
  • Ít shard: vài trăm GB/shard nếu khoá auto-increment (tăng ở shard cuối), dưới 100 GB nếu không; dùng dump Hive để chọn biên.
  • Quy trình migrate: copy theo lô có rate limit → replay binlog → dark read dài (shadow_select so kết quả) → dark write → copy lại từ đầu (vì dark write lệch dữ liệu do không có 2PC) → replay → dark read ngắn → cutover bằng rename → reverse replay về bảng cũ để có đường lùi.
  • Tách shard lớn bằng EXCHANGE PARTITION: đổi shard thành bảng hai partition qua online schema change rồi hoán đổi tức thì sang hai shard con; shard cuối của khoá auto-increment chỉ cần cắt ở cuối.
  • Đã shard ba bảng lớn; tính chuyển một số use case HBase sang MyRocks shard.

Vì sao

  • Theo Quora, chi phí tích hợp phần mềm bên thứ ba chỉ đáng khi cần shard khoảng 100 bảng trở lên.

Bài học cho SWE

  • Vertical sharding mua được vài năm; horizontal sharding chỉ cần cho số ít bảng lớn.
  • Shadow read/write trước cutover và replay ngược sau cutover cho đường lùi; dark write làm lệch dữ liệu nên phải copy lại.
  • API truy vấn có cấu trúc (không phải SQL text) là điều kiện thuận lợi để thêm sharding vào tầng ứng dụng.

Liên quan