workers retries pricing perform now job generate ruby ruby-on-rails-4 redis thread-safety sidekiq

ruby - retries - sidekiq scheduler



¿Cuál es la mejor manera de usar Redis en un entorno de Raíles con múltiples hilos?(Puma/Sidekiq) (1)

Utiliza un grupo de conexiones global separado para el código de su aplicación. Pon algo así en tu inicializador redis.rb:

require ''connection_pool'' REDIS = ConnectionPool.new(size: 10) { Redis.new }

Ahora en el código de su aplicación en cualquier lugar, puede hacer esto:

REDIS.with do |conn| # some redis operations end

Tendrás hasta 10 conexiones para compartir entre tus trabajadores de puma / sidekiq. Esto conducirá a un mejor rendimiento, ya que, como notará correctamente, no tendrá todos los hilos peleándose por una sola conexión Redis.

Todo esto está documentado aquí: https://github.com/mperham/sidekiq/wiki/Advanced-Options#connection-pooling

Estoy usando Redis en mi aplicación, tanto para colas Sidekiq como para el almacenamiento en caché de modelos.

¿Cuál es la mejor manera de tener una conexión Redis disponible para mis modelos, teniendo en cuenta que los modelos que tocarán Redis serán llamados tanto desde mi aplicación web (ejecutada a través de Puma) como desde trabajos en segundo plano dentro de Sidekiq?

Actualmente estoy haciendo esto en mis inicializadores:

Redis.current = Redis.new(host: ''localhost'', port: 6379)

Y luego simplemente use Redis.current.get / Redis.current.set (y similar) en todo el código ...

Esto debe ser seguro para subprocesos, por lo que yo entiendo, ya que el Cliente Redis solo ejecuta un comando a la vez, usando un Monitor.

Ahora, Sidekiq tiene su propio grupo de conexión con Redis, y recomienda hacer

Sidekiq.redis do |conn| conn.get conn.set end

Tal como lo entiendo, esto sería mejor que el enfoque de simplemente usar Redis.current porque no tienes múltiples trabajadores en múltiples hilos esperando uno al otro en una sola conexión cuando presionan Redis.

Sin embargo, ¿cómo puedo hacer que esta conexión que obtengo de Sidekiq.red esté disponible para mis modelos? (sin tener que pasarlo como un parámetro en cada llamada a método)

No puedo configurar Redis.current dentro de ese bloque, ya que es global, y estoy de vuelta con todos los que usan la misma conexión (además de cambiar entre ellos aleatoriamente, lo que podría ser incluso no seguro para subprocesos)

¿Debo almacenar la conexión que obtengo de Sidekiq.Redis en una variable Thread-local, y usar esa variable thread-local en todas partes?

En ese caso, ¿qué hago en el contexto "Puma"? ¿Cómo configuro la variable local del hilo?

Cualquier idea sobre esto es muy apreciada.

¡Gracias!