2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

SidekiqをActiveJob経由で使うべきか

Posted at

実務でRailsアプリケーションを扱っており、非同期処理の実装でSidekiqを扱うことになりました。
Sidekiqを直接扱うパターンとActiveJob経由で扱うパターンの2通りあることを知ったため、それぞれのメリット/デメリットを調査しました。

参考にした記事

本記事を書くにあたり以下の記事を参考にさせていただきました。

はじめに

RailsアプリケーションへのSidekiqの導入手順は割愛します。
まず、Sidekiqを直接扱うパターンとは、以下のようにSidekiq:Workerモジュールを直接includeしたジョブクラスを定義した実装を指します。

class BackgroundJob
  include Sidekiq::Worker
  Sidekiq_options queue: "default"

  def perform(id)
    # 非同期実行したい内容
  end
end

一方で、ActiveJob経由で扱うパターンとは、以下のようにApplicationJobを継承したジョブクラスを定義する実装を指します。

class BackgroundJob < ApplicationJob
  queue_as :default

  def perform(an_active_record_object)
    # 非同期実行したい内容
  end
end

メリット/デメリット比較

Sidekiqを直接扱う ActiveJob経由で扱う
メリット ・高パフォーマンス
・Sidekiq固有機能が利用可
・引数にオブジェクトを指定可能
・他のキューイングへの移行コスト小
デメリット ・引数にオブジェクトを指定不可
・他のキューイングへの移行コスト大
・Sidekiqの固有機能を使えない

比較ポイントとしては大きく3点です。

1. パフォーマンス面

ActiveJobの公式ドキュメントによると、ActiveJobを介さずSidekiq等のキューイングをそのまま使用する場合、ジョブをRedisにpushする速度が2~20倍向上するとされています。

またSidekiqにはバルクキューイングという、同じジョブ大量に実行したい場合に効率的にキューイングできる仕組みもあります。ActiveJob経由で利用する場合はこうしたSidekiq固有の仕組みも利用できなくなります。

2. 引数の自由度

公式ドキュメントによると、Sidekiqに渡せる引数は 文字列、整数、浮動小数点数、真偽値、null(nil)、配列、およびハッシュとされており、オブジェクトを渡すことはできません。
そのため、ジョブの中で特定のActiveRecordオブジェクトに対する処理を実施したい場合は、以下のように引数でそのオブジェクトのIDを渡してジョブの中で検索をしてやる必要があります。

class BackGroundJob
  include Sidekiq::Worker

  def perform(user_id)
    user = User.find(user_id)
    user.do_hoge
  end
end

一方でActiveJobはGlobalIDという仕組みをサポートしているため、以下のように引数にActiveRecordオブジェクトを直接指定することができます。

class BackGroundJob < ApplicationJob
  def perform(user)
    user.do_hoge
  end
end

3. 他のキューイング(Shoryuken, Delayed_job等)への移行コスト

Sidekiqを直接扱う場合は、ジョブクラスにSidekiq固有のコードを書いていくことになるため、他のキューイングへの移行時のコストが大きくなります。一方でActiveJob経由の場合は、バックエンドのキューイングに関わらずコードは同じになるため、他のキューイングへの移行は行いやすくなります。ただし、キューイングを切り替えることはそこまで頻繁には起きないと考えられるため、そこまでメリット(デメリット)にはならないかと考えています。

最後に

上記の参考記事では、SidekiqかActiveJobかの二者択一ではなく共存させるのも一つの方法だと述べられています。私もこの考えに賛成です。

ハイパフォーマンスが求められるジョブやバルクキューイング等のSidekiq固有機能を利用したい場合は直接利用、ハイパフォーマンスは求められず引数にオブジェクトを指定したほうが実装がシンプルになる場合はActiveJob経由、のように使い分けられるとよいかと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?