Thắc mắc về building infra ứng dụng chat
Anh Dũng ơi,
Em đang nghiên cứu về system design ứng dụng chat có khả năng scale nhiều WebSocket server, và em đang nghĩ cách là dùng Redis Pub/Sub để broadcast message giữa các server. Tuy nhiên, em đang không rõ nếu Redis (kể cả trong trường hợp sử dụng Redis Cluster) bị downtime thì các WebSocket server sẽ nhận message như thế nào?
Liệu giải pháp hợp lý trong trường hợp này có nên là truy vấn lại message từ database không ạ?
Anh có thể giải thích giúp em hướng xử lý phù hợp hoặc best practice cho tình huống này không ạ?
Remain: 5
2 Answers
tvd12
Enlightened
tvd12
Enlightened
Dùng redis cũng là một ý tưởng tốt em ạ, nhưng dùng redis đúng như em nói khi cluster bị down thì tin nhắn từ server A có thể không broadcast đến B, C được dẫn đến những client kết nối đến B, C không nhận được tin nhắn.
Vậy nên giải pháp đưa ra là tin nhắn vẫn phải được lưu ở trong cơ sở dữ liệu nữa. Khi client kết nối với bất kỳ server nào thì nó sẽ đồng bộ tin nhắn (tính từ tin nhắn cuối cùng mà nó nhận được), server cũng sẽ gửi các tin nhắn cho client tính từ tin nhắn lần cuối nó gửi cho các client, ví dụ:
- Server A: Nhận được tin nhắn thứ 100, nó cần broadcast đến B để gửi cho client X, nhưng cluster down, vậy B sẽ vẫn còn trạng thái là last message id = 99.
- Trường hợp cluster không kịp sống lại và client disconnect sau đó kết nối vào A thay vì B thì client sẽ đồng bộ lại toàn bộ tin nhắn tính từ 99.
- Trường hợp cluster sống lại thì B sẽ lại tiếp tục lấy tin nhắn từ 99 và gửi cho các client bao gồm cà X, client vẫn giữ kết nối đến B nên tiếp tục nhận được tin nhắn.
Nhìn chung vẫn phải kết hợp nhiều thứ chứ không chỉ Redis hay DB là đủ em ạ, DB cung cấp giải pháp lưu trữ bền bỉ, còn redis cung cấp giải pháp thông báo cho các websocket server biết có tin nhắn mới để mà vào DB lấy ra rồi gửi đi và cập nhật trạng thái.
-
1
tvd12
Enlightened
tvd12
Enlightened
Làm sao để biết Redis down? Thực tế thư viện nào cũng cung cấp cơ chế ping pong để biết được trạng thái của Redis là gì để kết nối lại hoặc bắn ra lỗi để em có thể em gửi về hệ thống monitoring.
Trên thực tế thì việc lấy message ở máy chủ B có thể là:
- Đợi có message bắn sang từ A.
- Chạy 1 vòng loop liên tục để kiểm tra xem có message mới không (ví dụ 100ms 1 lần).
Kết hợp cả 2 cái này thì dù Redis có down hay không thì Websocket Server vẫn hoạt động bình thường được.
Như em có thể thấy không nhất thiết phải có Redis đâu, tất nhiên có redis thì nhiều khi tin nhắn được bắn ngay mà đỡ phải bị deplay 100ms
-
1