SolidQ: 내부, 외부 및 그 사이의 모든 것

[EN] Solid Queue internals, externals and all the things in between - Rosa Gutierrez

작성자
Visuality.pl
발행일
2025년 03월 17일

핵심 요약

  • 1 SolidQ는 기존 Redis 기반의 복잡성을 해결하고 관계형 데이터베이스를 활용한 새로운 Ruby on Rails Active Job 백엔드입니다.
  • 2 Rails 8의 기본 큐잉 시스템으로 채택되었으며, `FOR UPDATE SKIP LOCKED` 기능으로 데이터베이스 폴링 시 발생하는 성능 문제를 해결했습니다.
  • 3 37signals의 Hey 서비스에서 하루 2천만 건 이상의 작업을 안정적으로 처리하며, 복잡한 기존 시스템을 대체하고 데이터베이스 트랜잭션 무결성을 활용합니다.

도입

본 발표는 Ruby 커뮤니티 컨퍼런스에서 SolidQ에 대해 다룹니다. SolidQ는 Redis와 같은 키-값 저장소 대신 관계형 데이터베이스를 기반으로 하는 새로운 Active Job 백엔드입니다. 2024년 안정 버전이 출시되었고, Rails 8의 Solid Trifecta(Solid Cable, Solid Cache, SolidQ) 중 하나로 기본 채택되었습니다. 이는 37signals가 기존 Redis/Memcached 의존성을 관계형 데이터베이스로 대체하고자 한 목표에서 시작되었습니다.

37signals는 기존 Resque 기반 큐잉 시스템의 복잡성(7개 Gem 관리)과 대규모 작업 인큐잉 시 Redis 메모리 문제에 직면하여 SolidQ를 개발했습니다. SolidQ는 Solid Cache의 성공 사례에서 영감을 받아 관계형 데이터베이스를 활용하며, MySQL 환경에 적합하도록 설계되었습니다. 데이터베이스 기반 큐잉의 주요 문제인 폴링 시 잠금 및 경합을 해결하기 위해 SolidQ는 MySQL 및 PostgreSQL의 FOR UPDATE SKIP LOCKED 기능을 도입하여 워커들이 효율적으로 작업을 처리할 수 있도록 했습니다.

SolidQ 아키텍처는 작업 생명 주기에 따라 작업을 여러 테이블로 분리하여 ready_execution 테이블을 최소화하고 쿼리 성능을 최적화합니다. 워커, 디스패처, 슈퍼바이저 에이전트가 각기 다른 역할을 수행하며, 데이터베이스 트랜잭션을 통해 작업 손실을 방지하고 미래 작업을 별도 관리합니다. MySQL 8, PostgreSQL, SQLite를 지원하며 우선순위 및 큐 일시 중지 기능을 제공합니다.

동시성 제어(Sequential Jobs)는 semaphores 개념과 concurrency_controls 테이블을 통해 구현되었고, 초기 쓰기 성능 문제는 SolidQ를 별도의 데이터베이스로 운영함으로써 해결되었습니다.

현재 SolidQ는 37signals의 Hey 서비스에서 하루 약 2천만 개의 작업을 처리하며 400개의 워커를 사용합니다. 사용자 대면 작업의 지연 시간은 Resque와 동등하고, 대량 인큐잉 시 속도 향상을 제공합니다. 인큐잉 시간은 Resque보다 길지만(3-6ms), 대부분 쓰기 요청에서 발생하고 전체 요청 시간에 미치는 영향이 미미하여 사용자 경험에 부정적인 영향을 주지 않습니다. SolidQ는 프로덕션 환경에서 실제 사용하며 개발된 ‘fun-tested’ 시스템으로, 커뮤니티의 기여를 통해 지속적으로 개선되고 있습니다.

결론

SolidQ는 관계형 데이터베이스의 강력한 트랜잭션 무결성과 Rails Active Record의 이점을 활용하여 기존 큐잉 시스템의 복잡성과 Redis 의존성을 해결한 혁신적인 Active Job 백엔드입니다. 효율적인 폴링 메커니즘과 세심한 아키텍처 설계를 통해 대규모 트래픽을 안정적으로 처리할 수 있음을 입증했습니다. Rails 8의 기본 큐잉 시스템으로 채택됨으로써, Ruby on Rails 생태계에 중요한 변화를 가져올 것으로 기대됩니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!