Pub/Sub
Pub/Sub ทำงานอย่างไร
หัวข้อที่มีชื่อว่า “Pub/Sub ทำงานอย่างไร”Redis Pub/Sub ทำตาม pattern publish-subscribe แบบคลาสสิก:
- Client เรียก
SUBSCRIBE channelและเข้าสู่โหมดฟัง ไม่สามารถออกคำสั่งปกติได้อีกต่อไป — จะรับแต่ push message จาก Redis เท่านั้น - Client อื่นใดเรียก
PUBLISH channel messageRedis จะส่งต่อข้อความนั้นไปยัง subscriber ที่เชื่อมต่ออยู่ทุกคนของ channel นั้นทันที - ข้อความไม่เคยถูกเก็บไว้ หากไม่มี subscriber เชื่อมต่ออยู่ ข้อความจะถูกทิ้งอย่างเงียบ ๆ หาก subscriber เชื่อมต่ออยู่เมื่อสิบวินาทีก่อนแต่ตัดการเชื่อมต่อไปแล้ว จะไม่ได้รับอะไรเลย
แต่ละ channel เป็นแค่ชื่อ — Redis สร้างและลบ channel โดยปริยายเมื่อ subscriber มาและไป ไม่จำเป็นต้องสร้าง channel ก่อน publish
SUBSCRIBE และ PUBLISH — การสาธิตสองเทอร์มินัล
หัวข้อที่มีชื่อว่า “SUBSCRIBE และ PUBLISH — การสาธิตสองเทอร์มินัล”การโต้ตอบด้านล่างต้องใช้ session redis-cli สองอันที่รันพร้อมกัน เริ่ม Terminal 1 ก่อน แล้วส่งจาก Terminal 2
# Terminal 1 — subscriber127.0.0.1:6379> SUBSCRIBE newsReading messages... (press Ctrl-C to quit or any command to unsubscribe)1) "subscribe"2) "news"3) (integer) 1
# Terminal 2 — publisher (in a second redis-cli session)127.0.0.1:6379> PUBLISH news "Breaking: Redis is fast"(integer) 1
# Back in Terminal 1 — message arrives automatically1) "message"2) "news"3) "Breaking: Redis is fast"ข้อความยืนยันที่ Redis ส่งกลับไปยัง subscriber เมื่อ SUBSCRIBE มีสามส่วน:
| ส่วน | ค่า | ความหมาย |
|---|---|---|
| 1 | "subscribe" | ประเภท event |
| 2 | "news" | ชื่อ channel |
| 3 | (integer) 1 | จำนวน channel ทั้งหมดที่ client นี้ subscribe อยู่ขณะนี้ |
ข้อความที่ publish มาถึงก็มีสามส่วนเช่นกัน: ประเภท event "message", ชื่อ channel และ payload
ตัวเลขที่ PUBLISH คืนกลับมาคือจำนวน subscriber ที่ได้รับข้อความ ค่าที่คืนมาเป็น 0 หมายความว่าไม่มีใครฟังอยู่
PUBLISH news "Breaking: Redis is fast"
PUBLISH news "Another update"UNSUBSCRIBE
หัวข้อที่มีชื่อว่า “UNSUBSCRIBE”เพื่อออกจาก channel client ที่ subscribe อยู่จะส่ง UNSUBSCRIBE คุณสามารถระบุชื่อ channel เฉพาะหรือละเว้นชื่อ channel เพื่อ unsubscribe จากทุก channel พร้อมกันในครั้งเดียว
# Unsubscribe from one channel127.0.0.1:6379> UNSUBSCRIBE news1) "unsubscribe"2) "news"3) (integer) 0
# Unsubscribe from all channels (no argument)127.0.0.1:6379> UNSUBSCRIBE1) "unsubscribe"2) (nil)3) (integer) 0เมื่อจำนวนการ subscribe ลดเหลือ 0 client จะออกจากโหมดฟังและสามารถออกคำสั่งปกติได้อีกครั้ง
SUBSCRIBE หลายช่องพร้อมกัน
หัวข้อที่มีชื่อว่า “SUBSCRIBE หลายช่องพร้อมกัน”การเรียก SUBSCRIBE ครั้งเดียวรับชื่อ channel ได้หลายชื่อ client จะรับข้อความจากทุก channel บน connection เดียวกัน
127.0.0.1:6379> SUBSCRIBE sports weather finance1) "subscribe"2) "sports"3) (integer) 11) "subscribe"2) "weather"3) (integer) 21) "subscribe"2) "finance"3) (integer) 3Redis ส่งการตอบกลับยืนยันหนึ่งครั้งต่อ channel ฟิลด์ที่สามจะเพิ่มขึ้นเมื่อเพิ่มการ subscribe แต่ละครั้ง แสดงผลรวมที่ทำงานอยู่
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| Pub/Sub แบบ fire-and-forget | latency ต่ำมาก ไม่มี overhead ของการเก็บ log ลงดิสก์ | ข้อความหายถาวรถ้าไม่มี subscriber เชื่อมต่ออยู่ตอนนั้น ไม่มีทาง replay |
| SUBSCRIBE หลาย channel บน connection เดียว | ลดจำนวน connection ที่ต้องเปิดกับ Redis | client อยู่ในโหมดฟังทั้ง connection รันคำสั่งอื่นบน connection เดียวกันไม่ได้จนกว่าจะ unsubscribe |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- ใช้ Pub/Sub ส่งข้อความที่ต้องรับประกันการส่งถึง — เช่น order confirmation หรือ payment event หาก consumer offline ชั่วครู่ข้อความจะหายไปเลย ควรใช้ Streams แทนเมื่อข้อความสำคัญห้ามสูญหาย
- ลืมว่า client ที่ SUBSCRIBE อยู่ใช้คำสั่งทั่วไปไม่ได้ — connection จะเข้าสู่โหมดฟังทันที เรียก
GET/SETบน connection เดียวกันไม่ได้ ต้องเปิด connection แยกสำหรับ publish - ไม่ตรวจสอบค่าที่
PUBLISHคืนมา — ค่า0แปลว่าไม่มี subscriber รับข้อความเลย ถ้าไม่เช็คค่านี้จะไม่รู้ตัวว่าข้อความหายไปเงียบ ๆ
💡 ตัวอย่างจากของจริง
แชทแอป — ใช้ Pub/Sub ส่งสถานะ “กำลังพิมพ์…” (typing indicator) เพราะข้อมูลนี้ล้าสมัยเร็วและยอมให้หายได้หาก subscriber ไม่ทัน
Dashboard แบบ real-time — ใช้ Pub/Sub กระจาย metric ที่อัปเดตทุกวินาทีไปยังหน้าเว็บที่เปิดอยู่หลายแท็บพร้อมกัน โดยไม่สนใจ event ที่พลาดไปเพราะค่าถัดไปจะมาเร็ว