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 Thực Hành Chi Tiết

Hiểu Về Channel

Một channel là một tên được sử dụng để phân loại các tin nhắn được phát hành trên hệ thống pub/sub. Channel có thể có tên phụ thuộc vào hệ thống, như system-health:i-36a44b83, trade-prices:RAX, temp-reading:living-room, hoặc rất chung chung, như events. Bất kỳ subscriber quan tâm đến dữ liệu xuất hiện trên một channel đều có thể lắng nghe nó, và các publisher/subscriber mới dễ dàng được thêm vào khi hệ thống mở rộng.

Để biết channel nào đang hoạt động trên server Redis, bạn có thể sử dụng lệnh PUBSUB CHANNELS, lệnh này không trả về gì khi hệ thống chưa được sử dụng cho pub/sub:

$ redis-cli pubsub channels
(empty list or set)

Channel chỉ tồn tại trên hệ thống khi một subscriber đang lắng nghe tin nhắn trên nó, vì vậy không cần bao giờ "tạo" hoặc "xóa" channel – chúng chỉ tồn tại selama subscriber đang lắng nghe. Để thấy điều này, chúng ta có thể dùng redis-cli đóng vai subscriber ở một cửa sổ console, và chạy PUBSUB CHANNELS lại ở cửa sổ khác:

Console 1:

$ redis-cli subscribe events
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "events"
3) (integer) 1

Console 2:

$ redis-cli pubsub channels
1) "events"

Ngay khi Console 1 ngắt kết nối, hệ thống sẽ trở lại không có channel nào.

Phát Hành Tin Nhắn

Cú Pháp Lệnh

Lệnh PUBLISH được dùng để phát hành tin nhắn.

PUBLISH channel message

Tất cả subscriber đang lắng nghe trên channel sẽ nhận được tin nhắn. Nếu không có subscriber nào xung quanh để nhận tin nhắn, tin nhắn sẽ bị loại bỏ.

Ví Dụ Node.js

Sau khi tạo kết nối thường đến Redis, publish có thể được sử dụng như bất kỳ lệnh nào khác:

var client = require("redis").createClient();
client.publish("temp-reading:living-room", "37.0");

Sử Dụng Với Các Lệnh Redis Khác

Phát hành dữ liệu đến một channel là một thao tác nhanh, vì vậy nó thường được dùng kết hợp với các thao tác khác. Kết hợp các thao tác như thế này khai phá sức mạnh của Redis:

var client = require("redis").createClient();
client.multi()
  .publish("temp-reading:living-room", "37.0")
  .lpush("recent-temperatures", "37.0")
  .ltrim("recent-temperatures", 0, 99)
  .exec();

Đây là cùng một thao tác như ví dụ trước cho hệ thống pub/sub, nhưng trong cùng một giao dịch MULTI/EXEC, nhiệt độ cũng được đẩy vào một list giữ 100 nhiệt độ gần nhất.

Ví dụ ngắn này cho thấy một cách tích hợp Redis pub/sub vào một thiết kế hệ thống lớn hơn bao gồm lịch sử tin nhắn. Một thao tác như trên cho phép các client khác truy vấn các giá trị gần đây cũng như đăng ký các giá trị mới.

Đăng Ký Tin Nhắn

Cú Pháp Lệnh

Lệnh SUBSCRIBE được dùng để đăng ký các channel. Lệnh này đặt client vào một trạng thái đặc biệt "đã đăng ký" nơi nó không còn gửi các lệnh khác ngoài SUBSCRIBE hoặc UNSUBSCRIBE bổ sung.

SUBSCRIBE channel [channel ...]

Ví Dụ Node.js

Subscriber này có thể được dùng với ví dụ publisher trước đó:

var subscriber = require("redis").createClient();
subscriber.on("message", function(channel, message) {
  console.log("A temperature of " + message + " was read.");
});
subscriber.subscribe("temp-reading:living-room");

Đây sử dụng một event emitter đơn giản gọi một hàm mỗi khi tin nhắn đến. Hàm xử lý chỉ ghi nhiệt độ ra console ngay bây giờ – nó có thể làm bất cứ điều gì.

Sử Dụng Các Lệnh Khác Với Subscriber

Như đã đề cập, client đã đăng ký ở một chế độ đặc biệt và không thể dùng cho các lệnh khác. Để dùng các lệnh khác, bạn sẽ tạo một kết nối client riêng đến Redis:

var redis = require("redis"),
    subscriber = redis.createClient(),
    client = redis.createClient();
subscriber.on("message", function(channel, message) {
  console.log("A temperature of " + message + " was read.");
  client.incr("temp-count");
});
subscriber.subscribe("temp-reading:living-room");

Handler này ghi tin nhắn ra console và tăng một counter Redis. Trong một số trường hợp, bạn có thể tính toán một kết quả và sau đó phát hành kết quả đó đến một channel riêng cho các subscriber khác đọc – chỉ đừng phát hành nó trở lại channel bạn đang lắng nghe, vì bạn sẽ gây ra vòng lặp vô tận :)

Khớp Mẫu (Pattern Matching)

Cú Pháp Lệnh

Lệnh PSUBSCRIBE được dùng để khớp mẫu channel.

PSUBSCRIBE pattern [pattern ...]

Điều này hoạt động giống như lệnh SUBSCRIBE thông thường nhưng cho phép bạn khớp các channel có tên khớp với một mẫu. Điều này cho phép publisher rất cụ thể về thông tin họ phát hành, và cho phép subscriber lắng nghe nhiều channel mà không cần biết tên chính xác của chúng.

Các mẫu được hỗ trợ rất đơn giản: * khớp bất kỳ ký tự nào, ? khớp một ký tự đơn, và dấu ngoặc vuông có thể dùng để khớp một tập hợp ký tự chấp nhận được, như [acd].

Khớp đọc nhiệt độ từ nhiều phòng:

PSUBSCRIBE temp-reading:*

Khớp sự kiện từ A/B test như site-link:logo:a:clickrate và site-link:logo:b:clickrate:

PSUBSCRIBE site-link:logo:?:clickrate

Khớp sự kiện qua một loạt instance AWS, cho các sự kiện phát hành như system-health:us-east-1a:i-36a44b83 và system-health:us-east-1c:i-73657420636f636f6:

PSUBSCRIBE system-health:us-east-1[acd]:i-*

Ví Dụ Node.js

Trong ví dụ này, cũng có thể dùng với ví dụ publishing trước đó, nhiệt độ được ghi kèm theo phòng nơi nhiệt độ được đọc.

var subscriber = require("redis").createClient();
subscriber.on("pmessage", function(pattern, channel, message) {
  var room = channel.split(":")[1];
  console.log("A temperature of " + message + " was read in " + room);
});
subscriber.psubscribe("temp-reading:*");

Subscriber dựa trên mẫu nhận thêm một vài chi tiết trong callback: không chỉ channel và tin nhắn, mà còn mẫu cụ thể đã khớp – vì subscriber có thể lắng nghe trên nhiều channel hoặc mẫu.

Ghi Chú: Đặc Điểm Hiệu Suất Của PUBLISH

Mọi lệnh trong Redis đều có độ phức tạp thời gian được tài liệu hóa, và hầu hết thời gian các độ phức tạp này là trực quan. Vì thao tác PUBLISH cảm thấy rất đơn giản (gần như SET) người ta có thể giả định độ phức tạp của nó là O(1). Thực tế, độ phức tạp thời gian của PUBLISH tăng tuyến tính theo hành vi của subscriber.

Khi lệnh PUBLISH chạy, nó phải duyệt qua tất cả các pattern đã đăng ký có thể khớp với channel và tất cả subscriber nên nhận tin nhắn, dẫn đến độ phức tạp thời gian O(N+M).

Hầu hết các triển khai sẽ không bao giờ gặp rắc rối hiệu suất với độ phức tạp của PUBLISH, nhưng theo dõi hiệu suất của lệnh đó theo thời gian vẫn khôn ngoan – hãy cẩn thận nếu mã của bạn tự động tạo ra các pattern channel để lắng nghe.

Mã Của Bạn Ở Đây?

Chúng tôi rất muốn giới thiệu một walk-through của một số ví dụ tuyệt vời về ứng dụng được xây dựng bằng Redis pub/sub. Nếu bạn biết một số ví dụ tốt, hãy gửi cho chúng tôi tại support@redisgreen.net – chúng tôi sẽ cố gắng giới thiệu một số mã chúng tôi thấy.