Skip to content

Final Architecture

JJong-03 edited this page Mar 13, 2026 · 3 revisions

Final Architecture

이 문서는 플랫폼의 통합 아키텍처 개요이다. 인프라, 애플리케이션, 실행 모델, 관측성, 배포 파이프라인을 하나의 흐름으로 연결한다.

각 주제의 상세 설명은 개별 문서에 있으며, 이 문서는 요약과 링크 허브 역할을 한다.


1. Architecture Overview

Architecture Overview

이 시스템의 핵심 개념:

1 Backtest = 1 Kubernetes Job

검증 완료된 레거시 백테스트 엔진을 한 줄도 수정하지 않고, Docker 컨테이너로 감싸 Kubernetes Job으로 실행하는 클라우드 네이티브 플랫폼이다.

구성 요소 역할 설계 원칙
Immutable Engine 백테스트 로직 실행 (수정 금지) Engine Immutability (Design Principles)
Stateless Web 요청 검증, run_id 발급, Job 생성, 상태 조회 Stateless Architecture (Design Principles)
K8s Worker Job 엔진 실행, 결과 저장 후 종료 (ephemeral) Web↔Worker 책임 분리 (App Architecture)
MySQL 모든 결과의 단일 진실 공급원 Source of Truth (Design Principles)
GitOps (Argo CD) 선언형 배포, drift 자동 복구 Git = Infrastructure (CI_CD_GitOps)

2. High-Level System Architecture

Final Architecture

Architecture Layers

Layer 구성 요소 역할
Developer / GitOps GitHub Actions (CI), Argo CD (CD) Test → Build → Push → Auto-sync 배포
Edge & Config Ingress, ConfigMap, Secret 트래픽 라우팅, 환경 설정 주입
Web Service Flask Deployment (Stateless) 요청 검증, run_id 발급, Job 오케스트레이션
Worker Jobs K8s Job (Ephemeral Pod) 엔진 실행, Adapter 파생 데이터 생성
Persistence MySQL StatefulSet + PVC Canonical data 영구 저장
Observability Structured Logs, Prometheus, Grafana run_id 추적 + 메트릭 기반 모니터링

3. End-to-End Request Flow

User Request
  → Flask Web (Stateless)
    → Input validation
    → run_id (UUID4) 발급
    → MySQL INSERT (status=PENDING)
    → K8s Job 생성 (worker-<run_id_short>)
      → Worker Pod 시작
        → status=RUNNING 전이
        → data_hash 계산 (SHA-256)
        → Immutable Engine 실행
        → Adapter 파생 데이터 생성
        → MySQL UPDATE (status=SUCCEEDED, metrics, equity_curve, trades)
      → Worker Pod 종료
  → Client polls GET /status/<run_id>
    → MySQL SELECT → 결과 반환

상태 머신: PENDING → RUNNING → SUCCEEDED / FAILED (단방향, 되돌릴 수 없음)

  • user_error (잘못된 입력) → Web이 PENDING → FAILED 처리, Job 미생성 (HTTP 400)
  • system_error (런타임 장애) → Worker 또는 Web이 FAILED 처리 (HTTP 500)

상태 머신, sequence diagram, Job 규격 상세 → Execution Lifecycle


4. Architecture Layers

4.1 Infrastructure Layer

Kubernetes 클러스터 위에 namespace stock-backtest로 격리된 환경을 구성한다.

  • Web Deployment (Flask + Gunicorn, Stateless)
  • MySQL StatefulSet + PersistentVolumeClaim
  • Worker Job (ephemeral, backoffLimit: 1, ttlSecondsAfterFinished: 86400)
  • RBAC: namespace-scoped Role (jobs.batch에 대해 create/get/list/delete만 허용)
  • Ingress (NGINX): 외부 트래픽 라우팅

K8s 리소스 토폴로지, 계층 구조, 보안/스케일링 전략 → Infra Architecture

4.2 Application Layer

Web (app.py)                         Worker (worker.py)
├── 요청 검증 + run_id 발급           ├── 엔진 실행 (backtest/engine.py)
├── PENDING INSERT                    ├── Adapter 파생 데이터 생성
├── JobLauncher → K8s Job 생성        ├── MySQL 결과 저장
└── /status/<run_id> 상태 조회        └── SUCCEEDED/FAILED 전이 후 종료

JobLauncher 추상화: JOB_LAUNCHER_MODE 환경변수로 Local(subprocess) / K8s(BatchV1Api) 전환. Adapter Layer: 엔진 출력에서 drawdown, portfolio chart, win_rate 등을 파생. 엔진 수정 없이 UI 데이터를 확장한다.

모듈 구조, 의존 방향, Adapter 범위 → App Architecture

4.3 Data Layer

MySQL이 모든 백테스트 결과의 단일 진실 공급원이다.

  • MUST persist: run_id, metrics, equity_curve, trades, data_hash, image_tag, timestamps
  • SHOULD persist: chart_base64 (backward compatibility / performance optimization)
  • MUST NOT persist: drawdown_curve, portfolio charts (Adapter에서 on-demand 생성)

K8s Job 객체의 수명과 MySQL 감사 이력은 완전히 독립적이다. Job이 삭제되어도 run_id로 전체 실행 이력을 조회할 수 있다.

4.4 Observability Layer

두 계층으로 구성된다.

계층 구현 목적
Structured Logging stdout/stderr + [run_id=<UUID>] 요청 단위 전 구간 추적 (Rule 8 필수)
Metrics Prometheus + Grafana 시스템 건강 지표, SLO 모니터링
  • Web Pod의 /metrics 엔드포인트를 ServiceMonitor가 15초 간격으로 scrape
  • run_id는 Prometheus label로 사용하지 않음 (cardinality 제한)

메트릭 정의, PromQL, Grafana 대시보드 → Observability

4.5 Delivery Layer (CI/CD + GitOps)

git push → GitHub Actions (CI)
  1. pytest
  2. docker build + push :<git-sha-short>
  3. k8s/web-deployment.yaml image tag 업데이트 → commit
                    ↓
Argo CD (CD): k8s/ 디렉터리 감시 → auto-sync → Rolling Update
  • Immutable image tags: :<git-sha-short> (Rule 10)

  • 롤백: git revert → main 반영 → Argo CD 자동 sync

  • CI 파이프라인, GitOps 전략, 롤백 절차 → CI_CD_GitOps

  • 상세 롤백 절차 → Rollback Runbook


5. Core Architectural Principles

원칙 핵심 위반 시 결과
Engine Immutability engine.py 수정 금지. 새 기능은 Adapter 패턴. 재현성 파괴, 테스트 무효화
Stateless Web 파일 I/O 금지, stdout/stderr 로깅만 HPA 수평 확장 불가
Worker-only Execution Web은 오케스트레이션만, 실행은 Worker Web OOM, 실행 격리 실패
GitOps Deployment k8s/ = Source of Truth, 수동 kubectl 금지 배포 이력 추적 불가
run_id Tracing 모든 로그에 [run_id=<UUID>] 포함 분산 환경 디버깅 불가
Reproducibility 동일 입력 → 동일 출력 (4개 식별자) 결과 신뢰성 상실

6. Observability & Traceability

Structured Logging (필수)

모든 컴포넌트(Web, Worker)가 stdout/stderr로 로그를 출력하며, 모든 로그 라인에 [run_id=<RUN_ID>]를 포함한다. kubectl logsgrep으로 전 구간 추적이 가능하다.

Prometheus Metrics (선택 구현)

5개 애플리케이션 메트릭을 /metrics 엔드포인트로 노출한다.

Metric Type 설명
http_requests_total Counter HTTP 요청 수 (method, endpoint, status)
http_request_duration_seconds Histogram 요청 처리 시간
backtest_requests_total Counter 백테스트 제출 수 (rule_type, outcome)
job_launch_success_total Counter Job 생성 성공
job_launch_failure_total Counter Job 생성 실패

Grafana Dashboard

4개 Row, 17개 Panel로 구성된 대시보드가 Web API Health, Backtest Pipeline, Job Orchestration, Infrastructure Health를 시각화한다.

메트릭 상세, PromQL, scrape 설정, 대시보드 구조 → Observability


7. Reproducibility Model

동일한 4개 식별자가 주어지면 엔진은 동일한 결과를 생성해야 한다.

Identifier 역할 저장 위치
data_hash 동일한 시장 데이터 보장 (SHA-256) backtest_results.data_hash
rule_type + params 동일한 전략 로직/파라미터 보장 backtest_results.rule_type, params_json
engine_version 동일한 엔진 코드 버전 보장 image_tag로 표현됨
image_tag 동일한 컨테이너 이미지 및 런타임 환경 보장 backtest_results.image_tag
  • data_hash는 Worker가 엔진 실행 전에 계산한다.
  • engine.py가 불변이므로 engine_version은 실제 저장 시 image_tag로 표현된다.
  • 입력 데이터는 Docker 이미지에 내장되며 read-only로 사용된다.

재현성 식별자, 검증 절차, 저장 경계 → Reproducibility


8. Related Documentation

문서 내용
Infra Architecture K8s 리소스 토폴로지, 계층 구조, 보안/스케일링 전략
App Architecture 모듈 구조, Web↔Worker 책임 경계, JobLauncher, Adapter Layer
Execution Lifecycle 상태 머신, Failure 분류, Job 규격, 생명주기 정책
Observability Prometheus 메트릭, Grafana 대시보드, /metrics 엔드포인트
CI_CD_GitOps CI 파이프라인, GitOps 전략, Image Tag 전략, 롤백
Security Model RBAC, Secret 관리, Network Egress, Input Validation
ERD-Data Model backtest_results 테이블 스키마, 인덱스 전략
Reproducibility 재현성 식별자, 데이터 공급 전략, 저장 경계
Design Principles 8가지 아키텍처 원칙
ADR-Design Decisions 8개 ADR (K8s Job, JSON, Stateless, API, Image Tags 등)

Navigation

← Previous Archive Next →
ADR-Design Decisions Home Infra Architecture

Clone this wiki locally