Expiration & TTL
ทำไม expiration ถึงสำคัญ
หัวข้อที่มีชื่อว่า “ทำไม expiration ถึงสำคัญ”Redis มักถูกใช้เป็น cache หรือที่เก็บ session ในทั้งสองกรณีคุณอยากให้ key หายไปเองหลังผ่านไประยะหนึ่ง — คุณไม่ควรต้องเขียน cleanup job เอง Redis จัดการเรื่องนี้ให้แบบ native ผ่าน key expiration
การตั้งค่า expiration
หัวข้อที่มีชื่อว่า “การตั้งค่า expiration”คุณสามารถแนบ TTL (time-to-live) ตอนสร้าง key หรือเพิ่มเข้าไปกับ key ที่มีอยู่แล้วก็ได้:
| Command | คำอธิบาย |
|---|---|
SET key val EX secs | สร้าง + หมดอายุเป็นวินาที |
SET key val PX ms | สร้าง + หมดอายุเป็นมิลลิวินาที |
EXPIRE key secs | ตั้ง/อัปเดต expiry เป็นวินาทีกับ key ที่มีอยู่ |
PEXPIRE key ms | ตั้ง/อัปเดต expiry เป็นมิลลิวินาที |
EXPIREAT key unix-secs | หมดอายุที่ Unix timestamp แบบสัมบูรณ์ (วินาที) |
PEXPIREAT key unix-ms | หมดอายุที่ Unix timestamp แบบสัมบูรณ์ (มิลลิวินาที) |
127.0.0.1:6379> SET session:abc "user:42" EX 300OK127.0.0.1:6379> TTL session:abc(integer) 299127.0.0.1:6379> SET cache:home "<html>...</html>"OK127.0.0.1:6379> EXPIRE cache:home 60(integer) 1127.0.0.1:6379> TTL cache:home(integer) 59SET session:abc "user:42" EX 300
TTL session:abc
SET cache:home "<html>...</html>"
EXPIRE cache:home 60
TTL cache:homeTTL และ PTTL — ตรวจเวลาที่เหลือ
หัวข้อที่มีชื่อว่า “TTL และ PTTL — ตรวจเวลาที่เหลือ”TTL คืนค่าเป็นวินาที ส่วน PTTL คืนค่าเป็นมิลลิวินาที ทั้งคู่มีค่าคืนพิเศษอยู่สองค่า:
-1— key มีอยู่แต่ ไม่มี expiry (เป็น persistent)-2— key ไม่มีอยู่ (หรือหมดอายุไปแล้ว)
127.0.0.1:6379> SET persistent "I live forever"OK127.0.0.1:6379> TTL persistent(integer) -1127.0.0.1:6379> TTL nonexistent:key(integer) -2127.0.0.1:6379> SET brief "gone soon" PX 5000OK127.0.0.1:6379> PTTL brief(integer) 4987SET persistent "I live forever"
TTL persistent
TTL nonexistent:key
SET brief "gone soon" PX 5000
PTTL briefPERSIST — ลบ expiration ออก
หัวข้อที่มีชื่อว่า “PERSIST — ลบ expiration ออก”ถ้าคุณอยากยกเลิก expiry ของ key แล้วทำให้ key กลับมา persistent อีกครั้ง ให้ใช้ PERSIST:
127.0.0.1:6379> SET promo "SALE10" EX 3600OK127.0.0.1:6379> TTL promo(integer) 3599127.0.0.1:6379> PERSIST promo(integer) 1127.0.0.1:6379> TTL promo(integer) -1SET promo "SALE10" EX 3600
TTL promo
PERSIST promo
TTL promoจริง ๆ แล้ว Redis ลบ key ที่หมดอายุอย่างไร
หัวข้อที่มีชื่อว่า “จริง ๆ แล้ว Redis ลบ key ที่หมดอายุอย่างไร”Redis ใช้สองกลยุทธ์ที่เสริมกัน — คุณไม่ต้องทำอะไรเลย แต่เข้าใจไว้ก็ช่วยให้คุณคิดเรื่อง memory ได้ดีขึ้น:
Lazy expiry — เมื่อคุณเข้าถึง key (GET, EXISTS ฯลฯ) Redis จะตรวจ expiry ของ key นั้นก่อน ถ้าหมดอายุแล้ว Redis จะลบทิ้งทันทีตรงนั้น และคืน (nil) ราวกับว่าไม่เคยมีอยู่
Active expiry — Redis รัน background cycle (ค่าเริ่มต้นประมาณ 10 ครั้งต่อวินาที) ที่สุ่มตัวอย่าง key ที่มี TTL และลบ key ที่หมดอายุออกไป วิธีนี้ป้องกันไม่ให้ keyspace เต็มไปด้วย key ที่ไม่เคยถูกเข้าถึง
สองกลยุทธ์นี้รวมกันช่วยให้การใช้ memory ถูกจำกัดอยู่ในขอบเขตโดยไม่ block แอปพลิเคชันของคุณ
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| ตัวเลือก | Benefit | Cost |
|---|---|---|
| ตั้ง TTL ให้ key ทุกตัวที่เป็น cache/session | memory ถูกล้างอัตโนมัติ ไม่ต้องเขียน cleanup job เอง | ถ้าคำนวณ TTL ผิดพลาด ข้อมูลอาจหายไปเร็วเกินไปทั้งที่ระบบยังต้องใช้อยู่ |
| พึ่งพา lazy expiry (ตรวจตอนเข้าถึง key) | ไม่มี overhead เพิ่มถ้าไม่มีใครอ่าน key นั้นเลย | key ที่หมดอายุแต่ไม่มีใครเข้าถึงจะยังกิน memory ค้างอยู่จนกว่า active expiry cycle จะมาเจอ |
ใช้ PERSIST ยกเลิก TTL ของ key ที่เคยตั้งไว้ | ยืดอายุข้อมูลสำคัญได้โดยไม่ต้องสร้าง key ใหม่ | เสี่ยงลืมว่า key นั้นเคยตั้งใจให้เป็นข้อมูลชั่วคราว ทำให้ memory โตแบบไม่มีการล้าง |
ข้อผิดพลาดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ข้อผิดพลาดที่พบบ่อย”- เช็ก
TTL key == 0เพื่อตรวจว่า key หายไปหรือไม่ — ค่าที่ถูกต้องสำหรับ key ที่ไม่มีอยู่คือ-2ไม่ใช่0เพราะ TTL จะไม่มีวันค้างอยู่ที่ศูนย์ ต้องแยกเงื่อนไข-2(ไม่มีอยู่) กับ-1(persistent) ให้ถูกต้อง - ลืมตั้ง TTL ให้ key ที่ควรเป็นข้อมูลชั่วคราว — ถ้า
SETcache หรือ session โดยไม่ผูกEX/PXเลย ข้อมูลจะกลายเป็น persistent และสะสมจนmaxmemoryเต็ม - สับสนระหว่าง
EXPIRE(relative) กับEXPIREAT(absolute timestamp) — ใช้ผิดตัวจะทำให้ TTL คลาดเคลื่อนจากที่ตั้งใจ โดยเฉพาะเมื่อ clock ของ client กับ server ไม่ตรงกัน
💡 ตัวอย่างจากของจริง
Twitter timeline cache — ผูก TTL กับ key แคช timeline เพื่อให้ข้อมูลเก่าถูกล้างอัตโนมัติ แล้ว regenerate ใหม่จาก source of truth เมื่อมีคน request เข้ามาหลัง cache หมดอายุ
Stack Overflow — ใช้ TTL กับ session key เพื่อ log out ผู้ใช้อัตโนมัติหลังไม่มี activity ในช่วงเวลาที่กำหนด แทนที่จะต้องมี background job มาลบ session เก่า