동시성
핵심 인사이트 (3줄 요약)
- 본질: 동시성 원칙은 애플리케이션을 여러 독립적 프로세스(또는 스레드)로 구성하여, 각각이 동시에 처리할 수 있는 요청 수를 늘리는 것이 아니라 프로세스 인스턴스를 늘려 전체 처리량을 극대화해야 한다는 12팩터 앱의 제8원칙이다.
- 가치: 동시성 원칙을 적용하면 트래픽 변동에 유연하게 대응할 수 있고, 특정 인스턴스 장애가 전체 서비스에 영향을 주지 않으며, 시스템 리소스를より 효율적으로 활용할 수 있다.
- 융합: 컨테이너 오케스트레이션(Kubernetes HPA), 오토스케일링, 그리고 마이크로서비스架构의 서비스 복제와 긴밀하게 연결되어 있다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
동시성(Concurrency)는 컴퓨터 과학에서 동일한 시간대에複数の処理が実行される能力を 의미한다. 소프트웨어 시스템의文脈では、 동시성은通常 두 가지 접근법으로 구현된다: 스레드 기반的多行程処理(マルチスレッド)와 프로세스 기반의水平 확장(Scale-out)이다.
전통적인 웹 애플리케이션에서는Apache Prefork MPM이나 IIS의 프로세스 모델처럼, 하나의巨大한 프로세스가 모든 요청을 처리하려 했던 경우가 많았다. 이 방식은 다음과 같은 한계를 가졌다:
- 확장성의 한계: 단일 프로세스의処理能力には上限があり、 이를 넘어서면 전체 시스템을 업그레이드해야 했다(Vertical Scaling, 수직 확장).
- 안정성 문제: 단일 프로세스가 메모리 누수나 예외로 종료되면 전체 서비스가 중단된다.
- 리소스 활용 비효율: 하나의 거대한 프로세스가 모든类型的 요청을処理하려다 보니, 일부 요청만 CPU 집약적이고 나머지는 I/O 대기가 되는 불균형이 발생한다.
12팩터 앱의 동시성 원칙은 이러한問題を解決하기 위해"프로세스 모델을 통한 수평 확장"을 권장한다. 즉, 하나의 거대한 프로세스를 여러 작은 프로세스로 분리하고, 각 프로세스가 자신의工作任务에 집중하게 함으로써 전체 시스템의処理能力と安定性を向上させる 것이다.
아래 다이어그램은 전통적 단일 프로세스 모델과 동시성 원칙의 차이를 보여준다.
[단일 프로세스 모델 vs 동시성 원칙]
❌ 전통적 단일 프로세스 모델 (한계)
┌─────────────────────────────────────────────────────────────┐
│ │
│ 거대한 단일 프로세스 (Vertical Scaling 만으로 대응) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 모든 요청 ──▶ [ 단일 프로세스 ] ──▶ 처리 완료 │ │
│ │ │ │ │ │
│ │ │ CPU 사용률 100% │ │
│ │ │ │ │ │
│ │ │ 메모리 과부하 ──▶ 서비스 중단 │ │
│ │ │ │ │
│ │ │ 한계에 도달하면 시스템 전체 업그레이드 │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 문제: │
│ - 확장에 한계 (Vertical Scaling은 비용이指数的に増加) │
│ - 단일 장애점 (SPOF) │
│ - 리소스 활용 비효율 │
└─────────────────────────────────────────────────────────────┘
✓ 동시성 원칙 (Scale-out)
┌─────────────────────────────────────────────────────────────┐
│ │
│ 여러 경량 프로세스 (Horizontal Scaling으로 유연하게 대응) │
│ │
│ 요청 ──▶ [프로세스 1] │
│ 요청 ──▶ [프로세스 2] ──▶ Workers (배경 작업) │
│ 요청 ──▶ [프로세스 3] │
│ 요청 ──▶ [프로세스 N] ... │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 로드밸런서 (Traffic Distributor) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 장점: │
│ - 프로세스 추가만으로處理능력 증가 (선형적 확장) │
│ - 특정 프로세스 장애 ≠ 전체 서비스 중단 (격리성) │
│ - CPU/메모리 집약적 작업을 별도 프로세스로 분리 가능 │
│ - 트래픽 변화에 유연하게 대응 │
└─────────────────────────────────────────────────────────────┘
📢 섹션 요약 비유: 동시성 원칙은"은행 창구의 증설"와 같다. 과거에는 한 명은행원(단일 프로세스)이 모든 업무를 처리하려 했으나, 고객 대기 시간이 길어지고 은행원이 과로로 쓰러지면(장애) 업무가 마비되었다. 그러나 창구를 여러 개(프로세스 동시 실행)로 늘리면, 고객이 분산되어 대기 시간이 줄어들고, 한 창구가 고장 나도 다른 창구가 업무를 계속 처리한다.
Ⅱ. 아키텍처 및 핵심 원리 (Deep Dive)
동시성 원칙을 구현하는 다양한 방법과 그 내부 동작 메커니즘을 분석한다.
| 동시성 유형 | 구현 방식 | 적합한 작업 | 예시 |
|---|---|---|---|
| 프로세스 복제 | 여러 프로세스 인스턴스 실행 | Web 요청 처리 | Node.js cluster 모듈, Puma (Ruby) |
| 워커 프로세스 | 별도 백그라운드 프로세스 | 이메일 전송, 이미지 처리 | Sidekiq (Ruby), Celery (Python) |
| 스레드 | 하나의 프로세스 내 여러 스레드 | I/O 대기가 많은 작업 | Java threading, Go goroutine |
| 이벤트 루프 | 단일 스레드, 비동기 I/O | 높은 동시성, 낮은 리소스 | Node.js, Nginx (event-driven) |
| 컨테이너 오토스케일링 | 파드 수 동적 조절 | 트래픽 변동 대응 | Kubernetes HPA |
아래는 동시성 원칙이 실제 시스템에서 어떻게 구현되는지 보여주는 ASCII 다이어그램이다.
[동시성 원칙의 실제 구현: Node.js cluster 모듈]
┌─────────────────────────────────────────────────────────────┐
│ 마스터 프로세스 (Master) │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ const cluster = require('cluster'); │ │
│ │ const numCPUs = require('os').cpus().length; │ │
│ │ │ │
│ │ if (cluster.isMaster) { │ │
│ │ for (let i = 0; i < numCPUs; i++) { │ │
│ │ cluster.fork(); // 워커 프로세스 생성 │ │
│ │ } │ │
│ │ } else { │ │
│ │ // 워커 프로세스: HTTP 서버 실행 │ │
│ │ app.listen(PORT); │ │
│ │ } │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌──────────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Worker 1│ │ Worker 2│ │ Worker N│
│ (CPU 1) │ │ (CPU 2) │ │ (CPU N) │
│ :3000 │ │ :3000 │ │ :3000 │
└─────────┘ └─────────┘ └─────────┘
│ │ │
└──────────────────────┼──────────────────────┘
│
▼
┌─────────────┐
│ 로드밸런서 │
│ (요청 분배) │
└─────────────┘
[동시성 원칙의 실제 구현: Kubernetes HPA]
┌─────────────────────────────────────────────────────────────┐
│ Kubernetes Horizontal Pod Autoscaler (HPA) │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ apiVersion: autoscaling/v2 │ │
│ │ kind: HorizontalPodAutoscaler │ │
│ │ metadata: │ │
│ │ name: myapp-hpa │ │
│ │ spec: │ │
│ │ scaleTargetRef: │ │
│ │ apiVersion: apps/v1 │ │
│ │ kind: Deployment │ │
│ │ name: myapp │ │
│ │ minReplicas: 2 ← 최소 복제본 수 │ │
│ │ maxReplicas: 10 ← 최대 복제본 수 │ │
│ │ metrics: │ │
│ │ - type: Resource │ │
│ │ resource: │ │
│ │ name: cpu │ │
│ │ target: │ │
│ │ type: Utilization │ │
│ │ averageUtilization: 70 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
트래픽 증가 시:
CPU 사용률 70% 초과 → 파드 2개 → 4개 → 8개 ... 자동 확장
CPU 사용률 50% 이하 → 파드 수 점진적 축소
📢 섹션 요약 비유: 동시성 원칙의 구현은"음식 배달 시스템의 확대"와 같다. 배달 원이 한 명(단일 프로세스)일 때는 주문을 많이 받으면 배달이 지연되고, 한 명씩만 추가해야 했다. 그러나(Uber Eats 등) 플랫폼을 통해 여려 배달원(여러 프로세스/파드)을 동시에 운용하면, 주문이 증가할 때 배달원을 더 많이 투입하고, 주문이 줄면 배달원을 줄일 수 있어 효율적인 운영이 가능하다.
Ⅲ. 융합 비교 및 다각도 분석 (Comparison & Synergy)
동시성 원칙은 현대적인 클라우드 네이티브 아키텍처와 긴밀하게 연결되어 있으며, 다른 기술과 어떻게 시너지를 발생하는지 분석한다.
| 관련 기술 | 동시성 원칙과의 관계 | 시너지 효과 |
|---|---|---|
| 컨테이너 (Docker) | 컨테이너 격리로 프로세스 수준 동시성実現 | 자원 격리 + 유연한 확장 |
| 쿠버네티스 (K8s) | HPA (Horizontal Pod Autoscaler)로 동적 확장 | CPU/메모리 기반 자동 스케일링 |
| 마이크로서비스 (MSA) | 각 서비스가 독립적으로 확장 가능 | 서비스별 최적 확장 전략 |
| 비동기 메시징 | 워커 프로세스가 백그라운드 작업 처리 | 요청/응답과后台작업 분리 |
| 이벤트驱动 아키텍처 | 이벤트에 따라 처리 인스턴스 동적 조절 | 트래픽 패턴에맞는 확장이 가능 |
동시성 원칙과 오토스케일링의 결합은 현대 클라우드 네이티브 환경에서 가장 강력한 성능 최적화 패턴이다.
[동시성 + 오토스케일링: 트래픽 변화에 유연하게 대응]
트래픽
│
│ ╱╲
│ ╱ ╲
│ ╱ ╲
│ ╱ ╲ ← 파드 추가 (Scale-out)
│ ╱ ╲
│ ╱ ╲
│ ╱ ╲___──────────────
│ ╱ ← 트래픽 감소 시
│ ╱ 파드 감소 (Scale-in)
└──────────────────────────────────────────────────────▶ 시간
│ │ │ │ │ │ │ │
1개 2개 3개 4개 3개 2개 1개 1개 (파드 수)
📢 섹션 요약 비유: 동시성과 오토스케일링의 결합은"계절에 따른 음식 재료 준비"와 같다. 여름에는 사용량이 늘어난다고 더 많은 재료를 사전에 준비하고, 겨울에는 사용량이 줄면 재료를 줄이며, 항상 적절한 양을 유지한다. 이렇게 하면 재고 낭비도 줄이고 고객 불만도 예방할 수 있다.
Ⅳ. 실무 적용 및 기술사적 판단 (Strategy & Decision)
동시성 원칙을 실무에 적용할 때 흔히 발생하는 문제와 해결 방안을 분석한다.
1. 실무 의사결정 시나리오
-
시나리오 A:CPU를 많이 사용하는 작업(画像処理)과 I/O를 많이 사용하는 작업(API 호출)이 동일한 프로세스에서 수행되어 병목이 발생하는 상황
- 상황: 단일 프로세스에서 동기적으로 이미지 리사이징과 외부 API 호출을 모두 처리하여, 이미지 처리 대기 시간 때문에 API 응답까지 지연됨.
- 판단: 동시성 원칙에 따라 두 작업을 별도 프로세스로 분리해야 한다. 이미지 처리는CPU 워커(별도 프로세스/서버)로 분리하고, API 호출은 웹 프론트엔드(또는 event-driven)로 처리하여 각각 최적화된资源配置可以实现。
-
시나리오 B: 백그라운드 작업(이메일 전송, 로그 처리)이 웹 요청 처리와混재되어 성능 저하가 발생하는 상황
- 판단: 백그라운드 작업은 워커 프로세스(예: Sidekiq, Celery)가 전용으로 처리하고, 웹 요청은 웹 프로세스가処理する。 이렇게 하면 웹 응답 시간이 백그라운드 작업의影響을 받지 않는다.
[동시성 설계 패턴: 프로세스 유형 분리]
┌─────────────────────────────────────────────────────────────┐
│ 웹 프로세스 (Web Process) │
│ - HTTP 요청/응답 처리에特化 │
│ - 빠른 응답 시간 목표 │
│ - CPU/메모리 적당한 수준 │
│ - 수평 확장 가능 │
└─────────────────────────────────────────────────────────────┘
│ 메시지 큐
▼
┌─────────────────────────────────────────────────────────────┐
│ 워커 프로세스 (Background Worker Process) │
│ - 이메일 전송, 이미지/동영상 처리 등后台작업 전문 처리 │
│ - 배치 처리 가능 │
│ - 웹 프로세스와 독립적 확장 │
│ - 필요시大量 인스턴스로 급증 처리 가능 │
└─────────────────────────────────────────────────────────────┘
예: Ruby on Rails + Sidekiq
- Web: Puma (동시 요청 처리)
- Worker: Sidekiq (백그라운드 작업 처리)
📢 섹션 요약 비유: 동시성을위한 프로세스 분리는"식당의 주방과 배달 시스템 분리"와 같다. 주방(웹 프로세스)은 요리를 하는 데 집중하고, 배달(워커 프로세스)은 별도의 배달원이 담당한다. 만약 주방장이 요리도 하고 배달도 하면 양쪽 다 실력이 분산되고, 배달이 지연되면 주방장의 집중도도 떨어진다. 그러나 분리되면 각자 전문성에 집중할 수 있다.
Ⅴ. 기대효과 및 결론 (Future & Standard)
동시성 원칙의 올바른 적용은 시스템의処理能力、応答速度、可用性을 크게 향상시킨다.
| 관점 | 단일 프로세스 (AS-IS) | 동시성 원칙 적용 (TO-BE) | 핵심 성과 지표 |
|---|---|---|---|
| 처리량 | 단일 프로세스 처리 능력에 한계 | 인스턴스 추가만으로 선형적 확장 | 최대 TPS 증가 |
| 응답 시간 | 트래픽 증가 시 응답 시간 급증 | 트래픽 분산으로 일관된 응답 시간 | P50/P95/P99 레이턴시 개선 |
| 가용성 | 단일 장애점 (SPOF) | 프로세스 격리로 части故障許容 | 서비스 가용성 향상 |
| 자원 효율 | 하나의 거대한 프로세스, 자원 낭비 가능 | 필요한 만큼만 프로세스 실행 | 평균 CPU 활용률 향상 |
| 비용 효율 | 항상最大構成으로 운영 (과다Provision) | 실제 트래픽에 비례한 Provisioning | 인프라 비용 최적화 |
미래 전망 및 결론: 동시성 원칙은 서버리스(serverless) 컴퓨팅으로의 진화에서 더욱激进적으로 적용되고 있다. AWS Lambda, Azure Functions, Google Cloud Functions와 같은 FaaS 환경에서는 개발자가 프로세스나 컨테이너를管理하지 않고, 대신 함수 호출 수에 따라 자동으로処理능력이 확장/축소된다. 이것은 동시성 원칙의 궁극적 형태라 할 수 있다.
결론적으로, 동시성 원칙은 12팩터 앱의 제8원칙으로, 시스템의処理能力と安定性を向上させる 데 중요한 설계 원칙이다. 웹 요청 처리와后台작업을 분리하고, 필요에 따라 프로세스를 수평 확장할 수 있도록 설계함으로써, 트래픽 변동에 유연하게 대응하고 리소스를 효율적으로 활용할 수 있는 시스템을 구축할 수 있다.
📢 섹션 요약 비유: 동시성 원칙은"레스토랑의 좌석 배치 전략"과 같다. 한 명씩만 앉을 수 있는 작은 테이블(단일 프로세스) 대신, 필요에 따라 합석이 가능한 큰 테이블(프로세스 복제)을 사용하고, 손님이 늘어나면 테이블을 더 늘리고(스케일 아웃), 줄어들면 테이블을 합치거나 줄이면(스케일 인) 공간을 효율적으로 활용할 수 있다.