Scaling Time Series Data Storage — Part I

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

Phần 1/2. Phần 2: Netflix 2018.

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

Bối cảnh

  • Lịch sử xem (viewing history) dùng cho bookmark và gợi ý; hội viên xem hơn 140 triệu giờ/ngày, hơn 100 triệu hội viên (2018). Dữ liệu tăng theo ba chiều: thời gian, số hội viên, số giờ xem mỗi người.
  • Bản cloud-native đầu tiên dùng Cassandra: hợp time series (mỗi row số cột động), tỉ lệ ghi:đọc khoảng 9:1, chọn nhất quán cuối thay vì mất availability.

Thay đổi chính

  • Bắt đầu đơn giản: mỗi hội viên một row (row key CustomerId), mỗi lượt xem một cột. Ghi nhanh; nhưng row ngày càng rộng nên đọc cả row, đọc theo khoảng thời gian, phân trang đều chậm dần; nhiều SSTable phải đọc, compaction và repair nặng hơn.
  • Thêm EVCache trước Cassandra: key CustomerId, value là lịch sử nén; mỗi lần ghi kiểm tra cache, trúng thì merge. Cách này chạy tốt nhiều năm; tới 2012 cụm viewing history là một trong các cụm Cassandra riêng lớn nhất ở Netflix, muốn gấp đôi là vào vùng chưa ai thử.
  • Thiết kế lại thành Live + Compressed để chịu tăng trưởng 5 năm:
    • LiveVH: ít bản ghi gần đây, cập nhật thường xuyên, không nén; compaction thường xuyên, gc_grace_seconds nhỏ, repair thường xuyên.
    • CompressedVH: bản ghi cũ, nén thành một cột mỗi row; hiếm khi sửa, compaction thủ công, kiểm nhất quán lúc ghi nên bỏ được repair.
    • API có tuỳ chọn đọc gần đây (chỉ LiveVH) hoặc toàn bộ (đọc song song hai bảng).
    • Khi đọc LiveVH thấy vượt ngưỡng, task nền gộp và nén vào CompressedVH thành phiên bản mới, đọc lại kiểm tra rồi mới xoá phiên bản cũ; không khoá, ghi trùng hiếm hoi để last-writer-wins.
  • Chunking cho số ít hội viên lịch sử rất lớn: dữ liệu nén vượt ngưỡng thì chia chunk ghi song song lên các node khác nhau (key CustomerId$Version$ChunkNumber), row metadata ghi sau cùng; trường hợp thường gộp metadata vào cùng row. Latency bị chặn ở 1 đọc + 1 ghi (thường) hoặc 2 + 2 (hiếm). Cache cũng chunk tương tự.
  • Kết quả: dữ liệu giảm khoảng 6 lần, thời gian bảo trì Cassandra giảm khoảng 13 lần, latency đọc trung bình giảm khoảng 5 lần, ghi khoảng 1,5 lần.

Vì sao

  • Dữ liệu cũ hiếm khi đổi và hiếm khi cần chi tiết; tách theo tuổi cho phép tối ưu mỗi phần theo cách nó được dùng.

Bài học cho SWE

  • Bắt đầu với mô hình đơn giản nhất phục vụ truy vấn chính; thêm cache trước khi thiết kế lại.
  • Wide row trong Cassandra chậm dần theo thời gian; chặn kích thước bằng nén + chunk cho phần đuôi dài.
  • Ghi phiên bản mới, kiểm tra, rồi mới xoá bản cũ: thay cho khoá khi gộp dữ liệu nền.

Liên quan