Các giải pháp cho dual write

Các giải pháp cho dual write

Gần hai năm trước, trong bài Dual write, mình có giới thiệu một vài pattern để xử lý dual write và nói rằng có thể sẽ viết kỹ hơn về chúng sau. Hơi lâu một chút, nhưng cuối cùng cũng tới lúc rồi. Nếu chưa đọc bài đó, bạn có thể xem lại để hiểu vấn đề và lý do chỉ đổi thứ tự ghi hay retry trong bộ nhớ vẫn chưa giải quyết được.

Đọc tiếp →

Gom message từ Kafka topic bằng debounced aggregator

Ở Hasaki, khi kho không đủ hàng để đáp ứng một đơn hàng, hệ thống tạo yêu cầu điều chuyển nội bộ để lấy hàng từ địa điểm khác về. Luồng hiện tại publish một Kafka message cho mỗi đơn hàng, và mỗi message lại kích hoạt một yêu cầu điều chuyển riêng.

Vào giờ cao điểm, một kho có thể tạo ra hàng trăm message chỉ trong vài phút. Mỗi message tạo một yêu cầu điều chuyển nhỏ. Đội kho phải xử lý hàng chục yêu cầu lắt nhắt cho cùng một điểm đến, trong khi chỉ cần gom thành một batch là đủ.

Đọc tiếp →

Distributed lock với Redis: Redlock

Dù đã nêu nhiều điểm cần cân nhắc ở bài trước, mình vẫn thấy Redlock là thuật toán có giá trị. Nó vừa hữu ích trong thực tế, vừa là điểm bắt đầu để tìm hiểu cách tư duy về hệ thống phân tán.

Theo kinh nghiệm của mình, những hạn chế lý thuyết của Redlock hiếm khi gây thảm họa trong thực tế. Lý do là kỹ sư chọn Redis thường không đặt cược mọi thứ vào nó. Họ xem Redis là công cụ nhanh nhưng vẫn có thể lỗi, dùng làm cache hoặc rate limiter. Với cách nghĩ đó, họ sẽ bổ sung biện pháp bảo vệ như unique constraint ở database, idempotency key và thao tác an toàn khi retry. Những tình huống lỗi Kleppmann mô tả là có thật, nhưng hệ thống vẫn có thể chịu được nếu không giả định mọi thứ luôn hoàn hảo.

Đọc tiếp →

Distributed lock với Redis: những điểm cần cân nhắc

Dài quá lười đọc: Redis là hệ thống AP, không phải CP, nên không đảm bảo strong consistency. Với những trường hợp có nhiều thao tác đồng thời, bạn cần lường trước khả năng xảy ra data race khi dùng Redis. Nếu cần đảm bảo chặt chẽ, hãy cân nhắc hệ thống có strong consistency như etcd hoặc ZooKeeper.

Lock trên một Redis instance duy nhất

Ở bài trước, chúng ta đã tìm hiểu cách cài đặt distributed lock bằng một Redis instance. Bài đó đã trả lời câu hỏi nếu client crash thì sao?, nhưng còn bỏ ngỏ một câu hỏi quan trọng: nếu chính Redis gặp sự cố thì sao?

Đọc tiếp →

Distributed lock với Redis: một instance duy nhất

Lưu ý: Ví dụ code trong bài dùng Go, nhưng các khái niệm cũng áp dụng được với những ngôn ngữ khác.

Tại sao cần lock?

Thử tưởng tượng hai người cùng rút tiền từ một tài khoản ngân hàng. Nếu không đồng bộ đúng cách, cả hai có thể đọc cùng một số dư, tự trừ khoản tiền mình rút rồi ghi kết quả lại. Khi đó xảy ra lost update: một lần rút tiền coi như biến mất khỏi số dư.

Đọc tiếp →