GraphQL 성능 최적화: N+1 문제 해결 및 운영 노하우

Tuning GraphQL on Rails / Kazuhiko Yamashita - Kaigi on Rails 2024

3줄 요약

  • GraphQL 환경에서 발생하는 N+1 쿼리 문제는 Batch Loader와 Lookahead 기법으로 해결할 수 있습니다.
  • 대용량 데이터 처리 등 복잡한 케이스는 커스텀 로더 구현이 필요하며, APM 도구를 활용한 지속적인 모니터링이 중요합니다.
  • SLI/SLO 설정과 팀 단위의 성능 관리 문화를 통해 장기적인 서비스 성능 유지가 가능합니다.

본 발표는 핸드메이드 마켓 서비스 '민네(Minne)'의 사례를 통해 GraphQL 환경에서 발생하는 성능 문제, 특히 N+1 쿼리 해결 방안과 지속적인 성능 관리를 위한 운영 노하우를 공유합니다. 서비스 규모 확장과 엔화 약세 등으로 인한 인프라 비용 증가에 직면하여, 근본적인 성능 개선의 필요성이 대두되었습니다. 데이터독(Datadog)과 같은 APM 도구를 활용하여 애플리케이션의 프레임 그래프를 분석한 결과, 비효율적인 데이터베이스 쿼리, 즉 N+1 문제가 심각함을 확인했으며, 이를 해결하기 위한 구체적인 기술적 접근 방식과 실제 개선 효과, 그리고 향후 운영 전략에 대해 논의합니다.

GraphQL에서 N+1 쿼리를 해결하는 주요 방법으로는 Lookahead와 Batch Load가 있습니다. Lookahead는 필드 지정 시 추가 옵션을 통해 하위 필드 포함 여부를 미리 파악하여 관련 데이터를 미리 로드하는 방식입니다. 이는 간단한 로직에 적합하나, 조건이 복잡해지면 가독성이 저하될 수 있습니다. 민네에서는 주로 graphql-batch 라이브러리를 활용한 Batch Load 방식을 사용합니다. graphql-batchPromise.rb 라이브러리를 기반으로 비동기 처리를 통해 여러 개의 개별 쿼리를 하나의 배치 쿼리로 묶어 실행합니다. 이는 GraphQL 쿼리의 네스트 구조에 따라 자동으로 데이터 로딩을 최적화합니다. 특히, 대용량 데이터나 복잡한 비즈니스 로직으로 인해 기본 Batch Loader로 해결하기 어려운 경우에는 SQL의 ROW_NUMBER() 함수나 EXISTS 조건을 활용한 커스텀 로더 구현을 통해 효율적인 데이터 조회가 가능합니다. 커스텀 로더는 유연성을 제공하지만, 모델에 있어야 할 비즈니스 로직이 로더에 포함되어 코드의 책임 분리가 모호해질 수 있으므로 주의가 필요합니다. 성능 문제 발견 및 분석에는 APM 도구가 필수적입니다. 유닛 테스트만으로는 GraphQL의 복잡한 쿼리 패턴을 모두 포착하기 어렵기 때문입니다. 데이터독이나 센트리(Sentry)와 같은 APM을 통해 발행되는 SQL 쿼리와 프레임 그래프를 시각적으로 확인하고, 센트리의 스팬(Span) 기능을 활용하여 특정 코드 블록의 성능을 측정함으로써 문제의 원인을 정확하게 파악할 수 있습니다. 이러한 성능 개선 노력의 결과, 민네는 온프레미스 및 AWS 환경의 VM 수를 대폭 절감하고, API 응답 시간 단축 및 데이터베이스 CPU 부하 감소 등 유의미한 성과를 달성했습니다.

성능 최적화는 일회성 이벤트가 아닌 지속적인 과정입니다. 서비스가 성장함에 따라 새로운 기능 추가와 데이터 증가로 인해 성능 저하는 필연적으로 발생할 수 있습니다. 이를 방지하고 관리하기 위해 SLI(Service Level Indicator) 및 SLO(Service Level Objective)를 설정하여 핵심 성능 지표를 정의하고 목표를 관리하는 것이 중요합니다. GraphQL 응답 시간을 SLI로 설정하고 구체적인 목표를 세워 팀 전체가 이를 공유하고 달성하기 위해 노력해야 합니다. 또한, 오픈텔레메트리(OpenTelemetry)와 같은 표준화된 데이터 수집 기술과 그래파나(Grafana)와 같은 시각화 도구를 활용하여 성능 대시보드를 구축하고 정기적으로 검토하는 문화가 필요합니다. 성능 개선은 단순히 인프라 비용 절감을 넘어 고객 경험 향상이라는 궁극적인 목표를 달성하기 위한 것이므로, 기술팀뿐만 아니라 서비스 전체 팀이 성능을 공동의 책임으로 인식하고 관리하는 것이 성공적인 서비스 운영의 핵심입니다.