New Tweets per second record, and how!

Bài tóm tắt Twitter 2013 3. Quy mô lớn Độ khó: Trung bình

Twitter · 2013 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc

Bối cảnh

  • 3/8/2013 (khán giả Nhật xem Castle in the Sky): đỉnh 143.199 tweet/giây, trong khi bình thường là >500 triệu tweet/ngày, tức ~5.700 TPS. Đỉnh gấp ~25 lần mà user không thấy gián đoạn.
  • Ba năm trước, World Cup 2010 làm Twitter liên tục không truy cập được. Các tối ưu tại chỗ bị tăng trưởng nuốt chửng; họ "hết quả ngọt".
  • Hiện trạng sau 2010:
    • Một trong những cài đặt Ruby on Rails lớn nhất thế giới, ~200 kỹ sư cùng sửa một codebase monolith (từ kết nối DB tới render và public API).
    • Tweet lưu trên MySQL shard theo thời gian, một master: hot spot đọc/ghi, phải tạo DB mới ngày càng nhanh.
    • "Ném máy vào vấn đề"; code bị hy sinh tính dễ đọc để lấy hiệu năng.

Thay đổi chính

  • Mục tiêu: giảm latency (cả median lẫn outlier), giảm 10 lần số máy, cô lập lỗi; ranh giới logic rõ ràng; team nhỏ ra tính năng độc lập.
  • Ruby VM → JVM: Rails chỉ đạt 200–300 request/giây/host (mỗi process xử lý một request, nhân bản process bằng Unicorn). Họ đã có kinh nghiệm JVM (search viết bằng Java; Streaming API và Flock viết bằng Scala). Sau khi viết lại: 10–20K request/giây/host.
  • Một mô hình lập trình thống nhất: khi mỗi team tự làm concurrency/networking theo cách riêng, họ gặp thundering herd do client retry dồn dập vào service chậm và không có back-pressure nhất quán. Họ xây Futures + Finagle (thư viện client/server chung có pool kết nối, failover, load balancing).
  • Tách service theo "danh từ lõi": Tweet, timeline, user.
  • Storage: T-Bird = Gizzard đứng trước nhiều MySQL, hash tweet để chọn DB. Mất auto-increment, nên dùng Snowflake sinh ID (Twitter 2010). Đọc và ghi được phân tán khắp cluster thay vì dồn vào "DB mới nhất".
  • Observability: Viz (metric) và Zipkin (tracing) tích hợp sẵn trong Finagle; một dòng code là có metric p50/p99.
  • Runtime config: hệ thống Decider bật/tắt tính năng đồng loạt trên nhiều service, cho phép theo % traffic. Code deploy ở trạng thái "off" rồi tăng dần. Nó thay cho việc phối hợp deploy giữa các team.

Kết quả (2013)

Latency p50→p99 giảm mạnh; số máy giảm 5–12 lần; gần bốn số 9 availability trong 6 tháng; >50 lượt deploy/tuần trên các service.

Vì sao

Theo Twitter: monolith gây nghẽn cả về hiệu năng lẫn tổ chức; storage shard theo thời gian dồn mọi lượt ghi vào một master. Họ cũng nói rõ: tổ chức engineering được dựng lại để phản chiếu kiến trúc (team tự chủ sở hữu service).

Bài học cho SWE

  • Thiết kế cho đỉnh, không cho trung bình (đỉnh gấp 25 lần).
  • Shard theo thời gian tạo hot spot vì mọi lượt ghi mới dồn vào DB mới nhất. Chuyển sang hash.
  • Khi tách service, cần thư viện RPC chung (Finagle) ngay từ đầu, nếu không mỗi team tự tạo ra lỗi riêng (retry storm).
  • Feature flag runtime (Decider) tách deploy khỏi release.
  • Đánh đổi tự thừa nhận: không phải team nào cũng lên kế hoạch thay đổi giống nhau; đổi biểu diễn Tweet có thể bắt các service khác phải cập nhật.

Liên quan