테스트 병렬화의 한계 — 16 worker 가 아니라 7 worker 에서 멈춘 이유

"테스트가 느려서 병렬화" 라는 답은 *때로 맞지 않는다*. 병렬도를 늘리며 측정한 6개월의 데이터.

백재민
백재민
CollabOps 창업자
테스트 병렬화의 한계 — 16 worker 가 아니라 7 worker 에서 멈춘 이유

작년에 테스트 시간이 17분 이었다. 너무 길었다. 병렬화 가 답이라고 믿고 worker 를 4 → 8 → 16 으로 늘렸다.

4 worker:   17 분
8 worker:   11 분
16 worker:  10 분

16 worker 에서 11 → 10 분 으로 1 분만 줄었다. 그런데 비용은 16 worker 가 4 worker 의 4배. 어디서 수확체감 이 시작됐는지를 6개월간 측정했다.

테스트 병렬화의 4가지 병목

테스트가 worker 수에 비례 해 빨라지지 않는 이유는 4가지 병목 중 하나에 걸려서다.

병목 1 — 공유 리소스 (DB, 캐시)

테스트가 같은 DB 인스턴스를 공유하면, 병렬도 늘려도 DB 가 직렬화 지점 이 됨. 우리 사례 — Postgres 단일 인스턴스. 8 worker 까지는 OK, 16 worker 에서 connection pool 포화.

진단: 병렬도를 늘리며 DB latency 측정. 평균 latency 가 증가 하기 시작하는 지점이 병목 시작.

병목 2 — 느린 셋업고정 비용

각 worker 가 부팅 + 의존성 설치 + DB 마이그레이션고정 시간 소비. worker 4개일 때 셋업이 3분, 16개여도 셋업이 3분. 고정 비용은 병렬화로 안 줄어든다.

우리 사례 — 17분 중 3분이 셋업. 16 worker 에서도 셋업 3분. 실제 테스트 실행은 14분 → 7분 으로 줄었지만 총 시간 17 → 10분. 셋업이 minimum 시간을 정함.

해결: worker 사전 부팅 (warm pool), 의존성 캐싱, DB 스냅샷 reuse. 셋업을 3분 → 30초 로 줄이면 최대 절감 효과 가 나옴.

병목 3 — 불균형 분산 — long pole

worker 들이 균등하게 일을 받지 않는다. 한 worker 가 유난히 느린 테스트 그룹 을 받으면 다른 worker 가 기다린다.

우리 데이터 — 16 worker 중 15개가 4분에 끝나고 1개가 9분. 총 시간은 9분. 다른 15개는 기다림 시간.

해결: 테스트를 historical 실행 시간으로 분배 (간단한 분할이 아니라). 또는 work-stealing — 빨리 끝난 worker 가 다른 worker 의 미완 잡을 가져감.

병목 4 — 공유 외부 의존성

테스트가 외부 API (Stripe sandbox 등) 를 호출하면, 그 API 의 rate limit 이 병목.

우리 사례 — 결제 테스트 그룹이 Stripe sandbox 의 분당 50 요청 한도에 걸림. 병렬도 8 까지는 OK, 16 부터 rate limit retry역효과.

해결: 외부 API call 을 mock 으로 대체 또는 vendor-specific high-rate sandbox 요청.

우리 한계 — 7 worker 에서 수렴

위 4 병목을 분석 한 후 다시 측정:

worker 수 | 총 시간 | 병목
─────────┼────────┼──────────────────
1        | 38 분  | (없음)
2        | 22 분  | (없음)
4        | 14 분  | DB pool 시작
7        | 9 분   | 셋업 + DB 임계점
8        | 8 분   | DB pool 포화 시작
16       | 7.5 분 | 셋업 dominant
32       | 7.5 분 | 셋업 only — 병렬화 *무의미*

7~8 worker 에서 최대 효율. 그 이상은 비용만 늘고 시간은 거의 안 줄어듦. 이걸 처음부터 알면 CI 비용을 절반으로.

더 빠르게 가려면 — worker 수가 아니라 셋업

7~8 worker 에서 멈춘 후, 우리 다음 작업은 worker 추가가 아니라 셋업 단축. 4가지 작업:

  1. DB 스냅샷 reuse — 매 worker 가 마이그레이션 X, 미리 만든 snapshot 마운트
  2. 의존성 cache — 모든 worker 가 같은 cache 공유
  3. worker warm pool — 항상 5개 worker 를 실행 중 으로 유지
  4. 테스트 데이터 fixture 사전 로드 — 첫 테스트 실행 전에 미리

이 4가지로 총 시간 9분 → 4분. 같은 7 worker 로 2배 절감. worker 수 보다 셋업훨씬 큰 lever.

누가 이 글을 읽으면 좋은가

CI 테스트 시간을 worker 늘려서 단축하려는 모든 팀. 위 4 병목 중 어느 게 활성화되어 있는지 측정 없이 늘리면, 16 worker 에서도 7 worker 와 비슷한 시간 을 얻고 4배 비용 을 낸다.

태그#testing#ci#performance#parallelization#devops