Keyspace Notifications
Keyspace Notifications คืออะไร?
หัวข้อที่มีชื่อว่า “Keyspace Notifications คืออะไร?”Redis สามารถ publish ข้อความ Pub/Sub ได้ทุกครั้งที่เกิด event บางอย่าง — เช่น key หมดอายุ, มีการรัน SET, มีการรัน DEL และอื่น ๆ แอปพลิเคชันของคุณ subscribe ช่องทางเหล่านี้เพื่อตอบสนองโดยไม่ต้อง polling: ตัวอย่างเช่น ล้าง local cache เมื่อ key หมดอายุ หรือเรียก background job เมื่อมีการเขียน key เฉพาะ
Redis เปิดเผยช่องทาง 2 ประเภท:
- Keyevent channels — หนึ่งช่องทางต่อประเภท event; payload ของข้อความคือชื่อ key รูปแบบ:
__keyevent@<db>__:<event>(ตัวอย่าง:__keyevent@0__:expired) - Keyspace channels — หนึ่งช่องทางต่อ key; payload ของข้อความคือประเภท event รูปแบบ:
__keyspace@<db>__:<keyname>
การเปิดใช้งาน Keyspace Notifications
หัวข้อที่มีชื่อว่า “การเปิดใช้งาน Keyspace Notifications”Keyspace notifications ถูกปิดใช้งานโดยค่าเริ่มต้น เนื่องจากการ publish ทุก event จะเพิ่มภาระ CPU เปิดใช้งานด้วย CONFIG SET ขณะรันไทม์ หรือผ่าน redis.conf เมื่อเริ่มต้น
ค่าที่กำหนดคือสตริงของอักขระ flag ที่เลือกว่าจะ publish event class ใดบ้าง:
| Flag | Events ที่เปิดใช้งาน |
|---|---|
K | Keyspace events (ช่องทาง __keyspace@...) |
E | Keyevent events (ช่องทาง __keyevent@...) |
x | Expired events (TTL ของ key ถึงศูนย์) |
g | คำสั่งทั่วไป: DEL, EXPIRE, RENAME, … |
s | คำสั่ง Set (SADD, SREM, …) |
l | คำสั่ง List (LPUSH, RPOP, …) |
สำหรับ expiry notifications ใน production การตั้งค่าที่นิยมใช้คือ Ex — keyevent channel (E) สำหรับ expired events เท่านั้น (x):
notify-keyspace-events "Ex"หรือขณะรันไทม์:
127.0.0.1:6379> CONFIG SET notify-keyspace-events ExOKการ Subscribe รับ expiry events
หัวข้อที่มีชื่อว่า “การ Subscribe รับ expiry events”Keyspace notifications ใช้การทำงานแบบสอง terminal เปิด Terminal 1 และ subscribe ก่อนที่ key จะหมดอายุ:
127.0.0.1:6379> PSUBSCRIBE __keyevent@0__:expiredReading messages... (press Ctrl-C to quit)ใน Terminal 2 กำหนด key ที่มี TTL สั้น ๆ เพื่อ trigger event:
127.0.0.1:6379> SET demo:token "abc" EX 3OKหลังจาก 3 วินาที Terminal 1 จะได้รับการแจ้งเตือน:
1) "pmessage"2) "__keyevent@0__:expired"3) "__keyevent@0__:expired"4) "demo:token"บรรทัดที่สี่คือชื่อ key — ตอนนี้ subscriber ของคุณรู้แน่ชัดว่า key ไหนหมดอายุ
คำสั่งที่รันได้
หัวข้อที่มีชื่อว่า “คำสั่งที่รันได้”คำสั่งด้านล่างเปิดใช้งาน notifications และกำหนด key ที่มี TTL เพื่อให้คุณสังเกตการกำหนดค่าในการทำงาน หากต้องการดู expired event ให้เปิด redis-cli ตัวที่สอง รัน PSUBSCRIBE __keyevent@0__:expired จากนั้นใน terminal แรกรัน SET demo:token "hello" EX 5 แล้วรอ 5 วินาที
CONFIG SET notify-keyspace-events Ex
SET demo:token "hello" EX 5
TTL demo:tokenเนื่องจาก Pub/Sub ต้องการสอง connections พร้อมกัน ให้ทำ workflow สอง terminal ในสภาพแวดล้อม redis-cli ของคุณเองเพื่อดู expired event ในแบบ real time
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
Keyevent channel เฉพาะ event ที่ใช้ (เช่น Ex) | overhead ต่ำ เปิดเฉพาะสิ่งที่จำเป็น | ต้องเลือก flag ให้ครบ ไม่ครอบคลุมเหตุการณ์อื่นที่อาจต้องใช้ทีหลัง |
Flag กว้าง เช่น KEA (ทุก event) | ครอบคลุมทุกกรณีโดยไม่ต้องแก้ config เพิ่ม | เพิ่มภาระ CPU ที่วัดได้บน workload ที่เขียนหนัก เพราะ publish ทุก event |
| Pub/Sub-based notification แทน polling | ไม่ต้อง query ซ้ำ ๆ ลด load บน server | Pub/Sub ไม่มี delivery guarantee — ถ้า subscriber ไม่ได้ online ตอน event เกิด ข้อความนั้นหายไปเลย |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- เข้าใจผิดว่า
expiredevent ส่งมาทันทีที่ TTL หมดพอดี — Redis ใช้ lazy expiry (ตรวจตอนเข้าถึง key) ผสมกับ active expiry (สุ่มตรวจเป็นรอบ) เวลาที่ event ถูก publish จริงอาจช้ากว่าเวลาที่ TTL หมดเล็กน้อย ไม่ควรใช้เป็นนาฬิกาที่แม่นยำ - พึ่งพา keyspace notification เป็นกลไก reliable messaging — Pub/Sub ไม่เก็บ history และไม่ redeliver หาก subscriber หลุดการเชื่อมต่อชั่วขณะ event ที่เกิดระหว่างนั้นจะหายไปถาวร ถ้าต้องการ delivery guarantee ควรใช้ Streams แทน
- เปิด flag
KEAแบบ catch-all ใน production โดยไม่จำเป็น — การ publish ทุก event บน workload ที่เขียนหนักเพิ่มภาระ CPU อย่างมีนัยสำคัญ ควรเปิดเฉพาะ event class ที่แอปใช้งานจริง
💡 ตัวอย่างจากของจริง
E-commerce cart abandonment — ระบบ e-commerce หลายเจ้าใช้
expiredkeyspace event เพื่อ trigger การส่งอีเมลเตือนเมื่อ cart session หมดอายุโดยไม่มีการ checkoutSession cleanup services — บริการที่เก็บ session ใน Redis ใช้ keyspace notification เพื่อล้าง cache ฝั่ง application หรือ log-out ผู้ใช้จากระบบอื่นทันทีที่ session key หมดอายุ แทนที่จะต้อง polling ตรวจสอบเป็นระยะ