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>
11 KiB
11 KiB
Distribution Service 데이터베이스 설계서
📋 데이터설계 요약
설계 개요
- 서비스명: Distribution Service
- 아키텍처 패턴: Layered Architecture
- 데이터베이스: PostgreSQL (배포 상태 영구 저장), Redis (실시간 모니터링)
- 설계 일시: 2025-10-29
- 설계자: Backend Developer (최수연 "아키텍처")
데이터 특성
- 배포 상태 관리: 이벤트별 다중 채널 배포 상태 추적
- 채널 독립성: 6개 채널(TV, CALL, SNS)별 독립적 상태 관리
- 실시간 모니터링: Redis 캐시를 통한 배포 진행 상태 실시간 조회
- 성과 추적: 채널별 도달률(estimatedViews), 완료 시간, 재시도 횟수 추적
- 에러 관리: 채널별 에러 메시지, 재시도 정보 저장
주요 테이블
- distribution_status: 배포 전체 상태 관리 (이벤트 ID, 전체 상태, 시작/완료 시간)
- channel_status: 채널별 세부 배포 상태 (채널 타입, 진행률, 배포 ID, 도달률, 에러 정보)
캐시 설계
- event:{eventId}:distribution: 배포 상태 실시간 조회 (TTL: 1시간)
- distribution:channel:{eventId}:{channel}: 채널별 상태 캐시 (TTL: 30분)
1. 데이터베이스 스키마 설계
1.1 PostgreSQL 테이블 설계
1.1.1 distribution_status (배포 상태 테이블)
테이블 목적: 이벤트별 배포 전체 상태 관리
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
| id | BIGSERIAL | NO | - | 배포 상태 ID (PK) |
| event_id | VARCHAR(36) | NO | - | 이벤트 ID (UUID) |
| overall_status | VARCHAR(20) | NO | - | 전체 배포 상태 (IN_PROGRESS, COMPLETED, FAILED, PARTIAL_SUCCESS) |
| started_at | TIMESTAMP | NO | - | 배포 시작 시간 |
| completed_at | TIMESTAMP | YES | NULL | 배포 완료 시간 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 생성 시간 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 수정 시간 |
제약 조건:
- PRIMARY KEY: id
- UNIQUE KEY: event_id (이벤트당 하나의 배포 상태만 존재)
- INDEX: event_id (조회 성능 최적화)
- CHECK: overall_status IN ('IN_PROGRESS', 'COMPLETED', 'FAILED', 'PARTIAL_SUCCESS')
1.1.2 channel_status (채널 배포 상태 테이블)
테이블 목적: 채널별 세부 배포 상태 및 성과 추적
| 컬럼명 | 타입 | NULL | 기본값 | 설명 |
|---|---|---|---|---|
| id | BIGSERIAL | NO | - | 채널 상태 ID (PK) |
| distribution_status_id | BIGINT | NO | - | 배포 상태 ID (FK) |
| channel | VARCHAR(20) | NO | - | 채널 타입 (URIDONGNETV, RINGOBIZ, GINITV, INSTAGRAM, NAVER, KAKAO) |
| status | VARCHAR(20) | NO | - | 채널 배포 상태 (PENDING, IN_PROGRESS, SUCCESS, FAILED) |
| progress | INTEGER | YES | 0 | 진행률 (0-100) |
| distribution_id | VARCHAR(100) | YES | NULL | 채널별 배포 ID (외부 시스템 ID) |
| estimated_views | INTEGER | YES | 0 | 예상 도달률 (조회수) |
| update_timestamp | TIMESTAMP | NO | CURRENT_TIMESTAMP | 상태 업데이트 시간 |
| event_id | VARCHAR(36) | NO | - | 이벤트 ID (조회 최적화용) |
| impression_schedule | TEXT | YES | NULL | 노출 일정 (JSON 배열) |
| post_url | VARCHAR(500) | YES | NULL | 게시물 URL |
| post_id | VARCHAR(100) | YES | NULL | 게시물 ID |
| message_id | VARCHAR(100) | YES | NULL | 메시지 ID (카카오톡) |
| completed_at | TIMESTAMP | YES | NULL | 채널 배포 완료 시간 |
| error_message | TEXT | YES | NULL | 에러 메시지 |
| retries | INTEGER | YES | 0 | 재시도 횟수 |
| last_retry_at | TIMESTAMP | YES | NULL | 마지막 재시도 시간 |
| created_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 생성 시간 |
| updated_at | TIMESTAMP | NO | CURRENT_TIMESTAMP | 수정 시간 |
제약 조건:
- PRIMARY KEY: id
- FOREIGN KEY: distribution_status_id REFERENCES distribution_status(id) ON DELETE CASCADE
- UNIQUE KEY: (distribution_status_id, channel) - 배포당 채널별 하나의 상태만 존재
- INDEX: event_id (이벤트별 조회 최적화)
- INDEX: (event_id, channel) (채널별 조회 최적화)
- INDEX: status (상태별 조회 최적화)
- CHECK: channel IN ('URIDONGNETV', 'RINGOBIZ', 'GINITV', 'INSTAGRAM', 'NAVER', 'KAKAO')
- CHECK: status IN ('PENDING', 'IN_PROGRESS', 'SUCCESS', 'FAILED')
- CHECK: progress BETWEEN 0 AND 100
1.2 Redis 캐시 설계
1.2.1 배포 상태 캐시
키 패턴: event:{eventId}:distribution
데이터 구조: Hash
{
"eventId": "uuid",
"overallStatus": "IN_PROGRESS",
"startedAt": "2025-10-29T10:00:00",
"completedAt": null,
"successCount": 3,
"failureCount": 1,
"totalChannels": 6
}
TTL: 1시간 (3600초)
사용 목적:
- 배포 상태 실시간 조회 성능 최적화
- DB 부하 감소 (조회 빈도가 높은 데이터)
- 배포 진행 중 빠른 상태 업데이트
1.2.2 채널별 상태 캐시
키 패턴: distribution:channel:{eventId}:{channel}
데이터 구조: Hash
{
"channel": "INSTAGRAM",
"status": "IN_PROGRESS",
"progress": 75,
"distributionId": "ig_post_12345",
"estimatedViews": 5000,
"updateTimestamp": "2025-10-29T10:30:00",
"postUrl": "https://instagram.com/p/abc123",
"errorMessage": null
}
TTL: 30분 (1800초)
사용 목적:
- 채널별 배포 상태 실시간 모니터링
- 진행률 추적 및 업데이트
- 외부 API 호출 결과 임시 저장
2. Entity-Table 매핑
2.1 DistributionStatus Entity → distribution_status Table
| Entity 필드 | 테이블 컬럼 | 매핑 |
|---|---|---|
| id | id | 1:1 |
| eventId | event_id | 1:1 |
| overallStatus | overall_status | 1:1 |
| startedAt | started_at | 1:1 |
| completedAt | completed_at | 1:1 |
| channels | (관계) | 1:N → channel_status |
| createdAt | created_at | 1:1 (BaseTimeEntity) |
| updatedAt | updated_at | 1:1 (BaseTimeEntity) |
2.2 ChannelStatusEntity Entity → channel_status Table
| Entity 필드 | 테이블 컬럼 | 매핑 |
|---|---|---|
| id | id | 1:1 |
| distributionStatus | distribution_status_id | N:1 (FK) |
| channel | channel | 1:1 (Enum) |
| status | status | 1:1 |
| progress | progress | 1:1 |
| distributionId | distribution_id | 1:1 |
| estimatedViews | estimated_views | 1:1 |
| updateTimestamp | update_timestamp | 1:1 |
| eventId | event_id | 1:1 |
| impressionSchedule | impression_schedule | 1:1 (JSON String) |
| postUrl | post_url | 1:1 |
| postId | post_id | 1:1 |
| messageId | message_id | 1:1 |
| completedAt | completed_at | 1:1 |
| errorMessage | error_message | 1:1 |
| retries | retries | 1:1 |
| lastRetryAt | last_retry_at | 1:1 |
| createdAt | created_at | 1:1 (BaseTimeEntity) |
| updatedAt | updated_at | 1:1 (BaseTimeEntity) |
3. 데이터 관계
3.1 테이블 간 관계
distribution_status (1) ----< (N) channel_status
- 하나의 배포 상태는 여러 채널 상태를 가짐
- CASCADE DELETE: 배포 상태 삭제 시 채널 상태도 함께 삭제
3.2 인덱스 전략
distribution_status 테이블:
- PRIMARY KEY: id (클러스터 인덱스)
- UNIQUE INDEX: event_id (이벤트별 배포 상태 유일성 보장)
channel_status 테이블:
- PRIMARY KEY: id (클러스터 인덱스)
- UNIQUE INDEX: (distribution_status_id, channel) (배포당 채널별 유일성)
- INDEX: event_id (이벤트별 채널 상태 조회 최적화)
- INDEX: (event_id, channel) (복합 조회 최적화)
- INDEX: status (상태별 필터링 최적화)
4. 데이터 독립성 설계
4.1 서비스 간 데이터 분리
Distribution Service 데이터 소유권:
- 배포 상태 및 채널별 성과 데이터 완전 소유
- 타 서비스의 데이터를 직접 조회하지 않음
타 서비스 데이터 참조:
- Event ID: Event Service에서 생성한 ID를 참조 (FK 없음)
- User ID: 직접 저장하지 않음 (인증 정보로만 사용)
- 참조 방식: Redis 캐시 또는 Kafka 이벤트로만 참조
4.2 데이터 동기화 전략
Kafka 이벤트 발행:
// 배포 완료 시 이벤트 발행
Topic: distribution-completed
Event: {
"eventId": "uuid",
"distributedChannels": [
{
"channel": "INSTAGRAM",
"status": "SUCCESS",
"expectedViews": 5000
}
],
"completedAt": "2025-10-29T11:00:00"
}
Analytics Service 연동:
- Distribution Service → Kafka → Analytics Service
- 채널별 성과 데이터 비동기 전달
- 장애 격리 보장 (Circuit Breaker)
5. 쿼리 성능 최적화
5.1 조회 쿼리 최적화
이벤트별 배포 상태 조회:
-- 인덱스 활용: event_id
SELECT ds.*, cs.*
FROM distribution_status ds
LEFT JOIN channel_status cs ON ds.id = cs.distribution_status_id
WHERE ds.event_id = ?;
채널별 배포 현황 조회:
-- 인덱스 활용: (event_id, channel)
SELECT *
FROM channel_status
WHERE event_id = ? AND channel = ?;
진행 중인 배포 목록 조회:
-- 인덱스 활용: overall_status
SELECT *
FROM distribution_status
WHERE overall_status = 'IN_PROGRESS'
ORDER BY started_at DESC;
5.2 캐시 전략
조회 우선순위:
- Redis 캐시 조회 시도
- 캐시 미스 시 PostgreSQL 조회
- 조회 결과를 Redis에 캐싱
캐시 무효화:
- 배포 상태 업데이트 시 캐시 갱신
- 배포 완료 시 캐시 TTL 연장 (1시간 → 24시간)
- 채널 상태 변경 시 해당 채널 캐시 갱신
6. 데이터 보안 및 제약
6.1 데이터 무결성
NOT NULL 제약:
- 필수 정보: event_id, channel, status, overall_status
- 시간 정보: started_at, update_timestamp
CHECK 제약:
- overall_status: 4가지 상태만 허용
- channel: 6개 채널 타입만 허용
- status: 4가지 배포 상태만 허용
- progress: 0-100 범위 제한
UNIQUE 제약:
- event_id: 이벤트당 하나의 배포 상태
- (distribution_status_id, channel): 배포당 채널별 하나의 상태
6.2 CASCADE 정책
ON DELETE CASCADE:
- distribution_status 삭제 시 channel_status 자동 삭제
- 데이터 일관성 보장
7. 마이그레이션 전략
7.1 초기 데이터 마이그레이션
- 초기 배포 시 기본 데이터 없음 (운영 데이터만 존재)
- 채널 타입 Enum 검증 데이터 확인
7.2 스키마 변경 전략
- Flyway 또는 Liquibase를 통한 버전 관리
- 무중단 배포를 위한 Blue-Green 전략
- 인덱스 추가 시 CONCURRENTLY 옵션 사용
8. 모니터링 및 유지보수
8.1 성능 모니터링 지표
- 배포 상태 조회 응답 시간 (<100ms)
- 채널별 배포 성공률 (>95%)
- 재시도 횟수 평균 (<2회)
- 캐시 히트율 (>80%)
8.2 데이터 정리 정책
- 완료된 배포 상태: 30일 후 아카이빙
- 실패한 배포 로그: 90일 보관
- Redis 캐시: TTL 자동 만료
9. 참고 자료
9.1 관련 문서
- 클래스 설계서:
design/backend/class/distribution-service.puml - API 설계서:
design/backend/api/distribution-service-api.md - 시퀀스 다이어그램:
design/backend/sequence/inner/distribution-service-*.puml
9.2 외부 참조
- PostgreSQL 공식 문서: https://www.postgresql.org/docs/
- Redis 캐시 설계 가이드: https://redis.io/docs/manual/patterns/
문서 버전: v1.0 작성일: 2025-10-29 작성자: Backend Developer (최수연 "아키텍처")