Celery plugin to autoscale based on available CPU, memory, or other system attributes.
pip install celery-resource-autoscaler
To configure:
app = Celery()
app.conf.worker_autoscaler = 'celery_resource_autoscaler:ResourceAutoscaler'
app.conf.resource_limits = [
{
'class': 'celery_resource_autoscaler:MemoryLimit',
'kwargs': {'max_memory': 0.8},
},
{
'class': 'celery_resource_autoscaler:CPULimit',
'kwargs': {'max_load': 1.1},
},
]
Then run celery with --autoscale
enabled:
celery worker --autoscale=1000
Celery will now scale up to 1000 workers as needed, but will stop scaling if memory exceeds 80% or load per CPU exceeds 1.1.
You can provide custom Limit objects. Limit objects should provide a get_range()
function that returns the current
minimum and maximum allowed workers:
class FooLimit:
def __init__(self, min_foo=1, max_foo=10):
self.min_foo = min_foo
self.max_foo = max_foo
def get_range(self, proc_count, req):
current_foo_count = get_foo_count()
if current_foo_count > self.max_foo:
info("Foo limit: count %s exceeds maximum %s. Requesting scale down." % (current_foo_count, self.max_foo))
return (None, proc_count-1)
if cur_load < self.min_foo:
info("Foo limit: count %s below minimum %s. Requesting scale up." % (current_foo_count, self.min_foo))
return (proc_count+1, None)
return (None, None)
You can then use your custom Limit object:
app.conf.resource_limits = [
{
'class': 'foo_module:FooLimit',
'kwargs': {'max_foo': 20},
}
]
If you come up with useful generic Limit objects, pull requests are welcome!
Code for the CPU and memory limits was based on this pastebin from speedplane.
To run the all tests run:
tox
To combine the coverage data from all the tox environments run:
PYTEST_ADDOPTS=--cov-append tox