mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 20:06:23 +00:00
✨ 주요 기능 - Azure 기반 물리아키텍처 설계 (개발환경/운영환경) - 7개 마이크로서비스 물리 구조 설계 - 네트워크 아키텍처 다이어그램 작성 (Mermaid) - 환경별 비교 분석 및 마스터 인덱스 문서 📁 생성 파일 - design/backend/physical/physical-architecture.md (마스터) - design/backend/physical/physical-architecture-dev.md (개발환경) - design/backend/physical/physical-architecture-prod.md (운영환경) - design/backend/physical/*.mmd (4개 Mermaid 다이어그램) 🎯 핵심 성과 - 비용 최적화: 개발환경 월 $143, 운영환경 월 $2,860 - 확장성: 개발환경 100명 → 운영환경 10,000명 (100배) - 가용성: 개발환경 95% → 운영환경 99.9% - 보안: 다층 보안 아키텍처 (L1~L4) 🛠️ 기술 스택 - Azure Kubernetes Service (AKS) - Azure Database for PostgreSQL Flexible - Azure Cache for Redis Premium - Azure Service Bus Premium - Application Gateway + WAF 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
345 lines
8.7 KiB
Markdown
345 lines
8.7 KiB
Markdown
# AI Service 데이터베이스 설계서
|
||
|
||
## 📋 데이터설계 요약
|
||
|
||
### 서비스 특성
|
||
- **서비스명**: AI Service
|
||
- **아키텍처**: Clean Architecture
|
||
- **데이터 저장소**: Redis Cache Only (PostgreSQL 미사용)
|
||
- **특징**: Stateless 서비스, AI API 결과 캐싱 전략
|
||
|
||
### 데이터 구조 개요
|
||
AI Service는 외부 AI API(Claude)와 연동하여 이벤트 추천을 생성하는 서비스로, 영속적인 데이터 저장이 필요하지 않습니다. 모든 데이터는 Redis 캐시를 통해 임시 저장되며, TTL 만료 시 자동 삭제됩니다.
|
||
|
||
| 캐시 키 패턴 | 용도 | TTL | 데이터 형식 |
|
||
|------------|------|-----|-----------|
|
||
| `ai:recommendation:{eventId}` | AI 추천 결과 | 1시간 | JSON (AIRecommendationResult) |
|
||
| `ai:job:status:{jobId}` | AI 작업 상태 | 24시간 | JSON (JobStatusResponse) |
|
||
| `ai:trend:{industry}:{region}` | 트렌드 분석 결과 | 24시간 | JSON (TrendAnalysis) |
|
||
|
||
### 설계 근거
|
||
1. **Stateless 설계**: AI 추천은 요청 시마다 실시간 생성되므로 영속화 불필요
|
||
2. **성능 최적화**: 동일한 조건의 반복 요청에 대한 캐시 히트율 향상
|
||
3. **비용 절감**: AI API 호출 비용 절감을 위한 캐싱 전략
|
||
4. **TTL 관리**: 추천의 시의성 유지를 위한 적절한 TTL 설정
|
||
|
||
---
|
||
|
||
## 1. 캐시 데이터베이스 설계 (Redis)
|
||
|
||
### 1.1 AI 추천 결과 캐시
|
||
|
||
**캐시 키**: `ai:recommendation:{eventId}`
|
||
|
||
**TTL**: 3600초 (1시간)
|
||
|
||
**데이터 구조**:
|
||
```json
|
||
{
|
||
"eventId": "uuid-string",
|
||
"trendAnalysis": {
|
||
"industryTrends": [
|
||
{
|
||
"keyword": "string",
|
||
"relevance": 0.95,
|
||
"description": "string"
|
||
}
|
||
],
|
||
"regionalTrends": [...],
|
||
"seasonalTrends": [...]
|
||
},
|
||
"recommendations": [
|
||
{
|
||
"optionNumber": 1,
|
||
"concept": "string",
|
||
"title": "string",
|
||
"description": "string",
|
||
"targetAudience": "string",
|
||
"duration": {
|
||
"recommendedDays": 7,
|
||
"recommendedPeriod": "주중"
|
||
},
|
||
"mechanics": {
|
||
"type": "DISCOUNT",
|
||
"details": "string"
|
||
},
|
||
"promotionChannels": ["string"],
|
||
"estimatedCost": {
|
||
"min": 500000,
|
||
"max": 1000000,
|
||
"breakdown": {
|
||
"promotion": 300000,
|
||
"gift": 500000
|
||
}
|
||
},
|
||
"expectedMetrics": {
|
||
"newCustomers": {
|
||
"min": 50.0,
|
||
"max": 100.0
|
||
},
|
||
"revenueIncrease": {
|
||
"min": 10.0,
|
||
"max": 20.0
|
||
},
|
||
"roi": {
|
||
"min": 150.0,
|
||
"max": 250.0
|
||
}
|
||
},
|
||
"differentiator": "string"
|
||
}
|
||
],
|
||
"generatedAt": "2025-10-29T10:00:00",
|
||
"expiresAt": "2025-10-29T11:00:00",
|
||
"aiProvider": "CLAUDE"
|
||
}
|
||
```
|
||
|
||
**용도**: AI 추천 결과를 캐싱하여 동일한 이벤트에 대한 반복 요청 시 AI API 호출 생략
|
||
|
||
**캐싱 전략**:
|
||
- Cache-Aside 패턴
|
||
- 캐시 미스 시 AI API 호출 후 결과 저장
|
||
- TTL 만료 시 자동 삭제하여 최신 트렌드 반영
|
||
|
||
---
|
||
|
||
### 1.2 작업 상태 캐시
|
||
|
||
**캐시 키**: `ai:job:status:{jobId}`
|
||
|
||
**TTL**: 86400초 (24시간)
|
||
|
||
**데이터 구조**:
|
||
```json
|
||
{
|
||
"jobId": "uuid-string",
|
||
"status": "PROCESSING",
|
||
"progress": 50,
|
||
"message": "트렌드 분석 중...",
|
||
"createdAt": "2025-10-29T10:00:00"
|
||
}
|
||
```
|
||
|
||
**상태 값**:
|
||
- `PENDING`: 작업 대기 중
|
||
- `PROCESSING`: 작업 진행 중
|
||
- `COMPLETED`: 작업 완료
|
||
- `FAILED`: 작업 실패
|
||
|
||
**용도**: 비동기 AI 작업의 상태를 추적하여 클라이언트가 진행 상황 확인
|
||
|
||
**캐싱 전략**:
|
||
- Write-Through 패턴
|
||
- 상태 변경 시 즉시 캐시 업데이트
|
||
- 완료/실패 후 24시간 동안 상태 조회 가능
|
||
|
||
---
|
||
|
||
### 1.3 트렌드 분석 캐시
|
||
|
||
**캐시 키**: `ai:trend:{industry}:{region}`
|
||
|
||
**TTL**: 86400초 (24시간)
|
||
|
||
**데이터 구조**:
|
||
```json
|
||
{
|
||
"industryTrends": [
|
||
{
|
||
"keyword": "친환경",
|
||
"relevance": 0.95,
|
||
"description": "지속가능성과 환경 보호에 대한 관심 증가"
|
||
}
|
||
],
|
||
"regionalTrends": [
|
||
{
|
||
"keyword": "로컬 맛집",
|
||
"relevance": 0.88,
|
||
"description": "지역 특산물과 전통 음식에 대한 관심"
|
||
}
|
||
],
|
||
"seasonalTrends": [
|
||
{
|
||
"keyword": "겨울 따뜻함",
|
||
"relevance": 0.82,
|
||
"description": "추운 날씨에 따뜻한 음식 선호"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**용도**: 업종 및 지역별 트렌드 분석 결과를 캐싱하여 AI API 호출 최소화
|
||
|
||
**캐싱 전략**:
|
||
- Cache-Aside 패턴
|
||
- 동일 업종/지역 조합에 대한 반복 분석 방지
|
||
- 하루 단위 TTL로 최신 트렌드 유지
|
||
|
||
---
|
||
|
||
## 2. Redis 데이터 구조 설계
|
||
|
||
### 2.1 Redis 키 명명 규칙
|
||
|
||
```
|
||
ai:recommendation:{eventId} # AI 추천 결과
|
||
ai:job:status:{jobId} # 작업 상태
|
||
ai:trend:{industry}:{region} # 트렌드 분석
|
||
```
|
||
|
||
### 2.2 Redis 설정
|
||
|
||
```yaml
|
||
# application.yml
|
||
spring:
|
||
redis:
|
||
host: ${REDIS_HOST:localhost}
|
||
port: ${REDIS_PORT:6379}
|
||
password: ${REDIS_PASSWORD:}
|
||
timeout: 3000ms
|
||
lettuce:
|
||
pool:
|
||
max-active: 8
|
||
max-idle: 8
|
||
min-idle: 2
|
||
max-wait: -1ms
|
||
|
||
# 캐시 TTL 설정
|
||
cache:
|
||
ttl:
|
||
recommendation: 3600 # 1시간
|
||
job-status: 86400 # 24시간
|
||
trend: 86400 # 24시간
|
||
```
|
||
|
||
### 2.3 캐시 동시성 제어
|
||
|
||
**Distributed Lock**:
|
||
- Redis의 SETNX 명령을 사용한 분산 락
|
||
- 동일한 이벤트에 대한 중복 AI 호출 방지
|
||
|
||
```java
|
||
// 예시: Redisson을 사용한 분산 락
|
||
RLock lock = redisson.getLock("ai:lock:event:" + eventId);
|
||
try {
|
||
if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
|
||
// AI API 호출 및 캐시 저장
|
||
}
|
||
} finally {
|
||
lock.unlock();
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 캐시 무효화 전략
|
||
|
||
### 3.1 TTL 기반 자동 만료
|
||
|
||
| 캐시 타입 | TTL | 만료 이유 |
|
||
|----------|-----|----------|
|
||
| 추천 결과 | 1시간 | 트렌드 변화 반영 필요 |
|
||
| 작업 상태 | 24시간 | 작업 완료 후 장기 보관 불필요 |
|
||
| 트렌드 분석 | 24시간 | 일간 트렌드 변화 반영 |
|
||
|
||
### 3.2 수동 무효화 트리거
|
||
|
||
- **이벤트 삭제 시**: 해당 이벤트의 추천 캐시 삭제
|
||
- **시스템 업데이트 시**: 전체 캐시 초기화 (관리자 기능)
|
||
|
||
---
|
||
|
||
## 4. 성능 최적화 전략
|
||
|
||
### 4.1 캐시 히트율 최적화
|
||
|
||
**목표 캐시 히트율**: 70% 이상
|
||
|
||
**최적화 방안**:
|
||
1. **프리페칭**: 인기 업종/지역 조합의 트렌드를 사전 캐싱
|
||
2. **지능형 TTL**: 접근 빈도에 따른 동적 TTL 조정
|
||
3. **Warm-up**: 서비스 시작 시 주요 데이터 사전 로딩
|
||
|
||
### 4.2 메모리 효율성
|
||
|
||
**예상 메모리 사용량**:
|
||
- 추천 결과: ~50KB/건
|
||
- 작업 상태: ~1KB/건
|
||
- 트렌드 분석: ~10KB/건
|
||
|
||
**메모리 관리**:
|
||
- 최대 메모리 제한: 1GB
|
||
- 만료 정책: volatile-lru (TTL이 있는 키만 LRU 제거)
|
||
|
||
---
|
||
|
||
## 5. 모니터링 지표
|
||
|
||
### 5.1 캐시 성능 지표
|
||
|
||
| 지표 | 목표 | 측정 방법 |
|
||
|------|------|----------|
|
||
| 캐시 히트율 | ≥70% | (hits / (hits + misses)) × 100 |
|
||
| 평균 응답 시간 | <50ms | Redis 명령 실행 시간 측정 |
|
||
| 메모리 사용률 | <80% | used_memory / maxmemory |
|
||
| 키 개수 | <100,000 | DBSIZE 명령 |
|
||
|
||
### 5.2 알림 임계값
|
||
|
||
- 캐시 히트율 < 50%: 경고
|
||
- 메모리 사용률 > 80%: 경고
|
||
- 평균 응답 시간 > 100ms: 경고
|
||
- Redis 연결 실패: 심각
|
||
|
||
---
|
||
|
||
## 6. 재해 복구 전략
|
||
|
||
### 6.1 데이터 손실 대응
|
||
|
||
**특성**: 캐시 데이터는 손실되어도 서비스 정상 동작
|
||
- Redis 장애 시 AI API 직접 호출로 대체
|
||
- Circuit Breaker 패턴으로 장애 격리
|
||
- Fallback 메커니즘으로 기본 추천 제공
|
||
|
||
### 6.2 Redis 고가용성
|
||
|
||
**구성**: Redis Sentinel 또는 Cluster
|
||
- Master-Slave 복제
|
||
- 자동 Failover
|
||
- 읽기 부하 분산
|
||
|
||
---
|
||
|
||
## 7. 보안 고려사항
|
||
|
||
### 7.1 데이터 보호
|
||
|
||
- **네트워크 암호화**: TLS/SSL 연결
|
||
- **인증**: Redis PASSWORD 설정
|
||
- **접근 제어**: Redis ACL을 통한 명령 제한
|
||
|
||
### 7.2 민감 정보 처리
|
||
|
||
- AI API 키: 환경 변수로 관리 (캐시 저장 금지)
|
||
- 개인정보: 캐시에 저장하지 않음 (이벤트 ID만 사용)
|
||
|
||
---
|
||
|
||
## 8. 결론
|
||
|
||
AI Service는 **완전한 Stateless 아키텍처**를 채택하여 Redis 캐시만을 사용합니다. 이는 다음과 같은 장점을 제공합니다:
|
||
|
||
✅ **확장성**: 서버 인스턴스 추가 시 상태 동기화 불필요
|
||
✅ **성능**: AI API 호출 비용 절감 및 응답 시간 단축
|
||
✅ **단순성**: 데이터베이스 스키마 관리 부담 제거
|
||
✅ **유연성**: 캐시 정책 변경 시 서비스 재시작 불필요
|
||
|
||
**PostgreSQL 미사용 이유**:
|
||
- AI 추천은 실시간 생성 데이터로 영속화 가치 낮음
|
||
- 이력 관리는 Analytics Service에서 담당
|
||
- 캐시 TTL로 데이터 신선도 보장
|
||
|
||
**다음 단계**: Redis 클러스터 구성 및 모니터링 대시보드 설정
|