Roshi: a CRDT system for timestamped events

Bài tóm tắt SoundCloud 2014 2. Tăng trưởng Độ khó: Khó

SoundCloud · 2014 · 2. Tăng trưởng · Độ khó: Khó — bài gốc

Bối cảnh

  • Stream của SoundCloud: các event (thời điểm, ai làm, làm gì) từ những người mình follow, xếp mới nhất trước.
  • Cách đang chạy là fan-out on write trên Cassandra: mỗi user một row làm "inbox"; ai đó repost thì chèn event vào inbox của mọi follower. Đọc nhanh, nhưng theo SoundCloud: càng nhiều follower thì ghi càng lâu, lưu trữ tăng theo bậc hai với số user và mật độ follow, đổi social graph thì gần như không cập nhật nổi ở tầng dữ liệu. Những ràng buộc đó bắt đầu cản việc thử tính năng mới cho stream.

Thay đổi chính

  • Đổi mô hình sang fan-in on read: mỗi hành động chỉ là một lần append vào outbox của người làm; khi xem stream thì đọc các event mới nhất từ outbox của mọi người mình follow rồi merge. Ghi nhanh, lưu ít, stream luôn phản ánh graph hiện tại.
  • Cái khó dồn sang đọc: follow hàng nghìn người là hàng nghìn lần đọc song song, sắp xếp, merge, cắt trong deadline của một request. Theo SoundCloud, họ không biết ai ở quy mô tương tự dựng timeline bằng fan-in on read.
  • Dữ liệu toàn bộ chỉ dự kiến cỡ trăm GB, nên đặt hết trong bộ nhớ trên máy thường.
  • Dùng CRDT (thao tác kết hợp, giao hoán, idempotent) để có nhất quán cuối khi lỗi mà không phải tự lo điều phối phức tạp: một kiểu set gần LWW-element-set có dọn rác nội tuyến, lưu trạng thái trong Redis ZSET, tầng vận hành không trạng thái phía trên tự sửa khi đọc và ghi.
  • Roshi: khoảng 5.000 dòng Go (2.300 dòng test), khoảng 6 tháng-người, mã nguồn mở; lúc viết bài đang rollout.

Vì sao (theo SoundCloud)

Câu hỏi hiển nhiên là "sao không dùng Cassandra hay hệ có sẵn?". Theo SoundCloud, cái giá của hệ tổng quát hay bị đánh giá thấp: dịch bài toán sang ngôn ngữ chung của hệ, học chi tiết cài đặt, vận hành ở quy mô lớn, gặp bug do use case lạ. Với bài toán xác định rõ, lời giải chuyên biệt có thể rẻ hơn. Đây là quan điểm riêng của SoundCloud.

Bài học cho SWE

  • Fan-out on write và fan-in on read là hai đầu của cùng một đánh đổi đọc/ghi; khi chi phí ghi và lưu trữ chặn sản phẩm thì đáng xét lật mô hình (Realtime và fan-out).
  • Ràng buộc thao tác thành idempotent, giao hoán thì nhất quán cuối gần như "miễn phí"; đổi lại phải thiết kế mô hình dữ liệu cho vừa CRDT.
  • Bài toán nhỏ (vừa RAM) và hẹp có thể biện minh cho một kho tự viết thay vì database tổng quát (Chọn database theo workload).

Liên quan