Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Redis

Redis Pub/Sub:Howto Guide

บทความภาพรวมของเราเกี่ยวกับ Redis pub/sub กล่าวถึงจุดประสงค์ของ pub/sub และอธิบายตัวเลือกการออกแบบของ Redis pub/sub โดยเฉพาะ ตอนนี้เราจะมาพูดถึงวิธีใช้ Redis pub/sub โดยก้าวผ่านแนวคิดหลักแต่ละข้อของ Redis pub /sub:ช่อง เผยแพร่ สมัครรับข้อมูล และจับคู่รูปแบบ โดยใช้ไคลเอ็นต์ noderedis node.js

ทำความเข้าใจช่อง

ช่อง เป็นชื่อที่ใช้ในการจัดหมวดหมู่ข้อความที่เผยแพร่บนผับ/ระบบย่อย ช่องอาจมีชื่อขึ้นอยู่กับระบบ เช่น system-health:i-36a44b83 ,trade-prices:RAX , temp-reading:living-room หรืออะไรทั่วไป เช่นevents . ผู้ติดตามที่สนใจในข้อมูลที่ปรากฏบนช่องสามารถฟังได้ และผู้เผยแพร่ใหม่และผู้ติดตามสามารถเพิ่มได้อย่างง่ายดายเมื่อระบบเติบโตขึ้น

หากต้องการค้นหาว่าช่องใดเปิดใช้งานอยู่บนเซิร์ฟเวอร์ Redis คุณสามารถใช้ PUBSUB CHANNELS คำสั่ง ซึ่งไม่ส่งคืนสิ่งใดเมื่อระบบยังไม่ได้ใช้สำหรับ pub/sub:

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

ช่องจะมีอยู่บนระบบก็ต่อเมื่อสมาชิกกำลังฟังข้อความอยู่ ดังนั้นจึงไม่จำเป็นต้อง "สร้าง" หรือ "ลบ" ช่อง - ช่องเหล่านี้มีอยู่ในขณะที่สมาชิกกำลังฟังอยู่เท่านั้น หากต้องการดูสิ่งนี้ เราสามารถใช้ redis-cli เพื่อทำหน้าที่เป็นสมาชิกในหน้าต่างคอนโซลเดียว และเรียกใช้ PUBSUB CHANNELS อีกครั้งในอีกหน้าต่างหนึ่ง:

คอนโซล 1:

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

คอนโซล 2:

$ redis-cli pubsub channels
1) "events"

ทันทีที่คอนโซล 1 ตัดการเชื่อมต่อ ระบบจะไม่มีช่องสัญญาณอีกครั้ง

กำลังเผยแพร่ข้อความ

ไวยากรณ์คำสั่ง

PUBLISH คำสั่งที่ใช้ในการเผยแพร่ข้อความ

PUBLISH channel message

ผู้ติดตามทุกคนที่ฟังในช่องจะได้รับข้อความ หากผู้ที่ไม่มีสมาชิกอยู่ใกล้เพื่อรับข้อความ ข้อความก็จะหายไป

ตัวอย่าง Node.js

หลังจากสร้างการเชื่อมต่อปกติกับ Redis แล้ว คุณสามารถใช้การเผยแพร่ได้เหมือนกับคำสั่งอื่นๆ:

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

การใช้กับคำสั่ง Redis อื่นๆ

การเผยแพร่ข้อมูลไปยังแชนเนลเป็นการดำเนินการที่รวดเร็ว ดังนั้นจึงมักใช้ควบคู่กับการดำเนินการอื่นๆ การรวมการดำเนินการเช่นนี้จะช่วยปลดล็อกพลังของ 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();

นี่เป็นการดำเนินการเดียวกับตัวอย่างก่อนหน้านี้สำหรับระบบ pub/sub แต่อยู่ใน MULTI/EXEC เดียวกัน ธุรกรรมอุณหภูมิจะถูกผลักไปยังรายการที่เก็บอุณหภูมิล่าสุด 100 รายการ

ตัวอย่างสั้นๆ นี้แสดงวิธีการรวม Redis pub/sub เข้ากับการออกแบบระบบที่ใหญ่ขึ้นซึ่งมีประวัติข้อความ การดำเนินการในลักษณะเดียวกับด้านบนช่วยให้ลูกค้ารายอื่นสามารถค้นหาค่าล่าสุดและสมัครรับค่าใหม่ได้

การสมัครรับข้อความ

ไวยากรณ์คำสั่ง

SUBSCRIBE คำสั่งใช้สำหรับสมัครสมาชิกช่อง คำสั่งนี้ทำให้ไคลเอ็นต์อยู่ในสถานะพิเศษ "สมัครรับข้อมูล" ซึ่งจะไม่ส่งคำสั่งอื่นนอกเหนือจาก SUBSCRIBE เพิ่มเติมอีกต่อไป หรือ UNSUBSCRIBE คำสั่ง

SUBSCRIBE channel [channel ...]

ตัวอย่าง Node.js

สมาชิกนี้สามารถใช้กับตัวอย่างผู้เผยแพร่ก่อนหน้านี้:

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");

สิ่งนี้ใช้ตัวปล่อยเหตุการณ์อย่างง่ายซึ่งเรียกใช้ฟังก์ชันทุกครั้งที่มีข้อความมาถึง ฟังก์ชันการจัดการจะบันทึกอุณหภูมิไปที่คอนโซลทันที ซึ่งสามารถทำได้ทุกอย่าง

การใช้คำสั่งอื่นกับสมาชิก

ดังที่กล่าวไว้ก่อนหน้านี้ ไคลเอนต์ที่สมัครสมาชิกอยู่ในโหมดพิเศษและไม่สามารถใช้กับคำสั่งอื่นได้ หากต้องการใช้คำสั่งอื่น คุณจะต้องสร้างการเชื่อมต่อไคลเอ็นต์แยกต่างหากกับ 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");

ตัวจัดการนี้บันทึกข้อความไปยังคอนโซลและเพิ่มตัวนับ Redis ในบางกรณี คุณอาจคำนวณผลลัพธ์แล้วเผยแพร่ผลลัพธ์นั้นเพื่อแยกช่องให้สมาชิกคนอื่นอ่าน - อย่าเผยแพร่กลับไปที่ช่องเดียวกันกับที่คุณกำลังฟังอยู่ เพราะคุณจะทำให้เกิดการวนซ้ำไม่รู้จบ :)

การจับคู่รูปแบบ

ไวยากรณ์คำสั่ง

SUBSCRIBE คำสั่งใช้สำหรับจับคู่รูปแบบช่องสัญญาณ

PSUBSCRIBE pattern [pattern ...]

ใช้งานได้เหมือนกับ SUBSCRIBE . ปกติ คำสั่ง แต่อนุญาตให้คุณจับคู่ช่องที่มีชื่อที่ตรงกับรูปแบบ ซึ่งช่วยให้ผู้เผยแพร่โฆษณาระบุข้อมูลที่เผยแพร่ได้เฉพาะเจาะจงมาก และช่วยให้สมาชิกสามารถฟังช่องต่างๆ ได้โดยไม่ทราบชื่อที่แน่ชัด

รูปแบบที่รองรับนั้นเรียบง่าย:* ตรงกับอักขระใดๆ ? จับคู่อักขระตัวเดียว และวงเล็บเหลี่ยมสามารถใช้จับคู่ชุดอักขระที่ยอมรับได้ เช่น [acd] .

จับคู่การอ่านอุณหภูมิจากหลายห้อง:

PSUBSCRIBE temp-reading:*

จับคู่เหตุการณ์จากการทดสอบ A/B เช่น site-link:logo:a:clickrate และsite-link:logo:b:clickrate :

PSUBSCRIBE site-link:logo:?:clickrate

จับคู่เหตุการณ์ระหว่างชุดของอินสแตนซ์ AWS สำหรับกิจกรรมที่เผยแพร่ เช่นsystem-health:us-east-1a:i-36a44b83 และ system-health:us-east-1c:i-73657420636f636f6 :

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

ตัวอย่าง Node.js

ในตัวอย่างนี้ ซึ่งสามารถใช้กับตัวอย่างการเผยแพร่ก่อนหน้านี้ได้ อุณหภูมิจะถูกบันทึกพร้อมกับห้องที่อ่านอุณหภูมิ

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:*");

ผู้ติดตามตามรูปแบบจะได้รับรายละเอียดเพิ่มเติมเล็กน้อยในการเรียกกลับ ไม่เพียงแต่ช่องและข้อความเท่านั้น แต่ยังรวมถึงรูปแบบเฉพาะที่ตรงกัน เนื่องจากผู้ติดตามสามารถฟังได้หลายช่องหรือหลายรูปแบบ

หมายเหตุด้านข้าง:ลักษณะประสิทธิภาพของ PUBLISH

ทุกคำสั่งใน Redis มีความซับซ้อนของเวลาที่บันทึกไว้ และเวลาส่วนใหญ่ความซับซ้อนเหล่านี้จะเป็นไปตามสัญชาตญาณ ตั้งแต่ PUBLISH การดำเนินการรู้สึกง่ายมาก (เกือบจะเหมือน SET ) หนึ่งอาจถือว่าความซับซ้อนของมันคือ O(1) อันที่จริงความซับซ้อนของเวลาของ PUBLISH เติบโตเป็นเส้นตรงตามพฤติกรรมของสมาชิก

เมื่อ PUBLISH คำสั่งรันจะต้องผ่านทุกรูปแบบที่สมัครรับซึ่งอาจตรงกับช่อง และ สมาชิกทั้งหมดที่ควรได้รับข้อความ ส่งผลให้ O(N+M) มีความซับซ้อนด้านเวลา

การปรับใช้ส่วนใหญ่จะไม่มีปัญหาด้านประสิทธิภาพกับความซับซ้อนของ PUBLISH แต่การติดตามประสิทธิภาพของคำสั่งนั้นเมื่อเวลาผ่านไปยังคงเป็นเรื่องที่ฉลาด – ระวังหากโค้ดของคุณสร้างรูปแบบของช่องที่จะรับฟังโดยอัตโนมัติ

รหัสของคุณที่นี่หรือไม่

เราอยากจะนำเสนอตัวอย่างที่ดีของแอปที่สร้างโดยใช้ Redis pub/sub หากคุณทราบตัวอย่างที่ดี ส่งข้อความมาที่[email protected] – เราจะพยายามอย่างเต็มที่เพื่อนำเสนอโค้ดบางส่วนที่เราเห็น