Pichfork의 Refork 기능으로 루비 애플리케이션의 대규모 트래픽 스파이크 해결

[Euruko 2025] “Conquering Massive Traffic Spikes in Ruby Applications with Pitchfork” – Sangyong Sim

작성자
jeff
발행일
2025년 11월 10일

핵심 요약

  • 1 Unicorn 웹 서버의 LIFO(Last-In, First-Out) 요청 처리 방식이 트래픽 스파이크 시 '콜드 워커'를 발생시켜 심각한 성능 저하를 초래했음을 발견했습니다.
  • 2 Pichfork 웹 서버의 refork 기능을 도입하여 이미 워밍업된 워커를 템플릿으로 사용해 모든 워커를 '웜업' 상태로 유지, 지연 시간 급증 문제를 성공적으로 해결했습니다.
  • 3 Pichfork 도입 후 3배 증가한 트래픽에도 불구하고 응답 시간은 안정적으로 유지되었으며, 고객 경험이 크게 향상되었습니다.

도입

Stores Net Shop은 Shopify와 유사한 온라인 상점 구축 및 관리 서비스를 제공하며, '예약 판매' 기능에서 대규모 트래픽 스파이크로 인한 성능 문제를 겪었습니다. 트래픽은 예측 불가능하게 단 몇 초 만에 10배 이상 급증하며 P90 지연 시간이 수 분에 달해 고객 경험에 심각한 영향을 미쳤습니다. 본 발표는 이 문제를 해결하기 위한 여정과 Pichfork 웹 서버의 refork 기능 도입을 통한 해결 과정을 다룹니다.

문제 진단: 유니콘의 요청 처리 불균형

  • 성능 저하의 원인: APM 추적 결과, 데이터베이스나 외부 API 호출이 아닌 루비 애플리케이션 자체의 처리 시간(Ruby processing time)이 트래픽 스파이크 시 급증하는 것으로 나타났습니다. 이는 인프라나 외부 의존성 문제가 아닌, 애플리케이션 내부의 ‘콜드 워커(Cold Worker)’ 현상 때문이었습니다.

  • 콜드 워커 현상: 대규모 루비 애플리케이션은 부팅 후 데이터베이스 연결, 인메모리 캐시 구축, JIT 컴파일 등 초기화 작업이 많습니다. 이러한 초기화 작업을 거치지 않은 워커(콜드 워커)가 첫 요청을 처리할 때 현저히 느려지는 문제가 발생했습니다.

  • 유니콘(Unicorn)의 LIFO 특성: 기존에 사용하던 Unicorn 웹 서버는 Linux의 epoll을 사용하여 LIFO(Last-In, First-Out) 방식으로 요청을 처리합니다. 이로 인해 미리 스케일 아웃하여 충분한 워커를 확보했음에도 불구하고, 일부 워커만 계속 활성화되고 대다수 워커들은 ‘콜드’ 상태로 유지되는 문제가 발생했습니다.

  • 자동 스케일링의 한계: AWS 오토스케일링 그룹은 새 워커를 시작하고 헬스 체크를 통과하기까지 최소 2분 이상 소요됩니다. 그러나 예약 판매 트래픽은 1분 이내에 정점에 도달하고 5분 이내에 해소되므로, 오토스케일링은 이러한 급작스러운 스파이크에 대응하기에 너무 느렸습니다.

해결책: Pichfork의 Refork 기능 도입

  • Puma 전환의 어려움: 스레드 기반의 Puma로 전환하는 것은 12년 된 대규모 Ruby on Rails 애플리케이션 전체의 스레드 안전성을 보장해야 하므로 매우 복잡하고 비용이 많이 드는 작업이었습니다.

  • Pichfork와 Refork: Unicorn의 포크 버전인 Pichfork는 refork라는 혁신적인 기능을 제공합니다. 이 기능은 이미 충분히 많은 요청을 처리하여 ‘워밍업’된 워커를 템플릿으로 사용합니다. 이 템플릿 워커를 기반으로 다른 기존 워커들을 종료하고 새로운 워커들을 포크하여 생성합니다.

  • Refork의 장점: refork를 통해 모든 워커는 디컴파일된 바이트코드, 초기화된 캐시 등 ‘웜업’된 상태를 상속받게 됩니다. 이로써 모든 워커가 처음부터 빠른 속도로 요청을 처리할 수 있게 되어 콜드 워커 문제를 근본적으로 해결합니다.

  • 설정 및 주의사항: refork_after 설정은 refork가 트리거되는 요청 수를 지정합니다. 트래픽이 적은 스케일 업 기간 동안 빠르게 refork가 발생하도록 작은 값으로 설정하는 것이 중요합니다. 또한, Pichfork는 worker_killer가 없으므로 after_cast_complete 콜백을 사용하여 직접 메모리 관리 기능을 구현해야 합니다. 포킹 과정에서 파일 디스크립터 상속이나 백그라운드 스레드 안전성 등 주의해야 할 사항이 있습니다.

결론

Pichfork의 refork 기능 도입은 Ruby 애플리케이션의 대규모 트래픽 스파이크로 인한 성능 문제를 효과적으로 해결했습니다. 2023년 대비 3배 높은 트래픽에도 불구하고, 2024년에는 P90 지연 시간이 안정적으로 유지되었고, 고객들은 "매우 부드러웠다"는 긍정적인 반응을 보였습니다. 이 솔루션은 최소한의 변경으로 최대의 효과를 가져왔으며, Unicorn과 유사한 환경에서 예측 불가능한 트래픽 스파이크로 인한 '콜드 워커' 문제를 겪는 서비스에 유용한 해결책이 될 수 있음을 시사합니다. 비록 메모리 절감 효과는 크지 않았지만, 주요 목표였던 지연 시간 개선은 성공적으로 달성되었습니다.

댓글 1

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.
D
dallos
1개월 전
멋집니다.