Physical Architecture 설계하는 방법

System Architecture Design - From Logic to Implementation

Logical Architecture를 기반으로 구체적인 기술 스택을 선택하고 Physical Architecture를 설계하며 배포 가능한 형태로 구현하는 방법론을 다룬다.

Engineering
Architecture
저자

Kwangmin Kim

공개

2025년 11월 17일

1 Physical Architecture의 정의

Physical Architecture는 Logical Architecture를 구체적인 기술 스택과 인프라로 구현하는 설계 계층이다. 실제 배포, 운영, 모니터링이 가능한 형태로 정의된다.

핵심 특징:

  • 기술 명시: 프로그래밍 언어, 프레임워크, 데이터베이스, 클라우드 서비스 구체화
  • 인프라 정의: 서버, 네트워크, 스토리지 구조 명시
  • 배포 단위: 컨테이너, 마이크로서비스, 서버리스 등 배포 형태
  • 운영 고려: 모니터링, 로깅, 스케일링, 재해 복구 전략
  • 비용 및 성능: 실제 리소스 할당, 예상 비용
  • 개발팀 지향: 구현 팀이 직접 따를 수 있는 명확한 지침

1.1 세 계층의 최종 비교

측면 Conceptual Logical Physical
대상 모든 이해관계자 개발팀, 아키텍트 개발팀, DevOps팀
추상화 매우 높음 중간 낮음 (구체적)
기술 없음 독립적 명시적
예: 저장소 “저장소” “Relational DB + Cache Layer” “PostgreSQL 14 + Redis 7”
예: 통신 “데이터 전달” “REST API” “FastAPI + gRPC”
초점 무엇을 어떻게 (기술 중립) 무엇으로
산출물 개념도 모듈 명세서 배포 가이드

2 Physical Architecture 설계 단계

2.1 기술 스택 선택 전 고려사항

Physical 설계를 시작하기 전에 다음을 검토해야 한다:

  • 조직의 기술 역량: 팀이 보유한 기술 경험과 학습 곡선
  • 프로젝트 특성: 시스템의 복잡도, 규모, 기간
  • 성능 요구사항: 응답시간, 처리량, 동시성 목표
  • 운영 환경: 온프레미스 vs 클라우드, 멀티클라우드 전략
  • 비용 제약: 초기 투자, 운영 비용
  • 지속 가능성: 커뮤니티 지원, 장기 유지보수성

2.2 기술 스택 선택 프레임워크

각 Logical 모듈에 대해 기술을 선택할 때는 다음 기준으로 평가한다:

평가 기준:

  1. 기능성 (Functionality): 요구사항을 충족하는가?
  2. 성능 (Performance): 성능 목표를 달성할 수 있는가?
  3. 확장성 (Scalability): 수평/수직 확장이 가능한가?
  4. 운영성 (Operability): 배포, 모니터링, 유지보수가 쉬운가?
  5. 비용 (Cost): 라이선스, 인프라, 인력 비용이 적절한가?
  6. 에코시스템 (Ecosystem): 라이브러리, 도구, 커뮤니티가 활발한가?
  7. 보안 (Security): 보안 기능과 업데이트 지원이 충분한가?
  8. 학습곡선 (Learning Curve): 팀이 얼마나 빨리 습득할 수 있는가?

선택 매트릭스 예시:

기술 기능 성능 확장 운영 비용 에코 보안 학습 총점
PostgreSQL 9 8 8 9 10 10 9 8 8.6
MongoDB 8 7 9 7 8 9 7 8 7.9
Elasticsearch 9 9 9 8 6 9 8 7 8.1

2.3 계층별 기술 선택

2.3.1 프레젠테이션 계층 (Presentation Layer)

Logical Module: ChatInterface, APIGateway, Dashboard

선택 가능 기술:
- Frontend: React, Vue, Angular, Svelte
- Backend Framework: FastAPI, Flask, Django (Python)
                     Spring Boot (Java)
                     Express, NestJS (Node.js)
- API Gateway: Kong, AWS API Gateway, Nginx
- WebSocket: Socket.io, WebSocket (native)

선택 예시: Python 기반 빠른 개발

Chat Interface: 
  - Frontend: React + TypeScript
  - Backend: FastAPI
  - WebSocket: WebSocket (native) or Socket.io
  
API Gateway:
  - Nginx (경량) or Kong (기능 풍부)

Dashboard:
  - Frontend: Streamlit (프로토타입) or React
  - Backend: FastAPI

선택 예시: Java 엔터프라이즈 환경

Chat Interface:
  - Frontend: React or Angular
  - Backend: Spring Boot
  - WebSocket: Spring WebSocket
  
API Gateway:
  - Spring Cloud Gateway or Kong
  
Dashboard:
  - Frontend: Angular
  - Backend: Spring Boot

2.3.2 애플리케이션 계층 (Application Layer)

Logical Module: RequestHandler, Orchestration, QueryProcessor, ReasoningEngine

선택 가능 기술:
- 오케스트레이션: 커스텀 로직, Celery (Python), Akka (Java)
- 비동기 처리: AsyncIO (Python), CompletableFuture (Java)
- 워크플로우 엔진: Apache Airflow, Temporal, AWS Step Functions
- 메시지 큐: RabbitMQ, Apache Kafka, AWS SQS

선택 예시: Python + LangChain RAG

QueryProcessor:
  - LangChain (파이썬 라이브러리)
  - Custom Python 클래스
  
ReasoningEngine:
  - LangChain Agent
  - LLM 호출 (OpenAI API, Anthropic API)
  
Orchestration:
  - 커스텀 Python 로직 or Celery (분산 작업)

선택 예시: Java 엔터프라이즈 오케스트레이션

RequestHandler:
  - Spring Controller
  
Orchestration:
  - Spring Cloud Task
  - Temporal (복잡한 워크플로우)
  
MessagingQueue:
  - RabbitMQ or Apache Kafka

2.3.3 데이터 계층 (Data Layer)

Logical Module: VectorStore, TextRepository, MetadataRepository, CacheLayer

선택 가능 기술:

벡터 저장소:
  - FAISS (로컬, 인메모리)
  - Chroma (오픈소스, 경량)
  - Weaviate (프로덕션용)
  - Milvus (고성능)
  - Pinecone (클라우드 SaaS)
  - Azure Cognitive Search (클라우드)

텍스트 저장소:
  - PostgreSQL + pgvector (벡터 지원)
  - Elasticsearch (검색 최적화)
  - MongoDB (유연한 스키마)
  - Azure Cosmos DB

메타데이터 저장소:
  - PostgreSQL
  - Redis (빠른 접근)
  - DynamoDB (AWS)

캐시 계층:
  - Redis
  - Memcached
  - Local In-Memory Cache

선택 예시: 빠른 프로토타입

Vector Store:
  - FAISS (로컬) or Chroma (간단한 배포)
  
Text Repository:
  - PostgreSQL with full-text search
  
Metadata Repository:
  - PostgreSQL의 같은 인스턴스
  
Cache Layer:
  - Redis (선택사항, 필요시)

선택 예시: 프로덕션 고성능 시스템

Vector Store:
  - Milvus (클러스터 구성)
  or Pinecone (완전 관리형)
  
Text Repository:
  - Elasticsearch (검색 성능)
  + PostgreSQL (트랜잭션)
  
Metadata Repository:
  - PostgreSQL
  
Cache Layer:
  - Redis Cluster (고가용성)

3 Physical Architecture 다이어그램

3.1 배포 아키텍처 다이어그램

┌─────────────────────────────────────────────────────────────┐
│                         인터넷                               │
└────────────────┬────────────────────────────────────────────┘
                 │
        ┌────────▼────────┐
        │  Load Balancer  │ (Nginx / AWS ALB)
        │  (포트 443)     │
        └────────┬────────┘
                 │
        ┌────────▼────────────────────────┐
        │   Kubernetes Cluster            │
        │   (또는 EC2 / App Service)      │
        │                                 │
        │  ┌─────────────────────────┐   │
        │  │  Frontend Pods          │   │
        │  │  (React + Nginx)        │   │
        │  │  - 2 replicas           │   │
        │  └────────┬────────────────┘   │
        │           │                    │
        │  ┌────────▼────────────────┐   │
        │  │  API Service Pods       │   │
        │  │  (FastAPI)              │   │
        │  │  - 3 replicas           │   │
        │  └────────┬────────────────┘   │
        │           │                    │
        │  ┌────────▼────────────────┐   │
        │  │  Worker Pods            │   │
        │  │  (RAG Processing)       │   │
        │  │  - 2 replicas           │   │
        │  └────────┬────────────────┘   │
        │           │                    │
        └───────────┼────────────────────┘
                    │
        ┌───────────┴───────────┬──────────────┬─────────────┐
        │                       │              │             │
    ┌───▼──────┐       ┌───────▼─────┐  ┌───▼────┐  ┌──────▼─────┐
    │PostgreSQL│       │   Milvus    │  │ Redis  │  │ S3 Storage │
    │  + PgVec │       │  (Vector DB)│  │ Cache  │  │ (Raw Data) │
    └──────────┘       └─────────────┘  └────────┘  └────────────┘
        (Metadata)

3.2 컨테이너 구성 예시

Docker Image 1: frontend
  - Base: node:18-alpine
  - Content: React App + Nginx
  - Size: ~150MB
  - Registry: ECR / Docker Hub

Docker Image 2: api-service
  - Base: python:3.11-slim
  - Content: FastAPI application
  - Dependencies: LangChain, openai, pydantic
  - Size: ~800MB
  - Registry: ECR / Docker Hub

Docker Image 3: worker
  - Base: python:3.11-slim
  - Content: RAG worker process
  - Dependencies: LangChain, Celery, milvus-sdk
  - Size: ~900MB
  - Registry: ECR / Docker Hub

Docker Image 4: vector-db
  - Base: milvusdb/milvus:latest
  - Content: Milvus vector database
  - Ports: 19530 (gRPC), 9091 (HTTP)
  - Volumes: /var/lib/milvus (persistent)

Docker Image 5: postgres
  - Base: postgres:15-alpine
  - Extensions: pgvector
  - Ports: 5432
  - Volumes: /var/lib/postgresql/data

Docker Image 6: redis
  - Base: redis:7-alpine
  - Ports: 6379
  - Volumes: /data (persistence)

3.3 네트워크 토폴로지

외부 트래픽
    │
    ▼
┌─────────────────┐
│  CDN / CloudFront│ (정적 콘텐츠)
└────────┬────────┘
         │
         ▼
    ┌─────────────┐
    │Load Balancer│
    └─────┬───────┘
          │
     ┌────┴────────────────────┐
     │                         │
     ▼                         ▼
 ┌────────┐              ┌────────────┐
 │ Public │              │Private Network
 │Subnets │              │(DB, Cache) │
 │        │              │            │
 │Frontend│              │ PostgreSQL │
 │Pods    │◄────────────▶│ Milvus    │
 │        │              │ Redis     │
 └────────┘              └────────────┘
     │                         │
     │     External Storage   │
     │     (S3/Blob Storage)   │
     └─────────────┬───────────┘
                   │
               ┌───▼────┐
               │ Backup │
               └────────┘

3.4 프로젝트 예시

SW Architecture 예시

4 배포 옵션 선택

4.1 옵션 1: 로컬 개발 환경

# docker-compose.yml
version: '3.8'

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    environment:
      REACT_APP_API_URL: http://localhost:8000

  api:
    build: ./backend
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgresql://user:password@postgres:5432/rag_db
      REDIS_URL: redis://redis:6379
      MILVUS_HOST: milvus
      OPENAI_API_KEY: ${OPENAI_API_KEY}
    depends_on:
      - postgres
      - redis
      - milvus

  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_DB: rag_db
    volumes:
      - postgres_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  milvus:
    image: milvusdb/milvus:latest
    environment:
      COMMON_STORAGETYPE: local
    ports:
      - "19530:19530"
      - "9091:9091"
    volumes:
      - milvus_data:/var/lib/milvus

volumes:
  postgres_data:
  redis_data:
  milvus_data:

4.2 옵션 2: Kubernetes 클러스터 (프로덕션)

# kubernetes deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service
  namespace: rag-system
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-service
  template:
    metadata:
      labels:
        app: api-service
    spec:
      containers:
      - name: api
        image: my-registry.azurecr.io/api-service:1.0.0
        ports:
        - containerPort: 8000
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-credentials
              key: url
        - name: OPENAI_API_KEY
          valueFrom:
            secretKeyRef:
              name: openai-key
              key: key
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8000
          initialDelaySeconds: 5
          periodSeconds: 5
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 100
            podAffinityTerm:
              labelSelector:
                matchExpressions:
                - key: app
                  operator: In
                  values:
                  - api-service
              topologyKey: kubernetes.io/hostname

---
apiVersion: v1
kind: Service
metadata:
  name: api-service
  namespace: rag-system
spec:
  type: LoadBalancer
  selector:
    app: api-service
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8000

4.3 옵션 3: 클라우드 관리형 서비스

AWS 기반:

- Frontend: CloudFront + S3 + Lambda@Edge
- API: ECS/Fargate with Application Load Balancer
- Vector DB: Pinecone (관리형) 또는 SageMaker Vector Store
- Text DB: RDS PostgreSQL
- Cache: ElastiCache Redis
- Monitoring: CloudWatch + X-Ray
- Storage: S3

Azure 기반:

- Frontend: Azure Static Web Apps
- API: App Service 또는 Container Instances
- Vector DB: Azure Cognitive Search
- Text DB: Azure Database for PostgreSQL
- Cache: Azure Cache for Redis
- Monitoring: Application Insights
- Storage: Blob Storage

GCP 기반:

- Frontend: Cloud Storage + CDN
- API: Cloud Run 또는 App Engine
- Vector DB: Vertex AI Vector Search
- Text DB: Cloud SQL (PostgreSQL)
- Cache: Memorystore (Redis)
- Monitoring: Cloud Logging + Cloud Trace
- Storage: Cloud Storage

5 Physical Architecture 명세서

5.1 서버 요구사항

API Service Pod:
  CPU: 1000m (1 vCPU)
  Memory: 1Gi
  Disk: 20Gi (ephemeral)
  Network: 1 Gbps
  
Worker Pod:
  CPU: 2000m (2 vCPU)
  Memory: 2Gi
  Disk: 50Gi (ephemeral)
  Network: 1 Gbps

PostgreSQL:
  CPU: 2000m (2 vCPU)
  Memory: 4Gi
  Disk: 500Gi (persistent, SSD)
  Network: 1 Gbps
  High Availability: 2 replicas + 1 standby

Milvus Vector DB:
  CPU: 4000m (4 vCPU)
  Memory: 8Gi
  Disk: 1Ti (persistent, SSD)
  Network: 10 Gbps (권장)
  Replication: 3

Redis Cache:
  CPU: 1000m (1 vCPU)
  Memory: 8Gi
  Disk: 100Gi (persistent)
  Network: 1 Gbps
  Cluster: 3 nodes

5.2 네트워크 구성

방화벽 규칙:

Ingress:
  - 443 (HTTPS): 외부 → Load Balancer (모든 트래픽)
  - 80 (HTTP): 외부 → Load Balancer (HTTPS 리다이렉트)

Internal (VPC/VNet 내부):
  - 8000: API Service pods
  - 5432: PostgreSQL
  - 19530: Milvus gRPC
  - 9091: Milvus HTTP
  - 6379: Redis
  - 9090: Prometheus (모니터링)

Egress:
  - 443: OpenAI API (외부 인터넷)
  - 25, 587: Email 서비스 (알림용)

5.3 보안 구성

SSL/TLS:
  - 인증서: Let's Encrypt (자동 갱신)
  - TLS 버전: 1.2 이상
  - 암호화 알고리즘: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  
데이터 암호화:
  - 전송 중: TLS 1.2+
  - 저장: Database encryption (모든 DB)
  - API Keys: AWS Secrets Manager / Azure Key Vault

접근 제어:
  - 인증: OAuth 2.0 / JWT
  - 인가: RBAC (Role-Based Access Control)
  - 감사: 모든 API 호출 로깅
  
DDoS 방어:
  - AWS Shield / Azure DDoS Protection
  - Rate limiting: 100 req/sec per IP

5.4 모니터링 및 로깅

메트릭 수집:
  - 도구: Prometheus + Grafana
  - 수집 대상:
    - API 응답시간 (p50, p95, p99)
    - 데이터베이스 쿼리 시간
    - 벡터 검색 지연시간
    - 캐시 히트율
    - CPU, 메모리, 디스크 사용률
    - 네트워크 대역폭

로그 수집:
  - 도구: ELK Stack (Elasticsearch + Logstash + Kibana) 또는 Azure Monitor
  - 수집 대상:
    - 애플리케이션 로그 (DEBUG, INFO, WARNING, ERROR)
    - 접근 로그 (HTTP 요청)
    - 데이터베이스 쿼리 로그
    - 에러 추적 (Sentry)

알림:
  - 임계값 초과 시 Slack/Email 알림
  - 에러율 > 1% → 즉시 알림
  - 응답시간 p95 > 2초 → 경고
  - 디스크 사용량 > 80% → 경고

5.5 재해 복구 (DR) 계획

Backup 전략:
  - 데이터베이스: 1시간마다 스냅샷
  - 벡터 DB: 4시간마다 스냅샷
  - 백업 저장소: 다른 리전 (지역 중복)
  - 보관 기간: 30일

복구 목표 (RTO/RPO):
  - RTO (복구시간): 1시간
  - RPO (데이터손실범위): 1시간

페일오버:
  - Active-Standby 구성 (자동 페일오버)
  - Health check: 30초마다
  - 페일오버 시간: < 2분

테스트:
  - 월 1회 DR 드릴 실시
  - 복구 절차 문서화 및 검증

6 Physical Architecture 체크리스트

6.1 기술 스택

6.2 인프라 설계

6.3 배포 및 운영

6.4 모니터링 및 로깅

6.5 보안

6.6 재해 복구

6.7 비용 최적화

7 실제 예시: RAG 시스템 Physical Architecture

7.1 프로토타입 (로컬 개발)

기술 스택:
  - Frontend: React 18 + TypeScript
  - Backend: FastAPI (Python 3.11)
  - Vector DB: Chroma (로컬, 인메모리)
  - Text DB: SQLite (프로토타입)
  - Cache: Python 딕셔너리 (인메모리)
  
배포: docker-compose (로컬)
  - 3개 컨테이너 (Frontend, API, Vector DB)
  - 통신: localhost:8000
  
리소스:
  - CPU: 4 cores
  - RAM: 8GB
  - Storage: 50GB
  
성능 목표:
  - 응답시간: < 500ms
  - 동시 사용자: 1-5명

7.2 MVP (초기 프로덕션)

기술 스택:
  - Frontend: React 18 + Vercel 배포
  - Backend: FastAPI (Python 3.11) on AWS ECS
  - Vector DB: Chroma (Persistent)
  - Text DB: RDS PostgreSQL (db.t3.micro)
  - Cache: ElastiCache Redis (cache.t3.micro)
  
배포: AWS
  - ECS Fargate (1 vCPU, 2GB RAM, 2 tasks)
  - Application Load Balancer
  - RDS Single-AZ
  
리소스 (월 비용 예상):
  - Frontend 호스팅: $0 (Vercel Free)
  - ECS Fargate: $50 (compute)
  - RDS PostgreSQL: $20 (db.t3.micro)
  - ElastiCache Redis: $15 (cache.t3.micro)
  - Data Transfer: $10
  - 총 약 $95/월
  
성능 목표:
  - 응답시간: < 1초 (p95)
  - 동시 사용자: 10-50명
  - 처리량: 100 req/sec

7.3 엔터프라이즈 프로덕션

기술 스택:
  - Frontend: React 18 + Azure Static Web Apps
  - Backend: Spring Boot on Azure Container Instances
  - Vector DB: Milvus (3-node cluster)
  - Text DB: Azure Database for PostgreSQL (Flexible Server)
  - Cache: Azure Cache for Redis (Standard C1)
  - Orchestration: Azure Container Registry + GitHub Actions
  
배포: Azure Kubernetes Service (AKS)
  - 3 node cluster (VM 크기: Standard_D4s_v3)
  - API replicas: 3 (1 vCPU, 2GB each)
  - Worker replicas: 2 (2 vCPU, 4GB each)
  - Ingress: Application Gateway
  
리소스 (월 비용 예상):
  - AKS cluster: $200 (노드)
  - Managed disks: $100
  - PostgreSQL: $150 (Flexible Server)
  - Redis: $100 (Standard)
  - Milvus: $300 (managed)
  - Monitoring/Logging: $50
  - 총 약 $900/월
  
성능 목표:
  - 응답시간: < 200ms (p95)
  - 동시 사용자: 1000+명
  - 처리량: 1000 req/sec
  - 가용성: 99.9%
  - RTO: 1 hour
  - RPO: 1 hour

8 Physical 배포 체크리스트

배포 전 최종 확인:

8.1 프리플라이트 체크

8.2 배포 검증

8.3 운영 준비

9 정리

Physical Architecture는:

  1. 기술 구체화: Logical을 실제 구현 가능한 형태로 변환
  2. 배포 가능: 개발팀이 직접 배포하고 운영 가능
  3. 비용 최적화: 리소스와 비용을 명확하게 정량화
  4. 운영성: 모니터링, 로깅, 확장 전략 포함
  5. 문서화: 개발팀이 따를 수 있는 명확한 가이드

Conceptual → Logical → Physical 세 계층을 거쳐 설계하면, 최상위 비즈니스 요구사항부터 최하위 구현 세부사항까지 일관되고 체계적인 아키텍처를 구축할 수 있다.

Subscribe

Enjoy this blog? Get notified of new posts by email: