Centrifuge: a reliable system for delivering billions of events per day
Bài tóm tắt Segment 2018 3. Quy mô lớn Độ khó: Khó
Segment · 2018 · 3. Quy mô lớn · Độ khó: Khó — bài gốc
Bài ngoài sheet. Centrifuge là bước 1 trong Segment 2018 (thay cho 140+ queue riêng); bài này cho thấy nó giữ lại cô lập lỗi phía đích, còn cô lập trước bug crash trong service đã gộp thì bài đó vẫn để ngỏ.
Bối cảnh
- Segment nhận hàng trăm nghìn event mỗi giây và chuyển tới hàng trăm đích (Google Analytics, Salesforce, webhook của khách). Bất kỳ lúc nào cũng có vài chục đích đang hỏng: latency tăng 10 lần, 5xx, rate limit với từng khách lớn.
- Queue thất bại theo từng bước:
- Một queue chung: một đích chậm tạo backpressure lên toàn bộ luồng. Với hơn 200 đích, mỗi đích sập một giờ mỗi năm (99,9%), thì gần như mỗi ngày có một giờ ngừng.
- Một queue cho mỗi đích: cô lập theo đích nhưng tải khách theo luật lũy thừa; một khách lớn dồn 50.000 message liền nhau vào queue của một đích có rate limit 1.000/giây/khách thì hoặc chặn khách nhỏ 50 giây, hoặc gặp 429 rồi retry làm chậm thêm, hoặc chép hàng TB sang dead-letter queue.
- Lý tưởng là một queue cho mỗi cặp (nguồn, đích): 42.000 nguồn × trung bình 2,1 đích = 88.000 queue và còn tăng; Kafka, RabbitMQ, NSQ, Kinesis đều không scale tới số lượng đó một cách đơn giản.
Thay đổi chính
- Queue ảo trên database: thứ tự giao nằm trong MySQL (RDS), nên đổi chất lượng dịch vụ hay thứ tự giao chỉ là một câu SQL, không phải chép lại hàng TB dữ liệu như với queue (thứ tự trong Kafka do producer chốt).
- Mô hình dữ liệu: bảng
jobs(payload trung vị 5 KB, tối đa 750 KB; khoá chính KSUID, chỉ một index) và bảngjob_state_transitions, cả hai bất biến, chỉ append; không JOIN giữa các job; tập làm việc nhỏ. Máy trạng thái: chờ lập lịch → đang chạy → thành công / bị loại (400) / chờ retry (timeout, 5xx; backoff luỹ thừa) → quá hạn 4 giờ thì lưu trữ lên S3. - Một người ghi cho mỗi DB: mỗi Director (Go) giữ độc quyền một JobDB qua session Consul, cache toàn bộ job trong RAM và tự lo invalidation không cần phối hợp; chỉ đọc DB khi khôi phục sau lỗi. Lượng ghi áp đảo lượng đọc.
- Scale storage theo compute: 80–300 Director tự scale theo CPU; JobDB Manager giữ số DB khớp số Director, có DB dự phòng, và xoay vòng JobDB khoảng 30 phút một lần trước khi dữ liệu vượt RAM: sau 30 phút 99,9% event đã xong, một tiến trình nhỏ chuyển các job đang retry sang DB khác rồi
drop tablethay cho hàng loạtDELETEngẫu nhiên.
Kết quả (theo Segment, 2018)
- 5 kỹ sư, 9 tháng, 50.000 dòng Go; 400.000 HTTP request ra ngoài mỗi giây (load test 2 triệu); 340 tỉ job trong một tháng. Khoảng 1,5% dữ liệu chỉ giao được nhờ retry, một nửa số đó cần từ lần thử 3 tới 10.
- Sự cố thật một tháng sau khi triển khai: một tích hợp phổ biến (bình thường 16.000 request/giây) chỉ còn khoảng 15% thành công trong gần hai giờ. Centrifuge giữ lại khoảng 85 triệu event trong 90 phút và giao hết trong 30 phút sau đó; không mất dữ liệu, các tích hợp khác không bị ảnh hưởng. Họ thừa nhận chiến lược retry còn phải chỉnh: lúc đỉnh đã bắn khoảng 100.000 request/giây vào API của đối tác.
Bài học cho SWE
- Queue chỉ có push/pop; khi cần đổi thứ tự, ưu tiên, hay cô lập theo tenant ở số lượng lớn, một DB làm queue có thể linh hoạt hơn.
- Cô lập lỗi phía đích không nhất thiết đến từ việc tách service: ở đây nó đến từ queue ảo theo (khách, đích).
- Dữ liệu ngắn hạn có thể xoá theo cả bảng (xoay vòng DB) thay vì từng dòng.
- Retry giúp giao thêm dữ liệu nhưng cũng là tải dồn vào đối tác đang yếu; cần giới hạn.
Liên quan
- Multi-tenancy và cô lập tenant
- Segment 2018 (cùng năm, gom worker về một service) · Segment 2017
- Event-driven, message queue và Kafka · Hot partition và thundering herd · Monolith và microservices — đi và quay lại
Event-driven, message queue và KafkaHot partition và thundering herdMonolith và microservices — đi và quay lạiMulti-tenancy và cô lập tenant
#Centrifuge#Job scheduler#Virtual queue#Per-tenant isolation#Database as a queue#MySQL RDS#Immutable rows#KSUID#Single writer#Consul session#JobDB cycling#Drop table#Exponential backoff#Retry 1.5%
Được nhắc tới trong
Chủ đề (4)
Công ty (1)
Bài tóm tắt (3)