동시성

핵심 인사이트 (3줄 요약)

  1. 본질: 동시성 원칙은 애플리케이션을 여러 독립적 프로세스(또는 스레드)로 구성하여, 각각이 동시에 처리할 수 있는 요청 수를 늘리는 것이 아니라 프로세스 인스턴스를 늘려 전체 처리량을 극대화해야 한다는 12팩터 앱의 제8원칙이다.
  2. 가치: 동시성 원칙을 적용하면 트래픽 변동에 유연하게 대응할 수 있고, 특정 인스턴스 장애가 전체 서비스에 영향을 주지 않으며, 시스템 리소스를より 효율적으로 활용할 수 있다.
  3. 융합: 컨테이너 오케스트레이션(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원칙으로, 시스템의処理能力と安定性を向上させる 데 중요한 설계 원칙이다. 웹 요청 처리와后台작업을 분리하고, 필요에 따라 프로세스를 수평 확장할 수 있도록 설계함으로써, 트래픽 변동에 유연하게 대응하고 리소스를 효율적으로 활용할 수 있는 시스템을 구축할 수 있다.

📢 섹션 요약 비유: 동시성 원칙은"레스토랑의 좌석 배치 전략"과 같다. 한 명씩만 앉을 수 있는 작은 테이블(단일 프로세스) 대신, 필요에 따라 합석이 가능한 큰 테이블(프로세스 복제)을 사용하고, 손님이 늘어나면 테이블을 더 늘리고(스케일 아웃), 줄어들면 테이블을 합치거나 줄이면(스케일 인) 공간을 효율적으로 활용할 수 있다.