How We Partitioned Airbnb's Main Database in Two Weeks

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

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

Bối cảnh

  • Trước mùa du lịch hè 2015, DB MySQL chính (trên RDS, còn từ thời Airbnb là một app Rails) phải giảm tải. Airbnb chọn tách dọc theo chức năng thay vì shard ngang (theo bài, đồng ý với Asana và Percona rằng shard ngang là "thuốc đắng"); các service Java/Rails mới đã có DB riêng. Lần tách DB trước là năm 2012.
  • Profiler query phía client (tự viết vì RDS giới hạn) cho thấy hộp thư tin nhắn chiếm gần 1/3 số ghi của DB chính và tăng tuyến tính theo traffic; là chức năng độc lập nên bỏ được join và transaction chéo bảng.
  • Khoảng 130 engineer, rất ít người làm hạ tầng: chấp nhận downtime có kế hoạch để giảm công sức.

Thay đổi chính

  • Dùng replication của MySQL thay cho code migrate: tạo replica message-master từ master chính, gắn replica tầng hai message-replica, rồi promote message-master thành master độc lập (tính năng "Read Replica Promotion" của RDS). Không viết dòng code đối soát hay chép dữ liệu nào.
  • Chuẩn bị (tốn thời gian nhất, cần phối hợp nhiều team): tìm mọi query join chéo bằng query analyzer, thay bằng join trong app; với service còn lại, thu hồi quyền DB để chắc chắn không sót. Pipeline dữ liệu chuyển sang đọc export của message-replica. Promote không đảo ngược được nên bước này quyết định thành bại.
  • Thao tác: báo trước cho CS về downtime dưới 10 phút của hộp thư, làm lúc traffic thấp nhất tuần; deploy dùng user/kết nối DB mới cho tin nhắn (đọc đã sang replica); đổi host DB trong Zookeeper (SmartStack phát hiện, không cần deploy) để ghi trỏ sang master mới (ghi lỗi, bắt đầu tính downtime); kill kết nối cũ trên master chính; kiểm replication đã đuổi kịp; promote (DB chết hẳn khoảng 30 giây, ghi lỗi gần 4 phút vì 3,5 phút sau khi gọi promote mới chạy); bật Multi-AZ; xoá bảng thừa ở hai bên. Kế hoạch lùi: đổi lại host trong Zookeeper, mất các ghi đã vào DB mới.
  • Kết quả: khoảng hai tuần, dưới 7,5 phút downtime hộp thư, DB chính nhỏ đi 20%, ghi giảm 33% (phần này dự kiến còn tăng 50% trong vài tháng).
  • Bất ngờ: snapshot RDS dù có Multi-AZ vẫn làm latency tăng, và khi DB tải nặng thì tăng phi tuyến tới mức dồn query và làm sập DB; backup tự động hằng ngày hoá thành rủi ro ngày càng lớn theo tải, nên việc tách gấp hơn tưởng.

Vì sao

  • Downtime cục bộ có kiểm soát của một chức năng rẻ hơn nhiều so với cả site sập vì DB chính quá tải, và rẻ hơn vài tuần công viết migration có đối soát.

Bài học cho SWE

  • Tách dọc theo chức năng trước khi nghĩ tới shard ngang; dùng cơ chế sẵn có (replication) làm phần khó nhất là giữ nhất quán.
  • Thu hồi quyền truy cập là cách chắc chắn nhất để biết không còn ai dùng bảng cũ.
  • Thao tác cuối cùng không đảo ngược được thì dồn công vào chuẩn bị và tập dượt từng bước.

Liên quan