Debugging Production with Event Logging
Bài tóm tắt Zillow 2018 2. Tăng trưởng Độ khó: Dễ
Zillow · 2018 · 2. Tăng trưởng · Độ khó: Dễ — bài gốc
Bối cảnh
- Trang tìm căn hộ: khi lưu một bản ghi vào SQL, các thuộc tính tìm kiếm được index vào Elasticsearch; search chạy trên Elasticsearch, rồi lấy bản ghi đầy đủ từ SQL theo ID.
- Lỗi: kết quả tìm kiếm thỉnh thoảng có căn không khớp điều kiện, vì index Elasticsearch lệch với DB (giá thuê 1.000 trong index, 2.000 trong DB). Vừa mới chuyển dữ liệu căn hộ từ MongoDB sang SQL; nghi race condition, thứ không đặt breakpoint được.
Thay đổi chính
- Ghi sự kiện có ngữ cảnh (NewRelic custom event) mỗi lần index một căn: ID, phản hồi của Elasticsearch (gồm
versioncủa document), snapshot thuộc tính, stack trace. - Job đối chiếu chạy vài lần mỗi ngày: tìm bản ghi lệch giữa SQL và Elasticsearch, sửa, và gửi alert kèm snapshot dữ liệu.
- Ghép hai thứ: mỗi alert cho một ID, truy vấn lịch sử index của ID đó, thấy các lần index dồn sát nhau, version bị nhảy, và dòng code gây ra. Ba nguyên nhân:
- Job chạy sau khi lưu đọc từ replica chưa kịp nhận bản ghi mới từ master.
- Job được xếp hàng trong callback
after_savecủa Rails, chạy trước khi transaction commit; worker nhanh thì đọc dữ liệu cũ. - Job "index lại khi lỗi kết nối" ghi thẳng vào Elasticsearch (bỏ qua thư viện, để tránh vòng lặp tạo job), cũng xếp hàng từ
after_save: nguồn của version bị nhảy.
- Sửa: job đọc từ master; chuyển xếp hàng sang
after_commit.
Vì sao
- Index dẫn xuất được cập nhật bằng job bất đồng bộ sẽ lệch nếu job chạy trước commit hoặc đọc replica trễ; đây là dạng nhỏ của bài toán outbox (Event-driven, message queue và Kafka, Hạ tầng tìm kiếm).
- Race condition ở production chỉ tìm được bằng sự kiện có ngữ cảnh ghi sẵn, không bằng debugger (Observability và monitoring).
Bài học cho SWE
- Phát job sau commit (
after_commit, outbox), và job đọc từ nguồn không trễ khi cần dữ liệu vừa ghi. - Index dẫn xuất cần job đối chiếu định kỳ với nguồn sự thật, vừa sửa vừa báo.
- Ghi kèm version/phản hồi của hệ đích vào log sự kiện để thấy thứ tự ghi.
Liên quan
#Elasticsearch#Index drift#Race condition#Rails after_save vs after_commit#Replica lag#Background job#NewRelic custom events#Reconciliation job
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (4)