728x90
DB 부하를 Redis로 덜어주는 실전 패턴
✅ 왜 캐싱이 중요한가?
- 자주 조회되는 데이터를 매번 DB에서 가져오면 성능에 큰 부담
- GORM만 사용하면 매 요청마다 쿼리 발생
- Redis를 캐시로 두면 응답 속도 향상 + DB 부하 감소
🧱 기본 구조
Client → Gin → Service
├── Redis 캐시 hit → 바로 응답
└── miss → GORM → DB → 캐시 저장 → 응답
🧪 실습 전제
- Gin + GORM + Redis 사용
- User 모델 조회 예시
- Redis는 go-redis 사용
1. Redis 설정
import (
"github.com/redis/go-redis/v9"
"context"
)
var ctx = context.Background()
var rdb = redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "", // no password set
DB: 0, // use default DB
})
2. GORM 모델
type User struct {
ID uint `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
3. 캐싱 로직 추가
import (
"encoding/json"
"fmt"
"time"
)
// 유저 ID로 조회 (캐시 우선)
func GetUserByID(id uint) (*User, error) {
var user User
cacheKey := fmt.Sprintf("user:%d", id)
// 캐시에서 시도
val, err := rdb.Get(ctx, cacheKey).Result()
if err == nil {
json.Unmarshal([]byte(val), &user)
return &user, nil
}
// 캐시 miss → DB에서 조회
result := db.First(&user, id)
if result.Error != nil {
return nil, result.Error
}
// 캐시에 저장
jsonData, _ := json.Marshal(user)
rdb.Set(ctx, cacheKey, jsonData, time.Minute*10)
return &user, nil
}
4. 캐시 무효화 전략
데이터 변경 시, 관련 캐시는 지우는 것이 핵심
func UpdateUser(id uint, newName string) error {
result := db.Model(&User{}).Where("id = ?", id).Update("name", newName)
if result.Error != nil {
return result.Error
}
// 캐시 삭제
cacheKey := fmt.Sprintf("user:%d", id)
rdb.Del(ctx, cacheKey)
return nil
}
5. TTL 전략 (Time To Live)
- 일반적으로는 5~30분으로 설정
- 변하지 않는 데이터는 더 길게
- 로그인 유저 등 민감한 데이터는 짧게
rdb.Set(ctx, key, value, time.Minute*10) // 10분 캐시
6. 성능 최적화 팁
전략 | 설명 |
캐시 키 네이밍 | user:123, post:456처럼 prefix로 영역 분리 |
직렬화 | json.Marshal vs gob → 속도 & 크기 트레이드오프 |
대량 데이터 | 리스트 캐싱은 주의 (페이징 별도 캐싱 고려) |
캐시 무효화 | 데이터 변경 시 무조건 Del 먼저! |
fallback | 캐시 실패 시 DB fallback 필수 구현 |
✅ 정리
- Redis 캐시를 도입하면 GORM 성능을 수직 상승시킬 수 있음
- 캐시 히트율을 높이기 위한 TTL, 키 설계, 무효화 전략이 핵심
- 캐시만 믿지 말고 DB fallback 로직 필수
728x90
'개발 > Go' 카테고리의 다른 글
[Go] Go에서 싱글턴 패턴 구현하기 - 실전 예제로 쉽게 이해하기 (58) | 2025.06.20 |
---|---|
[Gin] GORM에서 CQRS 아키텍처 구현해보기 (85) | 2025.06.18 |
[Gin] GORM 디버깅 & 에러 핸들링 완전정복 (59) | 2025.06.13 |
[Gin] GORM으로 단위 테스트 잘하는 법 - 테스트 환경 구성부터 Mock까지 (70) | 2025.06.11 |
[Gin] GORM에서 안전한 쿼리 작성법 - SQL 인젝션 방지와 Named Parameter 전략 (69) | 2025.06.09 |