Skip to content

Commit b4709dc

Browse files
authored
Celery: cleanup pidbox keys (#10002)
* Celery: cleanup `pidbox` keys Simple task to remove `pidbox` keys older than 15 minutes. This is a workaround to avoid Redis OOM for now. We will need to find out a better solution here. There is an upstream issue opened that we should check in the near future and probably remove this workaround: celery/celery#6089 * Celery: use `redis` to get the client `app.backend.client` is not working anymore since we are not using a backend result anymore.
1 parent 3a82043 commit b4709dc

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

readthedocs/core/tasks.py

+32
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
"""Basic tasks."""
22

3+
import math
4+
5+
import redis
36
import structlog
47
from django.conf import settings
58
from django.core.mail import EmailMultiAlternatives
@@ -56,3 +59,32 @@ def clear_persistent_messages():
5659
expires__lt=timezone.now(),
5760
)
5861
expired_messages.delete()
62+
63+
64+
@app.task(queue="web")
65+
def cleanup_pidbox_keys():
66+
"""
67+
Remove "pidbox" objects from Redis.
68+
69+
Celery creates some "pidbox" objects with TTL=-1,
70+
producing a OOM on our Redis instance.
71+
72+
This task is executed periodically to remove "pdibox" objects with an
73+
idletime bigger than 5 minutes from Redis and free some RAM.
74+
75+
https://github.com/celery/celery/issues/6089
76+
https://github.com/readthedocs/readthedocs-ops/issues/1260
77+
78+
"""
79+
client = redis.from_url(settings.BROKER_URL)
80+
keys = client.keys("*reply.celery.pidbox*")
81+
total_memory = 0
82+
for key in keys:
83+
idletime = client.object("idletime", key) # seconds
84+
memory = math.ceil(client.memory_usage(key) / 1024 / 1024) # Mb
85+
total_memory += memory
86+
87+
if idletime > (60 * 15): # 15 minutes
88+
client.delete([key])
89+
90+
log.info("Redis pidbox objects.", memory=total_memory, keys=len(keys))

readthedocs/settings/base.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,12 @@ def TEMPLATES(self):
505505
'task': 'readthedocs.domains.tasks.email_pending_custom_domains',
506506
'schedule': crontab(minute=0, hour=3),
507507
'options': {'queue': 'web'},
508-
}
508+
},
509+
'every-15m-delete-pidbox-objects': {
510+
'task': 'readthedocs.core.tasks.cleanup_pidbox_keys',
511+
'schedule': crontab(minute='*/15'),
512+
'options': {'queue': 'web'},
513+
},
509514
}
510515

511516
MULTIPLE_BUILD_SERVERS = [CELERY_DEFAULT_QUEUE]

0 commit comments

Comments
 (0)