단순한 병렬화를 넘어 공유 상태 제거부터 동적 큐까지, 7단계로 풀어낸 백엔드 CI 최적화 전략
이 아티클은 채널톡 메인 백엔드 서버의 CI 피드백 속도를 개선하기 위한 7단계의 긴 여정을 담고 있습니다. 작은 서비스에서 병목 패턴을 먼저 파악한 뒤 이를 큰 시스템에 확장 적용하는 전략적 접근을 통해, 복잡한 의존성을 가진 대규모 테스트 환경을 어떻게 효율적으로 병렬화할 수 있는지 구체적인 방법론을 제시합니다.
대규모 통합 테스트와 복잡한 서비스 의존성 때문에 CI가 느려져 고통받는 팀에게 이 아티클을 강력히 추천합니다. 기술적인 해결책뿐만 아니라 문제를 하위 단위로 쪼개고 실험 기반으로 최적의 설정을 찾아가는 시니어 엔지니어의 문제 해결 프로세스를 배울 수 있습니다.
AI 에이전트와 사람의 코드 구현 속도가 빨라졌음에도 불구하고, 36분이 넘는 긴 CI 피드백 시간이 개발 전체의 병목 현상을 초래했습니다. 특히 약 9,800개의 테스트가 포함된 대규모 메인 백엔드 서버에서 공유 데이터베이스 의존성과 중복된 준비 과정으로 인해 병렬 실행이 제한적이었습니다.
공유 상태 제거를 위해 pgtestdb를 도입하여 테스트별 독립 DB 환경을 구축하고, 중복되는 준비(prepare) 과정을 분리하여 아티팩트로 재사용했습니다. 또한 입력 해시 기반 캐싱과 최근 실행 기록을 바탕으로 테스트를 배분하는 동적 큐 시스템을 도입하여 노드 간 실행 불균형을 해소했습니다.
CI 소요 시간을 초기 36.6분에서 중앙값 기준 15분 38초로 약 58% 단축했으며, 캐시 적중 시 최단 10분 40초를 기록했습니다. 테스트 노드 종료 시간 편차를 6분에서 1분 36초로 줄여 자원 효율성을 극대화하고 안정적인 피드백 루프를 확보했습니다.
Trade-off
Go 서비스에 적용한 빌드 캐시는 복원 오버헤드가 절약 시간보다 커서 롤백되었으며, 테스트 러너를 50개까지 늘렸을 때는 이미지 풀링 등 네트워크 병목으로 인해 오히려 전체 실행 시간의 변동성이 커지는 한계가 확인되었습니다.
PostgreSQL의 템플릿 기능을 활용하여 테스트마다 독립적인 데이터베이스 복본을 수 밀리초 내에 생성해주는 도구입니다.
테스트를 고정된 세트로 나누지 않고, 실행 이력을 기반으로 배치들을 만든 뒤 러너들이 큐에서 하나씩 가져가 실행하는 방식입니다.
소스 코드, 종속성 파일, 환경 설정 등을 묶어 해시값을 만들고, 해당 값이 변경되지 않았다면 이전 빌드 결과물을 즉시 재사용하는 기법입니다.