Redis 캐시 설치 계획서 - 개발환경
1. 개요
1.1 설치 목적
- 통신요금 관리 서비스의 개발환경 Redis 캐시 구축
- 모든 마이크로서비스 공유 캐시 서버 운영
- 성능 최적화 및 외부 시스템 호출 최소화
- KOS 시스템 연동 데이터 캐싱
1.2 참조 문서
- 물리아키텍처설계서: design/backend/physical/physical-architecture-dev.md
- 데이터설계서: design/backend/database/data-design-summary.md
- 백킹서비스설치방법: claude/backing-service-method.md
1.3 설계 원칙
- 개발 편의성: 단순 구성, 빠른 배포
- 비용 효율성: 메모리 전용 설정
- 성능 우선: 모든 서비스 공유 캐시
- 단순성: 복잡한 클러스터링 없음
2. 시스템 요구사항
2.1 환경 정보
- 환경: Azure Kubernetes Service (AKS) 개발환경
- 네임스페이스: phonebill-dev
- 클러스터: phonebill-dev-aks
- 리소스 그룹: phonebill-dev-rg
- Azure 리전: Korea Central
2.2 기술 스택
| 구성요소 |
버전/사양 |
용도 |
| Redis |
7.2 |
메인 캐시 엔진 |
| Container Image |
bitnami/redis:7.2 |
안정화된 Redis 이미지 |
| 배포 방식 |
StatefulSet |
데이터 일관성 보장 |
| 스토리지 |
없음 (Memory Only) |
개발용 임시 데이터 |
| 네트워크 |
ClusterIP + NodePort |
내부/외부 접근 지원 |
2.3 리소스 할당
| 리소스 유형 |
최소 요구사항 |
최대 제한 |
비고 |
| CPU |
100m |
500m |
개발환경 최적화 |
| Memory |
256Mi |
1Gi |
캐시 크기 제한 |
| 최대 메모리 |
512MB |
- |
메모리 정책 적용 |
| 스토리지 |
없음 |
- |
메모리 전용 |
3. 아키텍처 설계
3.1 Redis 서비스 구성
┌─────────────────────────────────────────────────────────────┐
│ AKS Cluster (phonebill-dev) │
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Auth Service │ │Bill-Inquiry Svc│ │
│ │ (Port: 8080) │ │ (Port: 8080) │ │
│ └─────────┬───────┘ └─────────┬───────┘ │
│ │ │ │
│ │ ┌─────────────────┐ │
│ │ │Product-Change │ │
│ │ │Service │ │
│ │ │ (Port: 8080) │ │
│ │ └─────────┬───────┘ │
│ │ │ │
│ └──────────┬───────────┘ │
│ │ │
│ ┌─────────────────┐ │
│ │ Redis Cache │ │
│ │ │ │
│ │ • Memory Only │ │
│ │ • Port: 6379 │ │
│ │ • Password Auth │ │
│ │ • LRU Policy │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
3.2 캐시 키 전략
3.2.1 키 네이밍 규칙
키_패턴:
고객정보: "customer:{lineNumber}"
상품정보: "product:{productCode}"
세션정보: "session:{userId}:{sessionId}"
권한정보: "permissions:{userId}"
가용상품: "available_products:{customerType}"
회선상태: "line_status:{lineNumber}"
KOS응답: "kos_response:{requestId}"
3.2.2 TTL 정책
| 캐시 유형 |
TTL |
용도 |
갱신 전략 |
| 고객정보 |
4시간 |
고객 기본정보 |
정보 변경시 즉시 무효화 |
| 상품정보 |
2시간 |
상품 목록/상세 |
상품 업데이트시 무효화 |
| 세션정보 |
24시간 |
사용자 세션 |
로그아웃시 삭제 |
| 권한정보 |
8시간 |
사용자 권한 |
권한 변경시 무효화 |
| 가용상품목록 |
24시간 |
변경 가능 상품 |
일 1회 갱신 |
| 회선상태 |
30분 |
실시간 회선정보 |
상태 변경시 갱신 |
3.3 메모리 관리 전략
메모리_설정:
최대_메모리: "512MB"
정책: "allkeys-lru" # 가장 오래된 키 제거
기본_TTL: "30분" # 명시되지 않은 키의 기본 만료시간
메모리_분배:
세션정보: 40% (204MB)
고객정보: 30% (154MB)
상품정보: 20% (102MB)
기타: 10% (52MB)
4. 설치 구성
4.1 Namespace 생성
# Namespace 생성
kubectl create namespace phonebill-dev
# Namespace 이동
kubectl config set-context --current --namespace=phonebill-dev
4.2 Secret 생성
# Redis 인증 정보 생성
kubectl create secret generic redis-secret \
--from-literal=redis-password="Hi5Jessica!" \
--namespace=phonebill-dev
4.3 ConfigMap 생성
# redis-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-config
namespace: phonebill-dev
data:
redis.conf: |
# Redis 7.2 개발환경 설정
# 메모리 설정
maxmemory 512mb
maxmemory-policy allkeys-lru
# 네트워크 설정
bind 0.0.0.0
port 6379
tcp-keepalive 300
timeout 30
# 보안 설정 (Secret에서 주입)
# requirepass 는 StatefulSet에서 env로 설정
# 로그 설정
loglevel notice
logfile ""
# 개발환경 설정 (데이터 지속성 없음)
save ""
appendonly no
# 클라이언트 설정
maxclients 100
# 기타 최적화 설정
tcp-backlog 511
databases 16
# 메모리 사용 최적화
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
4.4 StatefulSet 매니페스트
# redis-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
namespace: phonebill-dev
labels:
app: redis
tier: cache
spec:
serviceName: redis
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
tier: cache
spec:
containers:
- name: redis
image: bitnami/redis:7.2
imagePullPolicy: IfNotPresent
# 환경 변수
env:
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: redis-password
- name: REDIS_DISABLE_COMMANDS
value: "FLUSHALL" # 개발 중 실수 방지
# 포트 설정
ports:
- name: redis
containerPort: 6379
protocol: TCP
# 리소스 제한
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 1Gi
# Health Check
livenessProbe:
tcpSocket:
port: redis
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
failureThreshold: 3
readinessProbe:
exec:
command:
- /bin/bash
- -c
- redis-cli -a "$REDIS_PASSWORD" ping | grep -q PONG
initialDelaySeconds: 5
timeoutSeconds: 5
periodSeconds: 5
successThreshold: 1
failureThreshold: 3
# 볼륨 마운트
volumeMounts:
- name: redis-config
mountPath: /opt/bitnami/redis/etc/redis.conf
subPath: redis.conf
readOnly: true
# 볼륨 정의
volumes:
- name: redis-config
configMap:
name: redis-config
# 보안 컨텍스트
securityContext:
fsGroup: 1001
runAsUser: 1001
runAsNonRoot: true
# Pod 안정성 설정
restartPolicy: Always
terminationGracePeriodSeconds: 30
4.5 Service 매니페스트
# redis-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: phonebill-dev
labels:
app: redis
tier: cache
spec:
type: ClusterIP
selector:
app: redis
ports:
- name: redis
port: 6379
targetPort: redis
protocol: TCP
---
# 개발용 외부 접근 Service
apiVersion: v1
kind: Service
metadata:
name: redis-external
namespace: phonebill-dev
labels:
app: redis
tier: cache
spec:
type: NodePort
selector:
app: redis
ports:
- name: redis
port: 6379
targetPort: redis
nodePort: 30679
protocol: TCP
5. 배포 절차
5.1 사전 준비사항
# 1. AKS 클러스터 연결 확인
kubectl config current-context
# 2. 필요한 권한 확인
kubectl auth can-i create statefulsets --namespace phonebill-dev
# 3. 네임스페이스 확인
kubectl get namespaces | grep phonebill-dev
5.2 배포 순서
# 1. Namespace 생성
kubectl create namespace phonebill-dev
# 2. Secret 생성
kubectl create secret generic redis-secret \
--from-literal=redis-password="Hi5Jessica!" \
--namespace=phonebill-dev
# 3. ConfigMap 적용
kubectl apply -f redis-config.yaml
# 4. StatefulSet 배포
kubectl apply -f redis-statefulset.yaml
# 5. Service 생성
kubectl apply -f redis-service.yaml
# 6. 배포 상태 확인
kubectl get pods -l app=redis -n phonebill-dev -w
5.3 배포 검증
# 1. Pod 상태 확인
kubectl get pods -l app=redis -n phonebill-dev
kubectl describe pod redis-0 -n phonebill-dev
# 2. Service 확인
kubectl get services -l app=redis -n phonebill-dev
kubectl describe service redis -n phonebill-dev
# 3. Redis 연결 테스트
kubectl exec -it redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! ping
# 4. 설정 확인
kubectl exec -it redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! info memory
6. 애플리케이션 연동 설정
6.1 Spring Boot 애플리케이션 설정
# application-dev.yml
spring:
redis:
host: redis.phonebill-dev.svc.cluster.local
port: 6379
password: ${REDIS_PASSWORD:Hi5Jessica!}
timeout: 2000ms
jedis:
pool:
max-active: 20
max-wait: 1000ms
max-idle: 10
min-idle: 2
# 캐시 설정
cache:
redis:
time-to-live: 1800 # 30분 기본 TTL
key-prefix: "phonebill:dev:"
enable-statistics: true
6.2 환경별 캐시 키 설정
# 개발환경 캐시 키 설정
cache:
keys:
customer: "dev:customer:{lineNumber}"
product: "dev:product:{productCode}"
session: "dev:session:{userId}:{sessionId}"
permissions: "dev:permissions:{userId}"
available-products: "dev:available_products:{customerType}"
line-status: "dev:line_status:{lineNumber}"
kos-response: "dev:kos_response:{requestId}"
6.3 서비스별 캐시 설정
// Auth Service 캐시 설정
@Configuration
public class AuthCacheConfig {
@Bean
public RedisCacheManager authCacheManager() {
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(Duration.ofHours(8)) // 권한정보 8시간
.prefixKeysWith("dev:auth:");
return RedisCacheManager.builder()
.redisCacheConfiguration(config)
.build();
}
}
// Bill-Inquiry Service 캐시 설정
@Configuration
public class BillCacheConfig {
@Bean
public RedisCacheManager billCacheManager() {
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(Duration.ofHours(4)) // 고객정보 4시간
.prefixKeysWith("dev:bill:");
return RedisCacheManager.builder()
.redisCacheConfiguration(config)
.build();
}
}
// Product-Change Service 캐시 설정
@Configuration
public class ProductCacheConfig {
@Bean
public RedisCacheManager productCacheManager() {
RedisCacheConfiguration config = RedisCacheConfiguration
.defaultCacheConfig()
.entryTtl(Duration.ofHours(2)) // 상품정보 2시간
.prefixKeysWith("dev:product:");
return RedisCacheManager.builder()
.redisCacheConfiguration(config)
.build();
}
}
7. 모니터링 설정
7.1 Redis 메트릭 수집
# redis-metrics.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-metrics
namespace: phonebill-dev
labels:
app: redis
metrics: "true"
spec:
selector:
app: redis
ports:
- name: metrics
port: 9121
targetPort: 9121
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-exporter
namespace: phonebill-dev
spec:
selector:
matchLabels:
app: redis-exporter
template:
metadata:
labels:
app: redis-exporter
spec:
containers:
- name: redis-exporter
image: oliver006/redis_exporter:latest
env:
- name: REDIS_ADDR
value: "redis://redis:6379"
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: redis-secret
key: redis-password
ports:
- containerPort: 9121
name: metrics
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi
7.2 주요 모니터링 지표
| 지표 |
임계값 |
액션 |
| 메모리 사용률 |
> 80% |
캐시 정리, 메모리 증설 검토 |
| 연결 수 |
> 80 |
연결 풀 최적화 |
| Hit Rate |
< 80% |
캐시 전략 재검토 |
| Evicted Keys |
> 1000/min |
TTL 정책 조정 |
| 응답 시간 |
> 10ms |
성능 최적화 |
7.3 로그 모니터링
# Redis 로그 실시간 모니터링
kubectl logs -f redis-0 -n phonebill-dev
# 메모리 사용량 모니터링
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! info memory
# 키 통계 모니터링
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! info keyspace
# 클라이언트 연결 상태
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! client list
8. 백업 및 복구
8.1 백업 전략
백업_정책:
방식: "메모리 전용으로 백업 없음"
복구_방법: "Pod 재시작시 캐시 재구성"
데이터_손실: "허용 (개발환경)"
비상_계획:
- Pod 장애시 자동 재시작
- 애플리케이션에서 캐시 미스시 DB 조회
- 캐시 warm-up 스크립트 실행
8.2 캐시 Warm-up 스크립트
#!/bin/bash
# cache-warmup.sh - Redis 재시작 후 주요 데이터 캐싱
REDIS_HOST="redis.phonebill-dev.svc.cluster.local"
REDIS_PORT="6379"
REDIS_PASSWORD="Hi5Jessica!"
# 기본 상품 정보 캐싱
echo "상품 정보 캐싱 시작..."
curl -X POST "http://auth-service:8080/api/cache/warmup/products"
# 공통 코드 캐싱
echo "공통 코드 캐싱 시작..."
curl -X POST "http://auth-service:8080/api/cache/warmup/codes"
# 시스템 설정 캐싱
echo "시스템 설정 캐싱 시작..."
curl -X POST "http://bill-inquiry-service:8080/api/cache/warmup/config"
echo "캐시 Warm-up 완료"
9. 보안 설정
9.1 네트워크 보안
# redis-network-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: redis-network-policy
namespace: phonebill-dev
spec:
podSelector:
matchLabels:
app: redis
policyTypes:
- Ingress
ingress:
# 애플리케이션 서비스에서만 접근 허용
- from:
- podSelector:
matchLabels:
tier: application
ports:
- protocol: TCP
port: 6379
# 모니터링을 위한 접근 허용
- from:
- podSelector:
matchLabels:
app: redis-exporter
ports:
- protocol: TCP
port: 6379
9.2 보안 체크리스트
보안_체크리스트:
✓ 인증: "Redis 패스워드 인증 활성화"
✓ 네트워크: "ClusterIP로 내부 접근만 허용"
✓ 권한: "비루트 사용자로 실행"
✓ 명령어: "위험한 명령어 비활성화 (FLUSHALL)"
✓ 로그: "접근 로그 기록"
✗ 암호화: "개발환경에서 TLS 미적용"
✗ 방화벽: "기본 보안 그룹 사용"
10. 운영 가이드
10.1 일상 운영 작업
# Redis 상태 확인
kubectl get pods -l app=redis -n phonebill-dev
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! info server
# 메모리 사용량 확인
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! info memory
# 키 현황 확인
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! info keyspace
# 슬로우 로그 확인
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! slowlog get 10
10.2 캐시 관리 작업
# 특정 패턴 키 삭제
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! --scan --pattern "dev:customer:*" | xargs -I {} redis-cli -a Hi5Jessica! del {}
# 캐시 통계 확인
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! info stats
# 클라이언트 연결 확인
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! client list
# TTL 확인
kubectl exec redis-0 -n phonebill-dev -- redis-cli -a Hi5Jessica! ttl "dev:customer:010-1234-5678"
10.3 트러블슈팅 가이드
| 문제 |
원인 |
해결방안 |
| Pod 시작 실패 |
리소스 부족 |
노드 리소스 확인, 메모리 제한 조정 |
| 연결 실패 |
네트워크/인증 문제 |
패스워드, 포트, 네트워크 정책 확인 |
| 메모리 부족 |
캐시 데이터 과다 |
TTL 정책 조정, 메모리 증설 |
| 성능 저하 |
키 집중, 메모리 스왑 |
키 분산, 메모리 최적화 |
| 캐시 미스 증가 |
TTL 정책, 데이터 변경 |
TTL 조정, 무효화 전략 검토 |
11. 비용 최적화
11.1 개발환경 비용 구조
| 리소스 |
할당량 |
월간 예상 비용 |
절약 방안 |
| CPU |
100m-500m |
$3 |
requests 최소화 |
| Memory |
256Mi-1Gi |
$5 |
메모리 전용으로 스토리지 비용 없음 |
| 네트워킹 |
ClusterIP |
$0 |
내부 통신만 사용 |
| 총합 |
|
$8 |
스토리지 제거로 비용 최소화 |
11.2 비용 절약 전략
절약_방안:
- 스토리지_제거: "메모리 전용으로 스토리지 비용 제거"
- 리소스_최적화: "requests를 최소한으로 설정"
- 자동_스케일링_비활성화: "개발환경에서 고정 리소스"
- 야간_스케일다운: "비업무시간 리소스 축소"
12. 성능 튜닝 가이드
12.1 성능 목표
| 지표 |
목표값 |
측정 방법 |
| 응답 시간 |
< 5ms |
Redis PING |
| 처리량 |
> 1000 ops/sec |
Redis INFO stats |
| 메모리 효율성 |
> 90% hit rate |
Redis INFO keyspace |
| 연결 처리 |
< 100 concurrent |
Redis CLIENT LIST |
12.2 튜닝 매개변수
# redis.conf 최적화
성능_튜닝:
# 네트워크 최적화
tcp-keepalive: 300
tcp-backlog: 511
timeout: 30
# 메모리 최적화
maxmemory-policy: "allkeys-lru"
hash-max-ziplist-entries: 512
list-max-ziplist-size: -2
# 클라이언트 최적화
maxclients: 100
databases: 16
13. 마이그레이션 계획
13.1 운영환경 이관 준비
운영환경_차이점:
- 고가용성: "Master-Slave 구성"
- 데이터_지속성: "RDB + AOF 활성화"
- 보안_강화: "TLS 암호화, 네트워크 정책"
- 리소스_증설: "CPU 1-2 core, Memory 4-8GB"
- 모니터링_강화: "Prometheus, Grafana 연동"
- 백업_정책: "자동 백업, 복구 절차"
13.2 설정 호환성
호환성_체크:
✓ Redis_버전: "7.2 동일"
✓ 데이터_구조: "키 패턴 호환"
✓ 애플리케이션_설정: "연결 정보만 변경"
✓ 모니터링_지표: "동일한 메트릭 수집"
⚠ TTL_정책: "운영환경에서 조정 필요"
⚠ 메모리_정책: "운영환경 특성에 맞게 조정"
14. 완료 체크리스트
14.1 설치 검증 항목
필수_검증_항목:
□ Redis Pod 정상 실행
□ Service 연결 가능
□ 패스워드 인증 동작
□ 메모리 제한 적용
□ TTL 정책 동작
□ 애플리케이션 연동 테스트
□ 모니터링 메트릭 수집
□ 네트워크 정책 적용
□ 캐시 성능 테스트
□ 장애 복구 테스트
14.2 운영 준비 항목
운영_준비_항목:
□ 운영 매뉴얼 작성
□ 모니터링 대시보드 구성
□ 알림 규칙 설정
□ 백업 및 복구 절차 문서화
□ 성능 튜닝 가이드 작성
□ 트러블슈팅 가이드 작성
□ 개발팀 교육 완료
□ 운영팀 인수인계 완료
계획서 작성일: 2025-09-08
작성자: 데옵스 (최운영), 백엔더 (이개발)
검토자: 아키텍트 (김기획), QA매니저 (정테스트)
승인자: 프로젝트 매니저
다음 단계: Redis 캐시 설치 실행 → develop/database/exec/cache-exec-dev.md 작성