Redis
Redis เป็นฐานข้อมูลประเภท In-memory (จัดเก็บข้อมูลในหน่วยความจำหลัก) ที่ออกแบบมาให้มีความเร็วสูง เหมาะกับการใช้งานในสถาปัตยกรรมที่ต้องการประสิทธิภาพสูง ทั้งในด้านการอ่านและเขียนข้อมูล Redis มีการจัดเก็บข้อมูลในรูปแบบ Key-Value
คุณสมบัติเด่นของ Redis
ความเร็วสูง: เนื่องจาก Redis จัดเก็บข้อมูลในหน่วยความจำหลัก (RAM) ทำให้การเข้าถึงข้อมูลทำได้อย่างรวดเร็วมาก การตอบสนองสามารถทำได้ในระดับไม่กี่มิลลิวินาที (milliseconds)
การสนับสนุนโครงสร้างข้อมูลหลายรูปแบบ: Redis ไม่ได้จำกัดการจัดเก็บข้อมูลในรูปแบบ Key-Value แบบธรรมดาเท่านั้น แต่ยังรองรับโครงสร้างข้อมูลอื่น ๆ เช่น Lists (รายการ), Sets (เซ็ต), Hashes (แฮช), และ Sorted Sets (เซ็ตที่เรียงลำดับ)
รองรับการทำงานแบบ Persistent: แม้ว่า Redis จะจัดเก็บข้อมูลในหน่วยความจำ แต่ยังสามารถตั้งค่าให้จัดเก็บข้อมูลลงบนดิสก์ (Disk) ได้ โดยใช้เทคนิคเช่น RDB (Redis Database Backup) หรือ AOF (Append Only File) เพื่อให้แน่ใจว่าข้อมูลจะไม่สูญหายเมื่อต้องปิดเครื่องหรือรีสตาร์ทเซิร์ฟเวอร์
การรองรับ Pub/Sub (Publish/Subscribe): Redis ยังสามารถใช้ในการสื่อสารระหว่างบริการต่าง ๆ ได้ โดยใช้การกระจายข้อมูลผ่านโมเดล Pub/Sub ซึ่งทำให้เหมาะสำหรับงานที่ต้องการส่งข้อความหรือสตรีมข้อมูลแบบเรียลไทม์
Replication และ High Availability: Redis รองรับการทำงานแบบ Repllication ซึ่งช่วยในการทำสำเนาข้อมูลระหว่างเซิร์ฟเวอร์ต่าง ๆ เพื่อเพิ่มความทนทาน (resilience) ต่อการสูญหายของข้อมูล นอกจากนี้ Redis ยังมี Redis Sentinel ที่ช่วยในการจัดการการ failover และ Redis Cluster ที่ช่วยในการขยายระบบให้รองรับข้อมูลและปริมาณการประมวลผลได้มากขึ้น
Use Case ที่พบได้ทั่วไปของ Redis
Session Store: ระบบที่มีผู้ใช้งานจำนวนมากมักจะใช้ Redis ในการจัดเก็บข้อมูลการเข้าสู่ระบบของผู้ใช้ เนื่องจาก Redis สามารถดึงข้อมูลได้รวดเร็วมาก เหมาะกับการใช้งานแบบเรียลไทม์
Cache: ในกรณีที่มีการดึงข้อมูลจากฐานข้อมูลที่ต้องการความเร็วสูง Redis มักจะถูกนำมาใช้เป็นตัวกลางในการ Cache ข้อมูล ทำให้ลดภาระการเรียกใช้ฐานข้อมูลหลัก
Message Queue: ในระบบที่ต้องการสื่อสารระหว่างหลาย ๆ บริการ Redis ถูกใช้เป็น Message Broker โดยใช้ฟีเจอร์ Pub/Sub ในการจัดการการส่งข้อมูลระหว่างโปรแกรมหรือ microservices ต่าง ๆ
การจัดเก็บข้อมูลใน Redis
Redis มีสองวิธีหลักในการจัดการการบันทึกข้อมูลลงดิสก์เพื่อความปลอดภัยและความทนทานต่อการสูญหายของข้อมูล ซึ่งสองวิธีนี้คือ AOF (Append Only File) และ RDB (Redis Database Backup) ซึ่งแต่ละวิธีมีข้อดีข้อเสียที่แตกต่างกัน
RDB (Redis Database Backup)
RDB คือการบันทึกข้อมูลในรูปแบบ Snapshot ซึ่งจะทำการบันทึกข้อมูลทั้งหมดในช่วงเวลาที่กำหนดลงเป็นไฟล์ .rdb
การบันทึกแบบ RDB เหมาะสำหรับกรณีที่คุณไม่ต้องการให้ Redis ทำงานเขียนไฟล์บ่อยครั้ง ซึ่งจะช่วยลดภาระของการ I/O บนดิสก์ และยังทำให้การเริ่มต้น Redis ใหม่ทำได้อย่างรวดเร็ว
ข้อดีของ RDB
ประสิทธิภาพสูง: RDB จะทำการบันทึกข้อมูลเป็นช่วงๆ (ไม่บันทึกทุกครั้งที่มีการเปลี่ยนแปลง) ทำให้การทำงานหลักของ Redis (เช่นการอ่าน-เขียนข้อมูลในหน่วยความจำ) ทำได้รวดเร็วมาก
ไฟล์มีขนาดเล็ก: เนื่องจากเป็นการบันทึก Snapshot ของข้อมูลทั้งหมดในเวลาที่กำหนด ทำให้ไฟล์
.rdb
มักจะมีขนาดเล็กกว่าไฟล์ AOFการกู้คืนรวดเร็ว: หาก Redis ต้องรีสตาร์ทหรือเกิดการ crash ระบบสามารถโหลดไฟล์
.rdb
และกู้คืนข้อมูลได้อย่างรวดเร็ว
ข้อเสียของ RDB
ความเสี่ยงในการสูญหายของข้อมูล: เนื่องจาก RDB ทำการบันทึกข้อมูลตามช่วงเวลา (ไม่บันทึกทุกครั้งที่มีการเปลี่ยนแปลง) ข้อมูลที่ถูกเพิ่มเข้ามาหลังจากช่วงบันทึกล่าสุดอาจจะสูญหายได้ หากระบบเกิด crash ก่อนการบันทึกครั้งต่อไป
การสร้าง Snapshot อาจใช้ทรัพยากรมาก: ในบางกรณี การบันทึกข้อมูลขนาดใหญ่เป็น Snapshot อาจใช้ทรัพยากร CPU และหน่วยความจำมาก ทำให้ประสิทธิภาพของ Redis ลดลงชั่วคราว
AOF (Append Only File)
AOF เป็นวิธีการบันทึกการเปลี่ยนแปลงของคำสั่ง Redis ลงดิสก์ทุกครั้ง (append) ซึ่งการทำงานของ AOF จะบันทึกคำสั่งทุกคำสั่งที่ Redis ได้รับและทำงาน (เช่น SET, DEL) ลงไปในไฟล์แบบเรียงลำดับ เมื่อมีการรีสตาร์ท Redis ระบบจะทำการเล่นคำสั่งเหล่านั้นซ้ำเพื่อกู้คืนข้อมูลทั้งหมดกลับมา
ข้อดีของ AOF
ความทนทานของข้อมูลสูงกว่า: เนื่องจาก AOF บันทึกการเปลี่ยนแปลงทุกคำสั่ง ทำให้มีโอกาสสูญหายของข้อมูลน้อยกว่าเมื่อเทียบกับ RDB โดยคุณสามารถตั้งค่าการบันทึกแบบ AOF ให้บันทึกทุกคำสั่ง (Always) หรือบันทึกทุกช่วงเวลาที่กำหนด (Everysec) ได้
อ่านง่าย: ไฟล์ AOF เป็นบันทึกของคำสั่ง Redis แบบเรียงตามลำดับเวลา ทำให้สามารถเปิดอ่านและตรวจสอบคำสั่งย้อนหลังได้ง่าย
รองรับการใช้ Disk ที่มีความเร็วต่ำ: เนื่องจากการบันทึกคำสั่งทำทีละบรรทัด การใช้งาน AOF ไม่จำเป็นต้องใช้ดิสก์ที่มีความเร็วสูง
ข้อเสียของ AOF
ไฟล์มีขนาดใหญ่: เนื่องจาก AOF บันทึกคำสั่งทุกคำสั่ง การเติบโตของไฟล์อาจรวดเร็วและขนาดของไฟล์อาจจะใหญ่กว่า RDB มาก
กระบวนการบีบอัดไฟล์ (Rewrite): เนื่องจากไฟล์ AOF อาจโตเร็ว Redis จึงต้องทำการบีบอัดไฟล์เพื่อลดขนาด ซึ่งกระบวนการนี้อาจกินทรัพยากร CPU และหน่วยความจำ
ความเร็วในการกู้คืนช้ากว่า RDB: เนื่องจากการกู้คืนข้อมูลจาก AOF ต้องทำการเล่นคำสั่งทั้งหมดซ้ำตั้งแต่ต้น ทำให้การกู้คืนช้ากว่าการโหลดไฟล์ Snapshot แบบ RDB
อย่างไรก็ตาม Redis อนุญาตใช้ทั้ง RDB และ AOF พร้อมกันได้ ซึ่งจะทำให้ได้ข้อดีของทั้งสองแบบ
การกู้คืนจะมีขั้นตอนดังนี้
เมื่อ Redis เริ่มต้นทำงาน หากเปิดใช้ทั้ง RDB และ AOF, Redis จะทำการโหลดไฟล์ RDB ก่อน เพราะการโหลด RDB ทำได้รวดเร็วกว่า เนื่องจากเป็นการบันทึกข้อมูลทั้งระบบใน snapshot เดียว
หลังจากโหลดข้อมูลจาก RDB เสร็จแล้ว Redis จะอ่านไฟล์ AOF เพื่อตามให้ทันการเปลี่ยนแปลงที่เกิดขึ้นหลังจากการบันทึก RDB ครั้งล่าสุด
พื้นที่เก็บช้อมูล
ไฟล์ AOF จะเก็บเฉพาะคำสั่งที่ Redis ได้รับหลังจากการบันทึก snapshot ของ RDB ครั้งล่าสุด ดังนั้น RDB จะทำหน้าที่เก็บข้อมูล snapshot ขนาดใหญ่ ในขณะที่ AOF จะเก็บรายละเอียดการเปลี่ยนแปลงทั้งหมดตั้งแต่ snapshot ครั้งล่าสุด
ตัวอย่าง config redis.conf
เมื่อเปิด RDB และ AOF ร่วมกัน
# เปิดใช้งาน RDB
save 900 1 # บันทึก RDB ทุก 15 นาทีถ้ามีการเปลี่ยนแปลงอย่างน้อย 1 ครั้ง
save 300 10 # บันทึกทุก 5 นาทีถ้ามีการเปลี่ยนแปลง 10 ครั้ง
save 60 10000 # บันทึกทุก 1 นาทีถ้ามีการเปลี่ยนแปลง 10000 ครั้ง
# เปิดใช้งาน AOF
appendonly yes
# ปรับโหมด AOF ให้เขียนไฟล์ทุกวินาที
# สามารถเลือกใช้ always (ทุกครั้งที่มีการเปลี่ยนแปลง), everysec (ทุกวินาที), หรือ no (ไม่เปิดใช้)
appendfsync everysec
AOF Rewrite คืออะไร
AOF Rewrite เป็นกระบวนการที่ Redis ใช้ในการ บีบอัด (compact) ไฟล์ AOF (Append Only File) เพื่อให้มีขนาดเล็กลงและมีประสิทธิภาพในการจัดการพื้นที่ดิสก์มากขึ้น โดยที่ข้อมูลใน AOF ยังคงถูกต้องครบถ้วน
เมื่อ Redis ทำงานไปเรื่อย ๆ ไฟล์ AOF จะเติบโตขึ้นเรื่อย ๆ เนื่องจากทุกคำสั่งที่ Redis ได้รับและดำเนินการจะถูกบันทึกลงในไฟล์ AOF เพื่อให้สามารถกู้คืนข้อมูลทั้งหมดได้ แต่การเก็บคำสั่งทุกครั้งทำให้ไฟล์นี้อาจใหญ่ขึ้นอย่างรวดเร็ว และมีคำสั่งที่ไม่จำเป็น เช่น การอัปเดตข้อมูลที่เกิดขึ้นซ้ำ ๆ หลายครั้ง ซึ่งทำให้ AOF ไฟล์มีขนาดใหญ่กว่าความจำเป็นจริงๆ
AOF Rewrite จะทำหน้าที่สร้างไฟล์ AOF ใหม่โดยบันทึกเฉพาะสถานะปัจจุบันของข้อมูล (ซึ่งอาจเกิดจากหลายๆ คำสั่ง) และกำจัดคำสั่งที่ไม่จำเป็นออก เช่น การตั้งค่าค่าของ Key ซ้ำๆ ก็จะเหลือเพียงคำสั่งสุดท้ายเท่านั้น
ตัวอย่าง config เกี่ยวกับ AOF rewrite
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 100
: Redis จะทำการ Rewrite เมื่อขนาดของไฟล์ AOF เติบโตขึ้นมากกว่า 100% จากขนาดไฟล์ AOF ก่อนหน้าครั้งที่ทำ Rewrite
auto-aof-rewrite-min-size 64mb
: กำหนดขนาดขั้นต่ำของไฟล์ AOF ก่อนที่ Redis จะพิจารณาการ Rewrite (ในที่นี้คือขนาดต้องเกิน 64MB)
ดังนั้นจากตัวอย่างนี้ หากไฟล์ AOF เริ่มต้นมีขนาด 100MB และตั้งค่า auto-aof-rewrite-percentage
ไว้ที่ 100%, Redis จะเริ่มทำ AOF Rewrite เมื่อขนาดไฟล์เกิน 200MB (ซึ่งหมายถึงเติบโตขึ้นมาอีก 100% ของขนาดเดิม)
สรุปข้อดีของ AOF rewrite
ลดขนาดไฟล์: การบีบอัดไฟล์ช่วยลดขนาดของ AOF โดยเก็บเฉพาะคำสั่งที่จำเป็นและกำจัดคำสั่งซ้ำซ้อนที่ไม่จำเป็น
เพิ่มประสิทธิภาพการเขียนไฟล์: การเก็บข้อมูลในรูปแบบที่บีบอัดทำให้ Redis เขียนข้อมูลใหม่ๆ ลงไฟล์ AOF ได้เร็วขึ้น และทำให้การกู้คืนข้อมูลจาก AOF ทำได้รวดเร็วกว่า
กระทบต่อการทำงานน้อย: กระบวนการ AOF Rewrite เกิดขึ้นใน Process ย่อย ดังนั้น Redis ยังสามารถให้บริการได้โดยไม่กระทบต่อประสิทธิภาพหลัก
Maxmemory และ Eviction Policy
Maxmemory เป็นค่าที่กำหนดจำนวนหน่วยความจำสูงสุดที่ Redis สามารถใช้ได้ ซึ่งช่วยป้องกันไม่ให้ Redis ใช้หน่วยความจำมากเกินไปจนทำให้ระบบขาดเสถียรภาพ โดยเฉพาะในกรณีที่ Redis รันบนระบบที่มีหน่วยความจำจำกัด หาก Redis ใช้หน่วยความจำถึงค่า Maxmemory ที่กำหนดไว้ ระบบจะดำเนินการตาม Eviction Policy (นโยบายการลบข้อมูลออกจากหน่วยความจำ) เพื่อลบข้อมูลบางส่วนออกเพื่อเพิ่มพื้นที่สำหรับข้อมูลใหม่
ตัวอย่าง maxmemory
ใน redis.conf
maxmemory 2gb # กำหนดให้ Redis ใช้หน่วยความจำได้สูงสุด 2GB
Eviction Policy
เมื่อหน่วยความจำที่ Redis ใช้ถึงค่า maxmemory
ระบบจะทำการลบข้อมูลบางส่วนออกเพื่อลดการใช้หน่วยความจำตามนโยบายที่กำหนด
ซึ่งนโยบายการลบข้อมูลนี้เรียกว่า Eviction Policy มีหลายแบบดังนี้
noeviction (default) Redis จะไม่ลบข้อมูลใดๆ และเมื่อหน่วยความจำเต็ม Redis จะตอบกลับด้วยข้อผิดพลาดเมื่อมีการเพิ่มข้อมูลใหม่
allkeys-lru (Least Recently Used) ลบข้อมูลที่ไม่ได้ถูกเรียกใช้ล่าสุดออกจากฐานข้อมูลทั้งหมด (ทั้งที่มีและไม่มี TTL) เพื่อเพิ่มพื้นที่สำหรับข้อมูลใหม่
volatile-lru ลบข้อมูลที่มี TTL และไม่ได้ถูกใช้งานล่าสุดออกก่อน เพื่อรักษาข้อมูลที่ไม่มี TTL
allkeys-random ลบข้อมูลแบบสุ่มจากฐานข้อมูลทั้งหมดเมื่อหน่วยความจำเต็ม ไม่ว่าจะมี TTL หรือไม่
volatile-random ลบข้อมูลแบบสุ่มเฉพาะจากข้อมูลที่มี TTL ตั้งค่าไว้
volatile-ttl ลบข้อมูลที่มี TTL และใกล้หมดอายุก่อน เมื่อหน่วยความจำเต็ม
allkeys-lfu (Least Frequently Used) ลบข้อมูลที่ถูกเรียกใช้งานน้อยที่สุดจากฐานข้อมูลทั้งหมด
volatile-lfu ลบข้อมูลที่มี TTL และถูกใช้งานน้อยที่สุดก่อน
ตัวอย่าง setting ที่นิยม เช่น ตั้ง maxmemory
ไว้ที่ 75% ของ memory เครื่อง และใช้ policy volatile-lru
Last updated
Was this helpful?