af83

Remplacez Resque par Sidekiq

Lorsque l'on développe des applications web, il est souvent recommandé de répondre rapidement aux requêtes HTTP. En particulier, il faut éviter que les traitements lourds, comme l'encodage d'une vidéo ou la génération de vignettes, bloquent les réponses. Pour cela, la solution classique est d'utiliser un message queue. Le plus populaire dans le monde Rails est Resque (avec la base de données clé-valeur Redis comme stockage).

Le principe est simple : on définit des traitements à faire et quand l'application Rails souhaite faire un de ces traitements, elle place dans Redis un ordre. D'autres processus, les workers, prennent un ordre dans Redis, l'effectuent, puis passent à l'ordre suivant.

Chez af83, nous utilisons Resque sur plusiers projets et nous en sommes très satisfaits. Toutefois, Resque a un défaut : chaque worker traite un seul ordre à la fois et consomme pas mal de mémoire. Dans la pratique, cela veut souvent dire que l'on ne pourra pas traiter plus d'une dizaine d'ordres simultanément.

Sidekiq a été écrit spécialement pour dépasser cette contrainte. C'est un remplaçant de Resque écrit avec Celluloid, une bibliothèque d'Actors en Ruby. Dans Sidekiq, les workers sont des threads et non plus des processus, permettant de consommer beaucoup moins de mémoire par worker et donc d'en faire fonctionner beaucoup plus en parallèle.

En pratique, si on souhaite utiliser Sidekiq sur un projet Rails, on commence par l'ajouter au Gemfile :

gem 'sidekiq'

Puis, on écrit un worker (dans le répertoire app/workers), avec une méthode perform :

class MetricsWorker
  include Sidekiq::Worker

  def self.perform(action, count=1)
    Metrics.increment(action, count)
  end
end

Enfin, on peut utiliser ce worker depuis un contrôleur ou un modèle, en utilisant la méthode perform_async :

Metrics.perform_async("start", 1)

Il ne reste plus qu'à lancer sidekiq depuis la racine de Rails pour que celui-ci commence à récupérer les ordres et les traiter.

Bref, Sidekiq peut remplacer avantageusement Resque et ce d'autant plus facilement qu'il utilise le même stockage. Il est même possible d'utiliser resque-ui avec Sidekiq (il suffit d'indiquer à sidekiq d'utiliser le namespace resque pour redis en le lançant de cette façon : sidekiq -n resque).

Dernière chose, Sidekiq est distribuée sous 2 licences : GPLv3 et commerciale. Si la licence GPL vous convient, tant mieux, utilisez-là. Dans le cas contraire, vous pouvez payer 50$ à Mike Perham pour pouvoir utiliser Sidekiq (ça doit lui permettre de passer plus de temps sur ses projets Open Source).

Mise à jour : attention, Mongoid 2.x n'est pas thread-safe et il est donc très fortement déconseillé de l'utiliser avec Sidekiq. La version 3 de Mongoid est en cours de développement et sera thread-safe. Source : https://github.com/mongoid/mongoid/issues/1291

blog comments powered by Disqus