SolidQ 개발 배경 및 특징
SolidQ 개발의 주요 동기는 기존 Rescue 시스템의 복잡성이었습니다. 수년간 축적된 사용자 정의 코드와 포크된 젬(gems)으로 인해 Rescue는 관리하기 어려운 상태에 이르렀습니다. 37 Signals의 David Heinemeier Hansson(DHH)은 이러한 문제를 해결하고 Active Job의 이점을 최대한 활용하기 위해 데이터베이스 기반의 새로운 큐잉 시스템 개발을 제안했습니다. SolidQ는 Rescue의 문제점을 해결하고, Active Job이 제공하는 재시도, 오류 처리, 직렬화 등의 기능을 내장하여 더욱 단순하고 Rails에 최적화된 솔루션을 제공합니다.
Redis 대신 데이터베이스 선택
SolidQ는 Sidekiq과 같은 다른 큐잉 시스템이 Redis를 백엔드로 사용하는 것과 달리 데이터베이스를 사용합니다. 이는 데이터베이스를 통한 트랜잭션 무결성 확보라는 중요한 이점 때문입니다. 예를 들어, 애플리케이션 내에서 데이터 변경이 트랜잭션으로 처리될 때, 관련 작업의 인큐잉도 동일한 트랜잭션 내에서 이루어져 작업 실패 시 전체 롤백이 가능합니다. 또한, 작업이 인큐잉될 때 관련 데이터가 이미 커밋되어 있음을 보장하여 데이터 불일치 문제를 방지합니다. 초기에는 애플리케이션과 동일한 데이터베이스를 공유했지만, 대량의 쓰기 작업 부하로 인해 결국 별도의 데이터베이스를 사용하는 것이 기본값으로 자리 잡았습니다.
Good Job 및 Sidekiq과의 차별성
SolidQ는 Sidekiq이 Redis를 사용하는 것과 달리 데이터베이스를 활용하며, Good Job이 PostgreSQL의 특정 기능을 활용하여 MySQL 및 SQLite와 호환되지 않는다는 점에서 차별점을 가집니다. 37 Signals는 MySQL을 사용하기 때문에 Good Job의 PostgreSQL 종속성이 SolidQ 개발의 중요한 계기가 되었습니다.
성공적인 마이그레이션 전략
SolidQ로의 마이그레이션은 Hey 서비스를 대상으로 시작되었습니다. Hey는 비교적 최근에 개발된 코드베이스를 가지고 있었고, Basecamp와 유사한 작업 관련 문제를 겪고 있었지만, 시스템의 중요도가 Basecamp보다 낮아 새로운 시스템을 테스트하기에 적합했습니다. 마이그레이션은 Active Job의 어댑터 기능을 활용하여 사용자에게 영향을 미치지 않는 ‘소각(incineration)’과 같은 작업부터 점진적으로 SolidQ로 전환하는 방식으로 이루어졌습니다. 이 과정은 Kamal로의 인프라 마이그레이션과 겹쳐 일시 중단되기도 했으나, Kamal을 통한 배포의 용이성 덕분에 Rescue와 SolidQ 두 시스템을 동시에 운영하는 것이 단순해졌습니다.
효율적인 작업 관리 및 디버깅
SolidQ는 작업 상태(대기 중, 예약됨, 실행 중, 실패)를 데이터베이스에 투명하게 저장하여 디버깅 및 모니터링을 크게 용이하게 합니다. Mission Control과 같은 대시보드를 통해 실패한 작업을 쉽게 확인하고 수동으로 재시도할 수 있습니다. 이는 기존 Rescue의 복잡한 API와 달리 데이터베이스 필터링을 통해 특정 작업 클래스를 쉽게 찾을 수 있게 하여 문제 해결 시간을 단축시킵니다.
작업 패턴 및 재시도, 반복 작업
37 Signals 팀은 작업을 가능한 한 작고 독립적으로 유지하여 재시도 및 문제 해결을 용이하게 하는 방식을 선호합니다. 복잡한 작업 오케스트레이션은 작업 시스템 자체가 아닌 애플리케이션 코드 내에서 처리하는 것을 권장합니다. 장기 실행 작업(예: 데이터 내보내기)의 경우, 중단 시 상태를 저장하고 재개할 수 있는 기능을 개발 중입니다. 이는 배포 등으로 인해 작업이 중단될 때 처음부터 다시 시작할 필요 없이 이어서 처리할 수 있게 합니다. 또한, 작업이 다음 실행을 직접 예약하는 방식은 실패 시 후속 작업이 누락될 위험이 있어, 대신 cron과 유사한 반복 작업 모델을 선호합니다. SolidQ는 YAML 파일로 정의되고 자동으로 실행되는 내장된 반복 작업 기능을 제공하여 Unix cron의 제약을 우회하고 데이터 삭제와 같은 중요한 작업의 안정성을 높입니다.
견고한 테스팅 및 코드 관리
37 Signals는 작업 로직을 모델에 배치하고, Active Job의 헬퍼를 사용하여 작업의 인큐잉(enqueuing) 및 재시도를 테스트하는 방식을 권장합니다. Stephen Mar의 acidic_job
및 chaotic_job
과 같은 젬(gems)은 작업 테스트 시 다양한 시나리오를 시뮬레이션하는 데 유용하게 활용될 수 있습니다. 또한, 불필요한 코드를 적극적으로 삭제하는 문화는 프로젝트의 복잡성을 줄이고 유지보수 효율성을 높이는 데 기여합니다. 마이그레이션 스크립트와 같이 일회성으로 사용된 코드는 기록으로 남기되, 실제 프로젝트에서는 삭제하여 깨끗한 코드베이스를 유지합니다.
마이그레이션 고려사항 및 교훈
다른 팀이 Rescue 또는 Sidekiq에서 SolidQ로 전환을 고려한다면, 현재 시스템의 작업량, 지연 허용 범위, 하드웨어 및 데이터베이스 사양 등을 면밀히 분석하는 것이 중요합니다. 특히, 처음부터 애플리케이션과 별도의 데이터베이스를 사용하는 것을 권장합니다. 이는 SolidQ의 특정 기능(예: 동시성 제어)이 메인 데이터베이스에 큰 쓰기 부하를 줄 수 있기 때문입니다. 이번 마이그레이션의 가장 큰 성과는 SolidQ 자체의 문제가 아닌 배포 실수로 인한 단 한 번의 경미한 고객 영향만을 기록하며 거의 완벽하게 이루어졌다는 점입니다.