Basecamp의 YJIT 적용을 통한 성능 개선 사례

37signals Dev — Basecamp code runs 18% faster with YJIT

Unknown 2023년 12월 01일 https://dev.37signals.com/yjit-is-fast/

3줄 요약

  • Basecamp는 YJIT 도입 후 전반적인 애플리케이션 성능이 약 18% 향상되었습니다.
  • 특히 Ruby 3.3.0으로 업그레이드하면서 YJIT 코드 실행 비율이 98%까지 극적으로 증가하여 응답 시간이 최대 22% 단축되는 성과를 거두었습니다.
  • 이러한 개선은 코드 변경 없이 최소한의 메모리 오버헤드만으로 달성되었으며, YJIT의 높은 효율성을 입증합니다.

Basecamp는 최근 YJIT(Yet Another Ruby JIT)를 도입하여 애플리케이션 성능을 획기적으로 개선했습니다. 이 글에서는 Basecamp의 YJIT 설정 방식과 이를 통해 달성한 구체적인 성능 향상 수치를 공유합니다. 전반적으로 약 18%의 속도 향상을 기록하며, YJIT가 Ruby 및 Rails 애플리케이션에 미치는 긍정적인 영향을 명확히 보여줍니다.

Basecamp의 현재 환경은 Ruby 3.3.0-preview3 및 Rails Edge(master 브랜치)로 구성되어 있습니다. YJIT는 서버에서 RUBYOPT=--yjit-disable --yjit-exec-mem-size=192 환경 변수를 통해 초기에는 비활성화하고, 런타임에 RubyVM::YJIT.enable을 호출하여 활성화하는 방식으로 구성되었습니다. 이는 부팅 시 YJIT를 활성화하는 방식보다 더 빠른 부팅 시간을 제공하는 이점을 가집니다. 또한, 일부 서버에서는 yjit stats를 활성화하여 YJIT 관련 통계를 수집했습니다. 성능 지표는 Yabeda를 통해 계측하고 Prometheus에 기록한 후 Grafana로 시각화하여 추적됩니다.

성능 최적화 과정에서 Basecamp는 기본값인 128 MiB보다 큰 192 MiB의 메모리 크기가 애플리케이션에 가장 적합하다는 것을 발견했습니다. 이 설정은 RUBYOPT 환경 변수 내 --yjit-exec-mem-size=192를 통해 이루어졌습니다. 각 애플리케이션에 따라 최적의 메모리 값은 달라질 수 있으며, 이를 찾기 위해서는 RubyVM::YJIT.runtime_stats[:code_region_size] 값이 --yjit-exec-mem-size보다 작은지 확인하는 것이 중요하다고 언급됩니다.

YJIT 적용 후 응답 시간에서 전반적인 개선이 관찰되었습니다. 중앙값(Median)은 22%, 평균(AVG)은 16%, P90(상위 10% 응답 시간)은 16% 빨라지는 등 16%에서 22% 범위의 성능 향상을 기록했습니다. 특히 Ruby 3.3.0으로의 업그레이드는 성능 향상에 결정적인 역할을 했습니다. 업그레이드 이후 YJIT 코드 실행 비율(ratio_in_yjit)이 약 43%에서 약 98%로 극적으로 증가했습니다. 이는 Basecamp 코드의 98%가 느린 Ruby 인터프리터 대신 YJIT에 의해 실행된다는 것을 의미하며, 이는 성능에 지대한 영향을 미쳤습니다.

결론적으로, Basecamp는 YJIT 덕분에 코드 변경 없이도 상당한 성능 향상을 달성했습니다. 이는 최소한의 메모리 오버헤드만으로 이루어진 결과입니다. 문서에서는 아직 YJIT를 시도하지 않은 사용자들에게 즉시 테스트해 볼 것을 강력히 권장합니다. YJIT는 결국 Rails의 기본 설정으로 활성화될 예정이므로, 지금 바로 도입을 고려하는 것이 현명한 선택임을 강조하며 마무리됩니다.