Celery en Redis voor async taken in Python
sudo apt update && sudo apt install redis-server
Start de Redis-service en controleer of deze actief is:
sudo systemctl start redis-server
sudo systemctl enable redis-serverRedis luistert standaard op TCP-poort 6379. Controleer dit met:
redis-cli ping
De output moet `PONG` zijn.
2. Installeer Celery met Redis-ondersteuning
Celery heeft een aparte package nodig voor Redis-integratie. Installeer `celery[redis]` zodat alle dependencies voor Redis-ondersteuning worden meegeleverd:pip install "celery[redis]"
Zonder deze extra package kan Celery geen verbinding maken met Redis, ook al draait de Redis-server wel.
3. Configureer de Celery-applicatie
Maak een Celery-applicatie die Redis gebruikt als message broker en result backend. Maak een bestand `celery_app.py`:from celery import Celery</p><p>app = Celery(
'tasks',
broker='redis://localhost:6379/10',
backend='redis://localhost:6379/11'
)</p><p>app.conf.update(
task_serializer='json',
accept_content=['json'],
result_serializer='json',
timezone='Europe/Amsterdam',
enable_utc=True,
)De broker en backend wijzen naar Redis-database 10 respectievelijk 11. Dit is geen verplichte configuratie maar een gangbare manier om de datastromen te isoleren. Je kunt ook database 0 gebruiken met `redis://localhost:6379/0`.
4. Definieer een asynchrone taak
Celery-taken zijn gewone Python-functies met de `@app.task`-decorator. Maak `tasks.py`:from celery_app import app</p><p>@app.task
def send_email(recipient: str, subject: str, body: str) -> dict:
# Simuleer een langdurige operatie
import time
time.sleep(5)
# Hier zou je daadwerkelijk een e-mail versturen
return {
'recipient': recipient,
'subject': subject,
'status': 'sent'
}</p><p>@app.task
def process_upload(file_path: str) -> dict:
# Verwerk een geüpload bestand
with open(file_path, 'rb') as f:
data = f.read()
# Doe iets met de data
result = {'bytes_processed': len(data)}
return resultDe decorator zorgt ervoor dat Celery de functie herkent als een asynchrone taak die door een worker kan worden uitgevoerd.
5. Start de Celery worker
De worker draait in een afzonderlijk proces, los van de hoofdapplicatie. Start de worker met:celery -A tasks worker --loglevel=info
De worker luistert naar berichten in de Redis-queue en verwerkt taken zodra ze binnenkomen. Dit is essentieel voor de asynchrone werking: de webserver blijft reageren op gebruikersverzoeken, terwijl de worker zware taken in de achtergrond afhandelt.
6. Verstuur taken vanuit je applicatie
Roep taken aan met `.delay()` of `.apply_async()`. Maak `main.py`:from tasks import send_email, process_upload
<h2>Eenvoudige aanroep met .delay()</h2>
result = send_email.delay(
'user@example.com',
'Welkom',
'Bedankt voor je registratie'
)
<h2>Geavanceerde aanroep met .apply_async()</h2>
result = process_upload.apply_async(
args=['/tmp/bestand.pdf'],
countdown=10, # start na 10 seconden
retry=True,
retry_policy={
'max_retries': 3,
'interval_start': 0,
'interval_step': 0.2,
'interval_max': 0.2,
}
)`.delay()` is een verkorte vorm van `.apply_async()` en accepteert alleen positionele argumenten. `.apply_async()` biedt meer controle zoals vertragingen, retries, callbacks en queue-selectie.
7. Haal taakresultaten op
Gebruik het result object om de status en het resultaat van een taak op te vragen. Redis fungeert hier als result backend waar resultaten tijdelijk worden bewaard:from tasks import send_email</p><p>result = send_email.delay('user@example.com', 'Test', 'Body')
<h2>Controleer of de taak klaar is</h2>
print(f"Taak klaar: {result.ready()}")
<h2>Wacht op het resultaat (blokkeert tot de taak afgerond is)</h2>
result_data = result.get(timeout=10)
print(f"Resultaat: {result_data}")
<h2>Haal de taak-ID op</h2>
task_id = result.id
print(f"Taak-ID: {task_id}")Deze functionaliteit is handig wanneer een gebruiker geïnformeerd moet worden over de voortgang van een langdurige operatie.
8. Plan periodieke taken
Celery kan ook periodieke jobs uitvoeren via `celery beat`. Voeg dit toe aan `celery_app.py`:from celery.schedules import crontab</p><p>app.conf.beat_schedule = {
'verstuur-dagelijkse-rapporten': {
'task': 'tasks.send_email',
'schedule': crontab(hour=8, minute=0),
'args': ('admin@example.com', 'Dagelijks rapport', 'Hier is het rapport'),
},
}Start de beat scheduler samen met de worker:
celery -A tasks beat --loglevel=info
Verificatie
Controleer of de setup werkt door een testtaak te versturen en het resultaat op te halen. Voer dit uit in een Python-sessie:from tasks import send_email</p><p>result = send_email.delay('test@example.com', 'Test', 'Body')
print(result.ready()) # False als de taak nog loopt
print(result.get(timeout=10)) # Wacht op het resultaatDe output moet het resultaat tonen dat in de taak is gedefinieerd, bijvoorbeeld:
{'recipient': 'test@example.com', 'subject': 'Test', 'status': 'sent'}
Controleer ook de Redis-queues:
redis-cli -n 10 llen celery
Deze command toont het aantal taken in de queue. Na verwerking moet dit 0 zijn.
Veelgestelde problemen
1. Celery kan geen verbinding maken met Redis
Controleer of Redis draait en bereikbaar is op poort 6379:redis-cli ping
Als dit `PONG` teruggeeft, controleer dan of je `celery[redis]` hebt geïnstalleerd in plaats van alleen `celery`. Zonder de extra package kan Celery geen Redis-verbinding opzetten.
2. Taken worden niet uitgevoerd
De worker moet actief zijn. Start de worker met:celery -A tasks worker --loglevel=info
Controleer de logoutput op foutmeldingen. Als de worker wel draait maar taken niet worden opgepikt, controleer dan of de broker-URL in `celery_app.py` overeenkomt met de Redis-database die je gebruikt.
3. Resultaten zijn niet beschikbaar
Als `result.get()` een `TimeoutError` geeft, controleer dan of je de backend correct hebt geconfigureerd. De backend-URL moet wijzen naar een Redis-database die verschilt van de broker-database. Gebruik bijvoorbeeld database 10 voor de broker en database 11 voor de backend:broker='redis://localhost:6379/10',
backend='redis://localhost:6379/11'Celery zelf is geen message queue maar een framework dat afhankelijk is van een externe broker zoals Redis. Redis fungeert als transportlaag tussen de applicatie (producer) en de worker (consumer). Dit onderscheid bepaalt de architectuur van je asynchrone verwerking. De Celery-documentatie voor versie 5.6.2 is bijgewerkt op 24 augustus 2026, en de Redis-specifieke pagina in versie 5.6.3 op 27 juli 2026 — het project wordt actief onderhouden en de integratie met Redis blijft evolueren, dus het loont om de officiële documentatie te blijven volgen voor nieuwe mogelijkheden en optimalisaties.