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’ 시스템으로, 커뮤니티의 기여를 통해 지속적으로 개선되고 있습니다.