Tracking the Money — Scaling Financial Reporting at Airbnb
Bài tóm tắt Airbnb 2017 3. Quy mô lớn Độ khó: Trung bình
Airbnb · 2017 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Bối cảnh
- Thanh toán của Airbnb chạy ở 191 nước, hơn 70 loại tiền, hơn 20 bộ xử lý thanh toán (2017); sản phẩm mở rộng ngoài đặt phòng (trả tiền thợ ảnh, phiên dịch, trải nghiệm).
- Hệ báo cáo tài chính cũ (đầu 2012 → cuối 2016) là một ETL MySQL chạy đêm: trigger trên các bảng chính ghi lại mọi thay đổi của reservation và payment (để có lịch sử bất biến trên dữ liệu production vốn thay đổi được), rồi dựng bảng trung gian (doanh thu đã ghi nhận, phải thu, phải trả cho host) và từng báo cáo riêng.
Thay đổi chính
- Vấn đề của bản cũ: SQL không hợp mô hình nghiệp vụ phức tạp; logic gắn chặt với luồng đặt phòng nên mỗi sản phẩm mới là thêm báo cáo; báo cáo dựng riêng lẻ nên lệch số không biết do đâu; không test được; lần chạy đêm hơn 24 giờ, cuối đời chỉ chạy được hai ngày một lần.
- Hệ mới chạy Spark trên HDFS, viết bằng Scala, mô hình event handler:
- Platform event (đặt, sửa, huỷ, dịch vụ đã cung cấp) và payment event (tiền vào/ra, gift card, coupon không có dòng tiền thật) được sinh từ các dòng audit.
- Handler theo từng loại sản phẩm biến chúng thành accounting event; đơn vị nhỏ nhất là (loại sản phẩm, id sản phẩm).
- Từ đó sinh subledger theo kế toán kép: mỗi bút toán có thời điểm, số tiền, loại tiền, ghi nợ/có, tài khoản; tiền không tự xuất hiện hay biến mất.
- Một vòng đời chung cho mọi sản phẩm: hợp đồng tạo kỳ vọng (phải thu từ khách, phải trả tương lai cho host) → dòng tiền → dịch vụ hoàn thành (ghi nhận doanh thu) → chi trả.
- Sửa đơn (khách thêm ngày) xử lý bằng unbook rồi rebook toàn bộ thay vì tính phần chênh: đơn giản hơn khi sửa chồng sửa và khi backfill.
- Kết quả (3/2017): chạy đêm 4–5 giờ, scale ngang; một nguồn sự thật để điều tra lệch số; unit test cho từng handler + integration test + smoke test (luật dữ liệu phải thoả, vi phạm thì ghi log xử lý).
- Hướng tới: hệ tài chính tiêu thụ event do các hệ khác phát ra thay vì đọc audit row.
Vì sao
- Tách logic kế toán khỏi logic sản phẩm để sản phẩm mới chỉ cần một handler, và để thoát giới hạn của một instance RDS.
Bài học cho SWE
- Trigger ghi lịch sử là giải pháp tạm hữu ích nhưng đẩy độ phức tạp sang ETL SQL; theo Airbnb, chính họ thừa nhận đó không phải pattern tốt.
- Kế toán kép là một bất biến kiểm được bằng máy: tổng vào phải bằng tổng ra.
- Khi dữ liệu nguồn hay bị sửa, "xoá và ghi lại toàn bộ" dễ đúng hơn tính delta.
Liên quan
- Pipeline dữ liệu và analytics · Event-driven, message queue và Kafka
- Thanh toán chống trùng ở phía online: Airbnb 2019
#financial reporting#MySQL trigger#ETL#Spark#Scala#event handler#double entry accounting#subledger#unbook/rebook#smoke test
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (1)