솔리드 큐(Solid Queue): Active Job을 위한 37signals의 새로운 데이터베이스 기반 백엔드 공개

37signals Dev — Introducing Solid Queue

3줄 요약

  • 37signals는 Active Job의 새로운 데이터베이스 기반 백엔드인 Solid Queue를 오픈 소스로 공개했습니다.
  • 이는 기존 Resque/Redis 스택의 복잡성을 해소하고, 다양한 데이터베이스를 지원하며 운영 간소화를 목표로 합니다.
  • `SELECT ... FOR UPDATE SKIP LOCKED` 등 최적화된 설계로 높은 성능과 쉬운 디버깅을 제공합니다.

37signals는 Active Job을 위한 새로운 데이터베이스 기반 백엔드 `Solid Queue`를 오픈 소스로 공개했습니다. 현재 HEY에서 하루 1,800만 건의 작업 중 약 1/3을 처리하는 데 사용 중인 이 솔루션은 기존 Resque/Redis 스택의 복잡성을 해소하고, 개발자들에게 더 간편한 배경 작업 환경을 제공하고자 개발되었습니다. Solid Queue는 지연 작업, 동시성 제어, 큐 일시 중지, 작업별/큐별 숫자 우선순위 등 다양한 핵심 기능을 지원합니다.

37signals는 수년간 Resque와 Redis를 사용하며 규모 확장에 따른 복잡성과 운영의 어려움을 겪었습니다. 특히, resque-scheduler, resque-pool 등 7가지 이상의 개별 Gem을 관리해야 하는 부담이 컸습니다. 이러한 배경에서 delayed_job이 널리 사용되던 시절처럼 데이터베이스를 활용하여 Rails 설치만으로 배경 작업 처리가 가능한 단순한 솔루션을 목표로 삼았습니다. 기존 Active Job 백엔드들을 검토한 결과 GoodJob이 주목받았으나 PostgreSQL 전용이라는 한계로 인해, MySQL, PostgreSQL, SQLite를 모두 지원하는 독자적인 솔루션의 필요성이 대두되었습니다.

Solid Queue는 데이터베이스 기반임에도 불구하고 뛰어난 성능을 보여줍니다. 핵심은 MySQL 8 이상 및 PostgreSQL에서 지원하는 SELECT ... FOR UPDATE SKIP LOCKED 구문을 활용하여 워커들이 다른 워커를 방해하지 않고 작업을 효율적으로 가져오고 잠글 수 있게 한 것입니다. 또한, 처리 중이거나 미래에 예약될 작업, 실패한 작업 등은 실행 대기 중인 작업들과 분리하여 워커가 폴링하는 테이블의 크기를 최소화함으로써 쿼리 효율성을 극대화했습니다. 더 나아가, 커버링 인덱스를 활용한 작업 선택 전략은 정렬된 명명 큐와 우선순위 지정을 매우 빠르고 비차단적인 쿼리로 지원합니다. 현재 하루 약 560만 건의 작업을 처리하며 초당 약 1,300건의 폴링 쿼리를 수행하고, 평균 쿼리 시간은 110 µs로 매우 효율적입니다.

HEY의 핵심 작업에 Solid Queue를 적용한 결과, 가장 큰 이점은 단순성과 운영 용이성이었습니다. 모든 작업 정보가 관계형 데이터베이스에 저장되고 Active Record를 통해 인터페이스되므로, Resque 사용 시보다 작업 관련 문제 디버깅이 훨씬 쉬워졌습니다. 이와 더불어, Resque와 Solid Queue 모두를 관찰하고 운영할 수 있는 Mission Control이라는 대시보드도 구축하여 운영 편의성을 높였습니다.

Solid Queue는 37signals의 실제 대규모 운영 경험을 바탕으로 개발된 강력하고 단순한 Active Job 백엔드입니다. 이 솔루션은 복잡한 외부 시스템 의존성을 줄이고 데이터베이스 기반의 안정성과 성능을 동시에 제공함으로써, Rails 개발자들이 배경 작업을 더욱 효율적으로 관리할 수 있도록 돕습니다. 현재 버전 0.1.1이 공개되었으며, 내년 초 `Mission Control` 대시보드도 오픈 소스화될 예정이어서 Rails 생태계에 큰 기여를 할 것으로 기대됩니다.