SidekiqAutoscale
A simple gem to manage autoscaling of Sidekiq worker pools
Usage
Installation
Add this line to your application's Gemfile:
gem 'sidekiq_autoscale'
And then execute:
$ bundle install
Install the initializer:
$ rails g sidekiq_autoscale:install
This will create a config/initializers/sidekiq_autoscale.rb file.
Installing middleware in Sidekiq chain
Add the scaling middleware to your Sidekiq configuration
Sidekiq.configure_server do |config|
.....
config.server_middleware do |chain|
chain.add SidekiqScaling::Middleware
end
end
Configuration
All configuration can be done in a SidekiqAutoscale.configure block, either in a standalone initializer or in <environment>.rb files.
Standard configuration looks like this:
SidekiqAutoscale.configure do |config|
config.cache = Rails.cache
config.logger = Rails.logger
config.redis = # Put a real Redis client instance here
# Number of workers will never go below this threshold
config.min_workers = 1
# Number of workers will never go above this threshold
config.max_workers = 20
# The up and down thresholds used by all scaling strategies
config.scale_down_threshold = 1.0
config.scale_up_threshold = 5.0
# Current strategies are:
# :oldest_job - scales based on the age (in seconds) of the oldest job in any Sidekiq queue
# :delay_based - scales based on the average age (in seconds) all jobs run in the last minute
# :linear - scales based the total number of jobs in all queues, divided by the number of workers
# :base - do not scale, ever
config.strategy = :base
# Current adapters are:
# :nil - scaling events do nothing
# :heroku - scale a Heroku dyno
config.adapter = :heroku
# Any configuration required for the selected adapter
# Heroku requires the following:
config.adapter_config = {
api_key: "HEROKU_API_KEY",
worker_dyno_name: "DYNO_WORKER_NAME",
app_name: "HEROKU_APP_NAME"
}
# Kubernetes requires the following:
config.adapter_config = {
deployment_name: "myapp-sidekiq",
}
# The minimum amount of time to wait between scaling events
# Useful to tweak based on how long it takes for a new worker
# to spin up and start working on the pool
# config.min_scaling_interval = 5.minutes.to_i
# The number of workers to change in a scaling event
# config.scale_by = 1
# This proc will be called on a scaling event
# config.on_scaling_event = Proc.new { |event| Rails.logger.info event.to_json }
# This proc will be called when a scaling event errors out
# By default, nothing happens
# config.on_scaling_error = Proc.new { |error| Rails.logger.error error.to_json }
end
Kubernetes
This gem can scale a Kubernetes Deployment object that Sidekiq is running in.
Doing so requires the following RBAC config:
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: myapp-sidekiq
rules:
- apiGroups: ["apps"]
resources: ["deployments"]
verbs: ["get", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: sidekiq
subjects:
- kind: ServiceAccount
name: myapp-sidekiq
roleRef:
kind: Role
name: myapp-sidekiq
apiGroup: rbac.authorization.k8s.io
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: myapp-sidekiq
Then assign your sidekiq deployment the myapp-sidekiq service account.
License
The gem is available as open source under the terms of the MIT License.