Netflix Billing Migration to AWS — Part II

Bài tóm tắt Netflix 2016 4. Điều chỉnh Độ khó: Trung bình

Netflix · 2016 · 4. Điều chỉnh · Độ khó: Trung bình — bài gốc

Series 3 phần: Netflix 2016 (tổng quan) · phần 2 (bài này) · Netflix 2016 (database).

Bối cảnh

  • Trước dự án: 2 Oracle trong DC (subscription; hoá đơn/thanh toán), vài app REST làm CRUD cho website và CSKH, 3 batch (gia hạn hằng ngày, xử lý order và payment, báo cáo doanh thu), một Billing Proxy trên cloud chuyển lời gọi về DC, giao tiếp qua hàng đợi Weblogic định dạng cũ.
  • Yêu cầu: không được mất dữ liệu; SLA chặt cho xử lý hằng ngày vì doanh thu phải ghi đúng ngày; một phần cần ACID, phần khác cần sẵn sàng đa region.

Thay đổi chính

Kế hoạch ba "hồi", mỗi nước chuyển xong thì rút kinh nghiệm cho nước sau:

  • Act I — nước mới chạy trên cloud, đồng bộ ngược về DC. 6 nước sắp mở được phục vụ bởi app mới (Spring Boot, Spring Integration) với dữ liệu trong Cassandra ở nhiều region; batch cũ vẫn ở DC nên dữ liệu được đồng bộ ngược qua SQS + dead letter queue về một region có đường nối thẳng tới Oracle. Proxy cloud định tuyến theo nước của user. Gia hạn cho 6 nước này dùng crawler quét toàn bộ dòng Cassandra, biết trước là không scale nhưng đủ để thử.
  • Mô hình dữ liệu Cassandra: key là customerId, các thực thể liên quan nằm trong một column family bằng composite column để có tính "giao dịch" giữa chúng. Quy tắc: đọc một lần đầu thao tác, sửa trong bộ nhớ, ghi một lần cuối; đọc/ghi giữa chừng bị coi là anti-pattern. ORM tự viết trên Astyanax.
  • Act II — chuyển ứng dụng, chưa chuyển database. Viết lại batch thay vì bê nguyên (đọc config từ đĩa, hàng đợi Weblogic là anti-pattern trên instance tạm thời); một số API chuyển sang async để đi qua hàng đợi. Gia hạn cho toàn bộ thành viên đổi sang Aegisthus đọc SSTable Cassandra ra JSON trên S3, Pig chạy MapReduce mỗi ngày; Sqoop đẩy cả Oracle và Cassandra vào Hive để join khi điều tra.
  • Migrate từng nước: tắt các API không phải GET của nước đó (thành viên không thấy gì, chỉ trễ cập nhật) → Sqoop từ Oracle ra S3/Hive → Pig đổi sang định dạng Cassandra → ghi vào Cassandra → bật lại API ghi phục vụ từ cloud. Comparator chạy lặp: tìm lỗi, xoá dữ liệu, chạy lại đến khi sạch. Bắt đầu bằng nước ít thành viên, rồi gom nhóm nước giống nhau, Mỹ cuối cùng (đông nhất, có DVD).
  • Act III — Oracle còn lại quá quan hệ để ép sang NoSQL; Oracle trên cloud đắt license, Aurora còn beta, nên chọn MySQL trên EC2 (chi tiết ở phần 3). Viết lại PL/SQL thành logic ứng dụng. Kiến trúc cuối: master MySQL một region, DB dự phòng để promote, replica chỉ đọc ở region khác.

Vì sao

  • Mỗi hồi chỉ đổi một biến (nơi phục vụ API, nơi chạy batch, nơi lưu dữ liệu quan hệ), nên lỗi khoanh vùng được và lùi được.

Bài học cho SWE

  • Cassandra không có giao dịch nhiều dòng; gom các thực thể cần đổi cùng nhau vào cùng partition và ghi một lần là cách lấy lại phần nguyên tử.
  • "Tạm chấp nhận giải pháp không scale" (crawler quét hết) là hợp lý khi biết trước điểm phải thay và tập dữ liệu còn nhỏ.
  • Cắt theo quốc gia với API ghi tạm khoá cho mỗi lát là một dạng downtime cục bộ, ngắn, người dùng không thấy, thay cho một lần chuyển lớn.
  • Kết quả theo bài (2016): hơn 81 triệu thành viên ở 190+ nước, mọi phần billing chạy trên cloud.

Liên quan