Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Redis

Thành Thạo Redis Pub/Sub: Hướng Dẫn Nhanh Cho Nhắn Tin Nhanh

Tổng Quan Pub/Sub

Thiết Kế Pub/Sub: Tách Biệt "Publisher" Khỏi "Subscriber"

Giảm thiểu phụ thuộc và phân vùng kiến thức là mục tiêu then chốt trong thiết kế phần mềm có thể mở rộng. Mô hình nhắn tin publish/subscribe (pub/sub) tách biệt các phần của phần mềm bạn mà phát hành tin nhắn khỏi các phần mà hành động trên tin nhắn. Để hiểu rõ hơn, hãy xem một số ví dụ:

Ví Dụ Của "Publisher"

  • Một ứng dụng cho phép bạn gửi tin nhắn đến phòng chat
  • Một container Docker thông báo sức khỏe hoặc dịch vụ của nó
  • Một ứng dụng công bố giá giao dịch cổ phiếu
  • Một cảm biến nhiệt độ trong nhà bạn công bố đọc của nó
  • Một broadcaster tin nhắn trong game đa người chơi ("Elon đã bị grue ăn")

Ví Dụ Của "Subscriber"

  • Các ứng dụng lắng nghe tin nhắn trong phòng chat.
  • Một ứng dụng chuyển tiếp thông báo đến Slack
  • Một client di động dùng để xem điều gì đang xảy ra real-time
  • Một dịch vụ ghi log sự kiện để phân tích sau

Mô hình pub/sub giúp bạn tránh suy nghĩ quá nhiều về subscriber khi làm việc trên publisher, và ngược lại. Trong các ví dụ trên, chúng ta có thể tưởng tượng một vài subscriber quan tâm đến tin nhắn từ bất kỳ publisher nào. Các subscriber thậm chí có thể muốn lắng nghe tất cả publisher.

Trong pub/sub, một publisher không cần biết về subscriber của nó – nó đẩy một tin nhắn đến một channel (thường gọi là topic trong các hệ thống khác) và tiếp tục. Bất kỳ subscriber nào đang lắng nghe trên channel đó khi tin nhắn được phát hành sẽ nhận được nó.

Subscriber được thiết kế để lắng nghe một hoặc nhiều channel và phản ứng với tin nhắn khi chúng đến. Nếu một subscriber không thể theo kịp tốc độ tin nhắn được phát hành, nó sẽ bỏ lỡ một số tin nhắn. Đây là một thiết kế hữu ích: nó cho phép hệ thống mở rộng vượt quá khả năng của bất kỳ subscriber chậm nào. Publisher tiến về nhanh chóng mà không bị chậm lại do hành vi của subscriber.

Mục Tiêu Của Pub/Sub: Mở Rộng Phát Hành, Không Phải Xử Lý Khối Lượng Công Việc

Pub/sub là một mô hình được dùng trong mở rộng phần mềm – quan trọng để hiểu loại mở rộng nào nó giúp. Một sự phân biệt quan trọng là giữa pub/sub và hàng đợi tin nhắn (message queueing).

Trong mô hình hàng đợi, một hàng đợi (hoặc list trong Redis) đệm các tin nhắn cần xử lý trong khi một pool worker lấy mục khỏi list và xử lý chúng. Trong mô hình này, mở rộng kích thước pool worker của bạn mở rộng tốc độ xử lý hàng đợi, vì mỗi tin nhắn chỉ được truyền cho một worker. Tất cả worker xử lý bất kỳ tin nhắn nào theo chính xác cùng một cách.

Trong pub/sub ngược lại, hệ thống cố gắng gửi tất cả tin nhắn của một channel đến tất cả subscriber của nó. Đây là mô hình many-to-many, nơi mỗi subscriber khác nhau làm điều gì đó độc đáo với tin nhắn – cái ghi vào log bền vững, cái gửi đến Slack channel, cái reo chuông trong văn phòng bán hàng địa phương, v.v.

Tóm lại, pub/sub mở rộng phát hành tin nhắn, và hàng đợi mở rộng xử lý khối lượng công việc tin nhắn. Redis thường được dùng cho cả hai mục tiêu. Xem Sidekiq cho một ví dụ phổ biến của hàng đợi với Redis.

Đặc Điểm Của Redis Pub/Sub

Pub/sub là một mô hình đã tồn tại rất lâu, và trong khi mô hình cốt lõi là giống nhau, các tính năng cụ thể khác nhau đáng kể từ triển khai này sang triển khai khác.

Redis pub/sub là một triển khai nhẹ, nhanh. Để hiểu tốt nhất thiết kế của nó, sẽ hữu ích khi nhìn vào một số tính năng không phải là một phần của Redis pub/sub:

  • Không có persistence hoặc cache giá trị
  • Không có bảo đảm giao hàng (delivery guarantees)
  • Không có tối ưu hóa cluster... cho đến nay

Không Có Persistence: "Nhưng Tôi Tưởng Nó Giống Phòng Chat..."

Khác với hầu hết các thao tác Redis, có thể được ghi vào disk, Redis pub/sub là non-persistent. Tin nhắn phát hành được truyền trực tiếp đến subscriber và sau đó bị loại bỏ, không có bản ghi nào được giữ lại trong bộ nhớ Redis hoặc trên disk.

Điều này đôi khi gây nhầm lẫn cho người dùng mới nghe rằng Redis pub/sub thường được dùng để triển khai phòng chat. Nhiều người nghĩ đến các công cụ như Slack như phòng chat – bạn đăng nhập và thấy tin nhắn gần đây và sau đó nhận tất cả tin nhắn mới. Thực tế "xem tin nhắn gần đây" không phải là một phần của pub/sub, và phải được xử lý bằng cách riêng. Pub/sub chỉ hỗ trợ việc gửi tin nhắn mới. Trong nghĩa này, pub/sub giống như một livestream – khi bạn bật nó, bạn bắt đầu nhận thông tin, nhưng bạn không học được gì về điều gì xảy ra trước khi bạn bật nó. Bổ sung: Internet Relay Chat (IRC) sử dụng mô hình pub/sub không có lịch sử hoặc giữ tin nhắn tích hợp – đó là lý do ẩn dụ phòng chat rất phổ biến.

Thực tế bạn vẫn có thể triển khai phòng chat với Redis và pub/sub. Để làm vậy, bạn sẽ đảm bảo tin nhắn không chỉ được phát hành mà cũng được đẩy vào một list để người dùng có thể xem lịch sử tin nhắn.

Không Có Bảo Đảm Giao Hàng

Subscriber không được bảo đảm nhận tin nhắn trong mô hình pub/sub. Nếu một subscriber gặp sự cố mạng, không đọc tin nhắn đủ nhanh, hoặc ngờ nghệch không được gắn kết khi tin nhắn được phát hành, nó chỉ đơn giản không nhận được tin nhắn. Publisher có thể gửi tin nhắn đến channel ngay cả khi không có subscriber lắng nghe – những tin nhắn đó bị loại bỏ.

Một số hệ thống nhắn tin khác sử dụng read receipts hoặc "acks" hoặc có thể lưu đệm cho subscriber giúp chống lại các giai đoạn ngắt kết nối ngắn. Redis chọn lựa chọn đơn giản ở đây: nếu bạn bỏ lỡ tin nhắn, bạn đã bỏ lỡ tin nhắn. Tin nhắn bắt buộc phải đến người nhận cần được gửi bằng phương tiện khác.

Đánh đổi này nghe có vẻ tệ hơn thực tế. Việc loại bỏ xác nhận tin nhắn và đệm riêng cho subscriber cho phép Redis pub/sub xử lý tin nhắn rất nhanh, và có nhiều hệ thống hưởng lợi từ việc giao hàng "thời tiết đẹp".

Mở Rộng Cluster Không Hiệu Qua, Cho Hiện Tại...

Pub/sub là giải pháp cho mở rộng, vì vậy quan trọng để xem xét mở rộng không chỉ tin nhắn của bạn mà cả dịch vụ bạn dùng để gửi tin nhắn. Nhiều hệ thống nhắn tin, bao gồm RabbitMQ và Kafka, được thiết kế cho high availability và các thuộc tính mở rộng hợp lý khi thiết lập dịch vụ nhắn tin phát triển.

Redis Cluster (phần của Redis từ 3.0) có hỗ trợ tích hợp cho Redis pub/sub, với một lưu ý quan trọng. Mọi tin nhắn phát hành được broadcast đến mọi thành viên của một Redis cluster, điều này có thể nhanh chóng khiến các cluster lớn bị quá tải với traffic.

Câu trả lời ngắn gọn là chỉ dùng pub/sub trên các Redis server riêng lẻ hoặc trên các cluster nhỏ chuyên dụng cho pub/sub – cả hai tùy chọn này đều có thể xử lý một lượng lớn tin nhắn. Dài hạn, Redis Cluster sẽ có tính năng thông minh hơn để định tuyến tin nhắn chỉ khi cần, nhưng tính năng đó vẫn đang trong giai đoạn thiết kế.

Tổng Kết

Tổng thể Redis pub/sub là một công cụ hữu ích cho mở rộng phần mềm. Sự vắng mặt của từng tính năng chúng ta đã xem ở trên là một đánh đổi thiết kế, dẫn đến sự đơn giản và tốc độ cho Redis với chi phí là không phải là liều thuốc chữa hết cho mọi mục đích nhắn tin.

Giống như nhiều phần khác của Redis, nó không được tùy chỉnh cho mọi trường hợp sử dụng chuyên biệt nhưng nó có thể đưa bạn đi rất xa với một chút hiểu biết. Kết hợp với các tính năng khác của Redis, nó trở thành một công cụ rất mạnh mẽ trong bộ công cụ của nhà phát triển.

Với tổng quan cấp cao hoàn tất, bạn có thể đã sẵn sàng xem một số ví dụ mã pub/sub. Hãy xem Redis Pub/Sub: How To tiếp theo.