Spring Boot Caching: การเลือกใช้ Local Cache และ Redis ให้เหมาะกับสเกลของระบบ
เข้าใจ Caching Strategy: เริ่มต้นอย่างไรและเมื่อไหร่ควรขยับไป Redis
การทำ Caching คือหนึ่งในวิธีที่คุ้มค่าที่สุดในการเพิ่ม Performance ให้กับ Application แต่ความท้าทายไม่ได้อยู่ที่การเขียนโค้ด แต่อยู่ที่การเลือก "ที่เก็บข้อมูล" (Storage) ให้เหมาะสมกับขนาดของระบบครับ
1. เริ่มต้นง่ายๆ ด้วย @Cacheable (Abstraction Layer)
Spring Boot ออกแบบมาให้เราโฟกัสที่ Business Logic โดยไม่ต้องกังวลเรื่อง Implementation มากนัก ด้วยการใช้ Annotation เพียงตัวเดียว
รูปแบบการใช้งานทั่วไป:
@Service
public class DashboardService {
// Spring จะช่วยจำค่าที่ Return จาก Method นี้ไว้
@Cacheable("dashboard_stats")
public DashboardStats getStats() {
// จำลองการ Query ที่ใช้เวลานาน (เช่น 3 วินาที)
return repository.calculateHeavyStats();
}
}
เมื่อมีการเรียกใช้งานครั้งแรก Spring จะประมวลผลและเก็บค่าไว้ ส่วนครั้งถัดไปจะดึงค่าจาก Cache มาส่งให้ทันที ทำให้ลดภาระของ Database ได้มหาศาล
2. ข้อจำกัดของ Local Cache (Default)
หากเราไม่ได้ตั้งค่าอะไรเพิ่มเติม Spring Boot จะใช้ ConcurrentHashMap ในการเก็บข้อมูล ซึ่งถือเป็น Local Cache (เก็บใน RAM ของเครื่อง Application)
ข้อดี: เร็วมาก (ระดับ Nanosecond) และไม่ต้องติดตั้งอะไรเพิ่ม ข้อสังเกต: เหมาะสำหรับระบบที่มี Server เพียงเครื่องเดียว (Monolith)
ปัญหาที่จะพบเมื่อขยายระบบ (Scaling): หากคุณเพิ่ม Server เป็น 2 เครื่อง (Server A และ Server B) ข้อมูลใน Cache จะแยกกันอยู่
- User แก้ไขข้อมูลที่ Server A (Cache A อัปเดต)
- User กด Refresh แล้ว Load Balancer พาไป Server B (Cache B ยังเป็นค่าเก่า)
- ผลลัพธ์: User อาจได้รับข้อมูลที่ไม่ตรงกัน (Data Inconsistency)
3. การขยับไปใช้ Redis (Distributed Cache)
เพื่อแก้ปัญหาเรื่องข้อมูลไม่ตรงกันในระบบที่มีหลาย Server เราจึงต้องย้ายที่เก็บ Cache ไปไว้ที่ถังกลางที่ทุก Server เข้าถึงได้ ซึ่ง Redis คือตัวเลือกมาตรฐานในอุตสาหกรรม
ทำไมถึงควรใช้ Redis:
- Consistency: ทุก Server อ่าน/เขียน ข้อมูลชุดเดียวกัน ข้อมูลจึงตรงกันเสมอ
- Persistence: ข้อมูลใน Cache ไม่หายแม้จะ Restart Application Server (ช่วยลด Load ของ Database ตอนเริ่มระบบใหม่)
- Off-heap Memory: แยกการใช้ Memory ออกจาก Java Heap ทำให้ Application ทำงานได้เสถียรขึ้น
4. การปรับเปลี่ยนใน Spring Boot
ข้อดีของ Spring Cache Abstraction คือเราสามารถเปลี่ยนจาก Local Cache ไปเป็น Redis ได้โดย แทบไม่ต้องแก้ Java Code
สิ่งที่ต้องทำ:
- เพิ่ม Dependency
spring-boot-starter-data-redis - กำหนดค่าใน
application.yml:
spring:
data:
redis:
host: localhost
port: 6379
เพียงเท่านี้ Spring Boot จะเปลี่ยนการทำงานเบื้องหลังของ @Cacheable ให้ไปใช้ Redis โดยอัตโนมัติ
บทสรุป: เลือกใช้อย่างไรให้เหมาะสม?
| ปัจจัย | Local Cache (Map) | Redis (Distributed) |
| จำนวน Server | 1 เครื่อง | 2 เครื่องขึ้นไป |
| ความซับซ้อน | ต่ำ (ไม่ต้องติดตั้งเพิ่ม) | ปานกลาง (ต้องดูแล Redis Server) |
| ความเร็ว | เร็วที่สุด (Memory Access) | เร็วมาก (Network I/O) |
| ตัวอย่างข้อมูล | ค่า Config, Master Data ที่ไม่ค่อยเปลี่ยน | Session, Dashboard, Stock สินค้า |
คำแนะนำ: ในช่วงเริ่มต้นโปรเจกต์ การใช้ Local Cache อาจจะเพียงพอและดูแลง่าย แต่ควรออกแบบระบบโดยเผื่อทางเลือกในการเปลี่ยนไปใช้ Redis ไว้เสมอเมื่อระบบเริ่มมีการขยายตัว (Scale out) ครับ
No responses yet. Be the first to respond.