Caching Without Marshal Part 2: The Path to MessagePack
Bài tóm tắt Shopify 2022 3. Quy mô lớn Độ khó: Trung bình
Shopify · 2022 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc
Phần 2; phần 1 Shopify 2022 kể sự cố và lý do.
Thay đổi chính
- MessagePack từ chối object lạ: chỉ mã hoá kiểu cơ bản và extension type đã đăng ký; object khác ném
NoMethodErrorcó tham chiếu tới object. Đó là điểm để log xem thứ gì đang bị đưa vào cache. - Migrate song song khoảng 6 tháng:
- Thử mã hoá bằng MessagePack; được thì thêm byte tiền tố phiên bản (theo dõi tập extension type đã định nghĩa) rồi ghi.
- Không được thì bắt lỗi, quay về Marshal, và gửi lớp của object hỏng vào log và StatsD.
- Khi đọc, phân biệt bằng tiền tố:
0408là Marshal, còn lại là MessagePack. Log của bước 2 vừa cho biết cần extension type nào, vừa lộ những thứ lẽ ra không bao giờ nên vào cache.
- Bản mã hoá riêng cho ActiveRecord, gồm cả association và tham chiếu vòng; khi đọc mà tên class hay association không còn, ném lỗi rõ ràng và coi như trượt cache. Hệ quả: trong lúc deploy đổi tên class, các key liên quan bị vô hiệu và phải nạp lại, chấp nhận được vì sau deploy cache chạy lại bình thường.
- Gặp bug của
msgpack-ruby(extension type không áp cho lớp con của Hash nhưHashWithIndifferentAccess), gửi PR sửa (bản 1.4.3). - 95% payload mã hoá được ngay; 5% cuối là đuôi dài. Thêm type cho
TimeWithZone,Set, rồi một type bắt mọi object cóas_pack/from_pack, và module cho Struct/T::Struct. Khi log xác nhận không còn payload Marshal, bỏ hẳn Marshal. - Kết quả: cache an toàn mặc định; tỉ lệ đầy của memcached giảm rõ (MessagePack gọn hơn). Mở mã nguồn thành thư viện Paquito.
Vì sao
- Định dạng có tiền tố phiên bản và danh sách kiểu tường minh biến lỗi tương thích từ "sập" thành "trượt cache" (Cache và invalidation).
- Ghi định dạng mới, đọc được cả hai, quay về định dạng cũ khi chưa hỗ trợ, đo phần còn lại tới 0 rồi mới bỏ: mẫu migrate không downtime cho dữ liệu đang được dùng (Migration không downtime).
Bài học cho SWE
- Đặt tiền tố phiên bản vào mọi payload bền hoặc dùng chung để đọc được nhiều định dạng.
- Dùng đường fallback làm cảm biến: log mọi lần phải quay về định dạng cũ để biết còn bao nhiêu và là gì.
- Với cache, "trượt có kiểm soát" khi gặp dữ liệu không hiểu được tốt hơn exception.
Liên quan
#MessagePack#Extension types#Version prefix#Dual format#Fallback#Long tail#Packable#Paquito#Cache invalidation on deploy
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (1)