Sharding Pinterest: How we scaled our MySQL fleet

Bài tóm tắt Pinterest 2015 2. Tăng trưởng Độ khó: Trung bình

Pinterest · 2015 · 2. Tăng trưởng · Độ khó: Trung bình — bài gốc

Bối cảnh

  • 2011 Pinterest tăng trưởng cực nhanh; khoảng 9/2011 mọi tầng hạ tầng quá tải, vài hệ NoSQL "đều hỏng nặng", còn đọc từ nhiều MySQL slave gây bug khó chịu (nhất là với cache). Năm 2015: hơn 50 tỉ Pin trên 1 tỉ board.
  • Yêu cầu: ổn định, dễ vận hành, nội dung luôn truy cập được, lấy N pin của board theo thứ tự xác định; cập nhật "best effort".

Thay đổi chính

  • Chọn MySQL vì trưởng thành; theo tác giả, startup nên tránh đồ mới (MongoDB, Cassandra, Membase lúc đó crash với họ).
  • Bắt đầu 8 server EC2, mỗi server một MySQL, master-master sang máy backup; production chỉ đọc/ghi master ("đừng bao giờ đọc slave trong production").
  • 4.096 shard ảo là database db00000… phân theo dải trên máy vật lý; bảng cấu hình dải → host nằm trong ZooKeeper. Dữ liệu vào shard nào thì ở đó mãi; thêm capacity bằng chuyển cả shard sang máy mới (nhân bản rồi chia đôi dải), mở dải shard mới, hoặc nâng máy.
  • ID 64 bit = shard ID 16 bit + type 10 bit + local ID 36 bit (auto-increment trong shard), 2 bit dự trữ: ID tự chỉ chỗ dữ liệu, không cần dịch vụ sinh ID.
  • Bảng object (local_id, JSON blob); sửa bằng read-modify-write trong transaction SELECT ... FOR UPDATE. Bảng mapping một chiều (from, to, sequence) nằm ở shard của from; join làm ở tầng ứng dụng, cache mapping trong Redis và object trong memcache.
  • Không cần ALTER: thêm field bằng sửa JSON schema ở service (theo bài, khoảng một lần ALTER trong ba năm). Mod shard (md5 % 4096) cho tra theo khoá ngoài như Facebook ID, IP, email.
  • Không dùng auto-failover; script promote slave. Hệ thống không bảo đảm A, I, C đầy đủ; chuyển dữ liệu cũ sang phải chạy đi chạy lại tới khi phần sót gần bằng 0.

Vì sao

  • Ưu tiên giải pháp đơn giản dùng được ngay, node rất ổn định, tránh di chuyển dữ liệu từng item.

Bài học cho SWE

  • Tạo nhiều shard ảo từ đầu và chỉ di chuyển cả shard: thêm máy là chia dải, không phải resharding từng dòng.
  • Nhúng vị trí vào ID loại bỏ lookup và dịch vụ sinh ID.
  • Lưu blob JSON + bảng mapping đổi tính năng SQL lấy khả năng thay schema không cần ALTER.

Liên quan