대부분의 애플리케이션에는 메일러, 정기적인 정리 또는 사용자가 없어도 시간이 많이 소요되는 기타 작업을 위한 백그라운드 작업이 필요합니다.
여러 gem이 Rails 세계에서 작업 대기열과 백그라운드 처리를 지원합니다. Delayed Job과 Sidekiq이 가장 인기 있는 두 가지입니다.
이번 포스팅에서는 딜레이드잡(Delayed Job)과 사이드킥(Sidekiq)이 어떻게 대결하는지 자세히 살펴보겠습니다.
가자!
지연작업에 대한 간략한 소개
지연된 작업은 Shopify에서 직접 추출되었으며 테이블을 사용하여 모든 백그라운드 작업을 유지합니다. 매우 간단한 패턴을 따릅니다. perform에 응답하는 모든 Ruby 객체 메소드는 작업 테이블에 포함될 수 있습니다.
또한 특수 작업 개체를 유지할 필요가 없는 경우(테스트 가능성과 장기 실행 작업의 명확한 분리를 위해 권장되지만) .delay.method(params)를 호출할 수도 있습니다. 모든 Ruby 객체에서. 백그라운드에서 메서드를 처리합니다.
지연된 작업 README는 모든 일반적인 사용 패턴을 훌륭하게 설명합니다.
많은 팀이 지연 작업을 선택하는 이유는 간단하고 기존 데이터베이스를 사용하기 때문입니다. 다른 자원을 소비/유지할 필요가 없습니다.
그러나 데이터베이스 테이블에서는 여전히 공간을 차지합니다. 동시에 대기열에 있는 작업이 너무 많으면 모든 작업을 수용하기 위해 더 많은 디스크 공간이 필요할 수 있습니다.
Sidekiq에 대한 간략한 소개
반면 Sidekiq은 Redis를 데이터 저장소로 사용하여 모든 작업 메타데이터를 유지합니다. 이는 Delayed Jobs가 사용하는 일반 데이터베이스 시스템보다 훨씬 빠르다는 분명한 이점을 제공합니다. 이 외에도 각 Sidekiq 프로세스는 여러 스레드를 생성하여 작업을 더욱 빠르게 처리합니다.
Sidekiq의 각 백그라운드 작업에는 Sidekiq::Worker을 포함하는 특수 클래스가 필요합니다. perform에 대해 우려하고 응답합니다. 메서드를 사용합니다. 작업을 대기열에 추가하려면 perform_async(arg1, arg2)를 호출해야 합니다. 인수를 사용하여 작업자에 대해 설명합니다.
Sidekiq '시작하기' 가이드에는 이에 대한 내용과 기타 사용 패턴이 자세히 설명되어 있습니다.
지연된 작업 또는 Sidekiq과 함께 활성 작업 사용
Rails는 이미 최상위 수준 선언 및 작업 처리를 위한 성숙한 작업 프레임워크를 제공합니다. Delayed Job과 Sidekiq 모두 ActiveJob의 통합 API를 통해 작업 실행을 지원합니다. ApplicationJob에서 상속하기만 하면 됩니다. 그리고 perform_later에 전화하세요 작업 클래스에서 구성된 대기열 백엔드에 작업을 대기열에 넣습니다.
Active Job으로 작업을 실행하면 애플리케이션 코드가 프레임워크에 구애받지 않고 Delayed Job에서 Sidekiq으로(또는 그 반대로) 전환하는 것이 매우 쉬워진다는 이점이 있습니다. ActiveJob::TestHelper 또한 대기 중인 작업을 쉽게 테스트할 수 있습니다.
그러나 Active Job이 제공하는 추상화에는 작업 데이터를 저장소에 푸시하기 전에 래핑해야 하기 때문에 성능 오버헤드도 함께 발생합니다. Sidekiq에서는 ActiveJob이 Redis로 푸시할 때 약 2~20배 느리며 처리 오버헤드는 ~3배 더 높다고 주장합니다.
지연된 작업과 Sidekiq
이제 Delayed Jobs와 Sidekiq의 기본 사항을 알았으니 차이점과 각각의 결과에 대해 자세히 알아보겠습니다.
특징
기본 응용 프로그램의 경우 Sidekiq과 Delayed Job은 모두 즉시 사용할 수 있는 우수한 기능 세트를 제공합니다. 여기에는 작업 우선 순위 할당, 명명된 대기열 및 실패 시 자동 재시도가 포함됩니다.
지연된 작업은 또한 기본적으로 최대 실행 시간을 구성하는 방법을 제공합니다(Sidekiq은 그렇지 않음).
반면 Sidekiq은 작업 메타데이터 업데이트, 작업 대기열 건너뛰기 또는 작업 실행을 위한 미들웨어 지원을 제공합니다. Sidekiq은 지연된 작업 앱에 사용할 수 있는 일부 후크가 있지만 더 많은 콜백을 지원합니다. 콜백 대신 활성 작업과 함께 지연된 작업을 사용할 수 있습니다(즉, before_enqueue 및 around_perform Rails에 내장된 콜백).
웹 UI는 Sidekiq에서 기본으로 제공되는 또 다른 기능입니다. 이는 작업에 대한 기록 통계와 작업자, 현재 대기열에 추가된 작업 및 죽은 작업에 대한 정보를 제공합니다. 콘솔을 거치지 않고 즉시 작업 삭제 또는 실행과 같은 작업을 수행할 수 있습니다.
지연된 작업에는 내장된 웹 UI가 없지만 delayed_job_web Sidekiq과 유사한 기능을 갖춘 기본 웹 UI에 대한 액세스를 제공합니다.
Sidekiq의 성능 승리
성능 면에서 Sidekiq은 Delayed Job을 확실히 능가합니다. Sidekiq의 오픈 소스 벤치마크에 따르면 Sidekiq은 Delayed Job보다 약 30배 빠릅니다. 여기에는 두 가지 주요 이유가 있습니다:
- Redis는 디스크가 아닌 메모리에 데이터를 저장하기 때문에 Postgres와 같은 기존 데이터베이스보다 데이터 쿼리 속도가 훨씬 빠릅니다.
- 지연 작업은 여러 스레드를 사용하는 Sidekiq과 달리 단일 스레드를 실행하여 작업을 처리합니다.
이 모든 것이 서류상으로는 훌륭해 보이지만 큰 규모(예:분당 10,000개의 작업)로 작업하지 않는 한 차이는 그다지 중요하지 않습니다. 정확한 숫자는 작업의 평균 실행 시간에 따라 달라집니다. 실행 시간이 길수록 지연된 작업의 성능 오버헤드는 덜 중요합니다.
지연된 작업의 성능이 걱정된다면 몇 가지 성능 최적화를 수행할 수 있습니다. 사용할 정확한 인덱스는 작업 시스템의 통계에 따라 다릅니다. 예를 들어 여러 대기열을 사용하고 하나만 주요 작업 청크를 가져오는 경우 대기열 열(add_index :delayed_jobs, :queue)에 간단한 인덱스가 있습니다. ) 성능을 크게 향상시킬 수 있습니다.
AppSignal에서는 Sidekiq 매직 대시보드가 자동으로 생성되며 이를 통해 대기열 길이, 대기열 대기 시간, 작업 기간, 작업 상태, 메모리 사용량 등을 모니터링할 수 있습니다.

배포
Delayed Job과 Sidekiq 모두 작업자를 위한 유사한 배포 전략을 가지고 있습니다. Heroku를 사용하면 Procfile 내부에 항목을 추가하기만 하면 됩니다. 작업 프로세서를 시작하고 작업자를 실행합니다.
사이드킥의 경우:
지연된 작업의 경우:
메모리
여기서부터 상황이 좀 더 흥미로워지기 시작합니다. Sidekiq에는 실행되는 스레드 수를 제어할 수 있는 동시성 옵션이 있습니다. 대부분의 Sidekiq 및 Delayed Job 벤치마크에서는 Sidekiq의 최대 25개 스레드의 매우 높은 동시성이 언급되어 초고속 성능에 기여합니다.
하지만 실제 설정에서는 스레드를 좀 더 보수적인 것으로 제한해야 합니다. 실제 개수는 애플리케이션의 무게와 수행하는 작업 종류에 따라 다릅니다. 실제로 제가 본 것은 512MB 메모리(standard-1x에 해당)에서 작업자를 실행하는 경우입니다. Heroku의 경우) 스레드 수는 25개가 아닌 2~5개 사이입니다.
Sidekiq의 창시자인 Mike Perham이 쓴 'Taming Rails memory bloat'에서는 메모리 문제에 대해 더 자세히 논의하고 읽어 볼 가치가 있습니다. 전체 논의에 뛰어들지는 않겠지만 그는 MALLOC_ARENA_MAX=2으로 설정하는 것을 권장합니다. Sidekiq을 실행하는 모든 작업자에게 적용됩니다.
jemalloc 사용 일반 malloc 대신 도움이됩니다. 이를 수행하는 정확한 방법은 사용하는 플랫폼에 따라 다르지만 Heroku에서는 매우 간단합니다. heroku-buildpack-jemalloc을 첫 번째 빌드팩으로 설정하면 됩니다(heroku/ruby 앞선). 빌드팩).
지연된 작업은 더 간단한 리소스를 사용합니다
논의한 대로 지연된 작업은 기존 데이터베이스 인스턴스에서 실행됩니다. 다음을 늘려야 할 수도 있습니다.
- 사용 가능한 메모리
- 디스크 공간
- 최대 연결수
작업 부하나 실행하는 작업자 수에 따라 다릅니다. 하지만 필요한 유일한 리소스는 작업 프로세서입니다.
반면 Sidekiq은 작업을 처리하기 위해 Redis 인스턴스가 필요합니다. Redis를 캐시 저장소로도 사용하는 경우 Sidekiq 작업을 위한 "영구 저장소"로 구성된 별도의 인스턴스를 사용하는 것이 좋습니다.
Redis는 모든 것이 메모리에 맞을 때 가장 잘 작동하므로 작업이 너무 많은 경우(예:Sidekiq이 앱 문제로 인해 일정 시간 동안 작업 처리를 중지하는 경우) 모든 것을 정리하는 데 약간의 가동 중지 시간이 걸릴 수 있습니다. Redis가 앱과 동일한 서버에 있는 경우 특히 문제가 됩니다. 메모리 경쟁이 시작되어 교체로 이어지고 결국 앱 성능이 저하됩니다.
Redis에 대해 주목해야 할 중요한 점 중 하나는 maxmemory-policy noeviction로 구성해야 한다는 것입니다. Sidekiq의 데이터가 자동으로 삭제되는 것을 방지합니다. 그렇지 않으면 수행해야 할 작업을 흔적도 없이 놓칠 수 있습니다.
참고 사항:Sidekiq의 유료 업그레이드
추가 기능이 필요한 경우 Sidekiq에 Pro가 제공됩니다. 및 Enterprise 버전.
Pro에 가장 주목할만한 추가 사항은 Batch Jobs입니다. 병렬로 실행되고, 모니터링되고, 그룹으로 상호 작용할 수 있으며 모든 작업이 완료되면 콜백을 호출합니다. Pro에는 또한 네트워크 문제가 발생하는 동안에도 작업이 자동으로 삭제되지 않도록 향상된 안정성 기능이 있습니다.
Enterprise 버전에는 더 많은 기능이 포함되어 있습니다. 일반 Sidekiq 설치로 해결할 수 없는 문제를 찾고 있다면 Sidekiq 유료 기능을 살펴보세요.
실제로 Sidekiq 무료 버전은 여전히 훌륭하게 작동합니다. 하지만 다른 솔루션으로 전환하는 대신 필요에 따라 업그레이드할 수 있는 유료 옵션이 있다는 것을 아는 것이 좋습니다.
커뮤니티 및 개발 상태:Sidekiq이 우위에 있습니다
Sidekiq과 Delayed Job 뒤에는 거대한 커뮤니티가 있습니다. 하지만 StackOverflow나 공식 문서에서 질문에 대한 빠른 답변을 찾는 것이 항상 쉬운 것은 아닙니다.
개발 측면에서는 딜레이디드 잡(Delayed Job)의 상황이 그리 밝아 보이지는 않습니다. 딜레이드 잡(Delayed Job)은 2021년 12월과 2022년 1월에 약간의 작업이 이루어졌으나 앞으로 큰 발전이 있을 것 같지는 않습니다. 유지 관리 전용 모드인 것으로 보이며 Github에는 공개된 문제가 많이 있습니다.
이와 대조적으로 Sidekiq은 아직 활발하게 개발 중이며 제작자가 풀타임으로 작업하고 있습니다. 미해결 문제는 거의 없으며 정기적으로 해결됩니다.
마무리:Sidekiq인가 지연작업인가? 귀하의 필요에 따라 다릅니다.
이 게시물에서는 Rails 애플리케이션을 위한 두 가지 주요 작업 처리 시스템인 Sidekiq과 Delayed Job을 다루면서 이들 시스템의 장단점을 살펴보았습니다.
각각 다른 사용 사례가 있습니다. 이는 모두 귀하의 운영 예산과 규모에 따라 다릅니다.
성능과 장기적인 유지 관리 가능성이 중요하다면 Sidekiq은 당연한 선택입니다. 반면, 운영 비용이 문제라면 Delayed Job이 도움이 될 수 있습니다.
Delayed Job을 선택하든 Sidekiq을 선택하든 프로젝트에 행운이 있기를 바라며 행복한 코딩을 하세요!
👋 이 기사가 마음에 들었다면 Ruby 성능 모니터링 체크리스트에서 다른 Ruby(on Rails) 성능 기사를 살펴보세요.
추신 Ruby Magic 게시물이 보도되는 즉시 읽으려면 Ruby Magic 뉴스레터를 구독하고 단 하나의 게시물도 놓치지 마세요!