Kattava opas Celery-tehtäväjonoon, jossa on käytännön esimerkkejä Redis-integraatiosta tehokkaaseen asynkroniseen tehtävien käsittelyyn.
Celery-tehtäväjono: Hajautettu tehtävien käsittely Redis-integraation avulla
Nykypäivän yhä monimutkaisempien ja vaativampien sovellusten maailmassa kyky käsitellä tehtäviä asynkronisesti on ensisijaisen tärkeää. Celery, tehokas hajautettu tehtäväjono, tarjoaa vankan ratkaisun aikaa vievien tai resurssi-intensiivisten tehtävien siirtämiseen pois sovelluksen pääsuoritusketjusta. Yhdessä Redisin, monipuolisen muistissa olevan tietorakennevaraston, kanssa Celery tarjoaa erittäin skaalautuvan ja tehokkaan lähestymistavan taustatehtävien käsittelyyn.
Mitä on Celery?
Celery on asynkroninen tehtäväjono/työjono, joka perustuu hajautettuun viestinvälitykseen. Sitä käytetään tehtävien suorittamiseen asynkronisesti (taustalla) sovelluksen pääsuoritusketjun ulkopuolella. Tämä on ratkaisevan tärkeää seuraavista syistä:
- Sovelluksen reagoivuuden parantaminen: Siirtämällä tehtäviä Celery-työntekijöille verkkosovelluksesi pysyy reagoivana eikä jäädy monimutkaisten operaatioiden käsittelyn aikana.
- Skaalautuvuus: Celeryn avulla voit jakaa tehtäviä useille työntekijäsolmuille ja skaalata käsittelykapasiteettiasi tarpeen mukaan.
- Luotettavuus: Celery tukee tehtävien uudelleenyrityksiä ja virheiden käsittelyä, varmistaen että tehtävät suoritetaan loppuun asti myös virhetilanteissa.
- Pitkäkestoisten tehtävien käsittely: Prosessit, jotka vievät huomattavan paljon aikaa, kuten videon transkoodaus, raporttien luonti tai suurten sähköpostimäärien lähettäminen, sopivat ihanteellisesti Celerylle.
Miksi käyttää Redisiä Celeryn kanssa?
Vaikka Celery tukee useita viestinvälittäjiä (RabbitMQ, Redis, jne.), Redis on suosittu valinta sen yksinkertaisuuden, nopeuden ja helpon asennuksen vuoksi. Redis toimii sekä viestinvälittäjänä (kuljetuksena) että valinnaisesti tulosten taustajärjestelmänä Celerylle. Tässä syitä, miksi Redis sopii hyvin:
- Nopeus: Redis on muistissa oleva tietovarasto, joka tarjoaa erittäin nopean viestinvälityksen ja tulosten noudon.
- Yksinkertaisuus: Redisin asentaminen ja konfigurointi on suhteellisen suoraviivaista.
- Pysyvyys (valinnainen): Redis tarjoaa pysyvyysvaihtoehtoja, joiden avulla voit palauttaa tehtävät välittäjän vikaantuessa.
- Pub/Sub-tuki: Redisin julkaisu/tilaus-ominaisuudet sopivat hyvin Celeryn viestinvälitysarkkitehtuuriin.
Celeryn ydinkomponentit
Celeryn avainkomponenttien ymmärtäminen on olennaista tehokkaan tehtävänhallinnan kannalta:
- Celery-sovellus (celery): Pääasiallinen rajapinta Celeryn kanssa toimimiseen. Se vastaa tehtäväjonon konfiguroinnista sekä yhteyden muodostamisesta välittäjään ja tulosten taustajärjestelmään.
- Tehtävät (Tasks): Funktiot tai metodit, jotka on koristeltu
@app.task-dekoraattorilla ja jotka edustavat asynkronisesti suoritettavia työyksiköitä. - Työntekijät (Workers): Prosessit, jotka suorittavat tehtävät. Voit ajaa useita työntekijöitä yhdellä tai useammalla koneella lisätäksesi käsittelykapasiteettia.
- Välittäjä (Message Queue): Välittäjä, joka kuljettaa tehtävät sovellukselta työntekijöille. Redis, RabbitMQ ja muut viestinvälittäjät ovat käytettävissä.
- Tulosten taustajärjestelmä (Result Backend): Tallentaa tehtävien tulokset. Celery voi käyttää Redisiä, tietokantoja (kuten PostgreSQL tai MySQL) tai muita taustajärjestelmiä tulosten tallentamiseen.
Celeryn ja Redisin käyttöönotto
Tässä on vaiheittainen opas Celeryn ja Redisin käyttöönottoon:
1. Asenna riippuvuudet
Asenna ensin Celery ja Redis pip-työkalulla:
pip install celery redis
2. Asenna Redis-palvelin
Asenna redis-server. Ohjeet vaihtelevat käyttöjärjestelmän mukaan. Esimerkiksi Ubuntulla:
sudo apt update
sudo apt install redis-server
macOS:lle (käyttäen Homebrew'ta):
brew install redis
Windowsille voit ladata Redisin viralliselta verkkosivustolta tai käyttää Chocolatey-työkalua:
choco install redis
3. Konfiguroi Celery
Luo celeryconfig.py-tiedosto Celeryn konfigurointia varten:
# celeryconfig.py
broker_url = 'redis://localhost:6379/0'
result_backend = 'redis://localhost:6379/0'
task_serializer = 'json'
result_serializer = 'json'
accept_content = ['json']
timezone = 'UTC'
enable_utc = True
Selitys:
broker_url: Määrittelee Redis-välittäjän URL-osoitteen. Redisin oletusportti on 6379. `/0` edustaa Redisin tietokannan numeroa (0-15).result_backend: Määrittelee Redisin tulosten taustajärjestelmän URL-osoitteen, käyttäen samaa konfiguraatiota kuin välittäjä.task_serializerjaresult_serializer: Asettaa serialisointimenetelmäksi JSONin tehtäville ja tuloksille.accept_content: Listaa hyväksytyt sisältötyypit tehtäville.timezonejaenable_utc: Konfiguroi aikavyöhykeasetukset. On suositeltavaa käyttää UTC-aikaa yhdenmukaisuuden varmistamiseksi eri palvelimien välillä.
4. Luo Celery-sovellus
Luo Python-tiedosto (esim. tasks.py) määrittääksesi Celery-sovelluksesi ja tehtäväsi:
# tasks.py
from celery import Celery
import time
app = Celery('my_tasks', broker='redis://localhost:6379/0', backend='redis://localhost:6379/0')
app.config_from_object('celeryconfig')
@app.task
def add(x, y):
time.sleep(5) # Simulate a long-running task
return x + y
@app.task
def send_email(recipient, subject, body):
# Simulate sending an email
print(f"Sending email to {recipient} with subject '{subject}' and body '{body}'")
time.sleep(2)
return f"Email sent to {recipient}"
Selitys:
Celery('my_tasks', broker=...): Luo Celery-sovelluksen nimeltä 'my_tasks' ja konfiguroi välittäjän ja taustajärjestelmän URL-osoitteilla. Vaihtoehtoisesti voit jättää `broker`- ja `backend`-argumentit pois, jos konfiguroit ne yksinomaan käyttämällä `app.config_from_object('celeryconfig')`.@app.task: Dekoraattori, joka muuttaa tavallisen Python-funktion Celery-tehtäväksi.add(x, y): Yksinkertainen tehtävä, joka laskee kaksi lukua yhteen ja nukkuu 5 sekuntia simuloidakseen pitkäkestoista operaatiota.send_email(recipient, subject, body): Simuloi sähköpostin lähettämistä. Todellisessa tilanteessa tämä sisältäisi yhteyden ottamisen sähköpostipalvelimeen ja sähköpostin lähettämisen.
5. Käynnistä Celery-työntekijä
Avaa terminaali ja siirry hakemistoon, joka sisältää tiedostot tasks.py ja celeryconfig.py. Käynnistä sitten Celery-työntekijä:
celery -A tasks worker --loglevel=info
Selitys:
celery -A tasks worker: Käynnistää Celery-työntekijän ja määrittelee moduulin (tasks), jossa Celery-sovellus ja tehtävät on määritelty.--loglevel=info: Asettaa lokitason INFO-tasolle, mikä antaa yksityiskohtaista tietoa tehtävien suorituksesta.
6. Lähetä tehtäviä
Tuo tehtävät toisessa Python-skriptissä tai interaktiivisessa komentotulkissa ja lähetä ne Celery-työntekijälle:
# client.py
from tasks import add, send_email
# Send the 'add' task asynchronously
result = add.delay(4, 5)
print(f"Task ID: {result.id}")
# Send the 'send_email' task asynchronously
email_result = send_email.delay('user@example.com', 'Hello', 'This is a test email.')
print(f"Email Task ID: {email_result.id}")
# Later, you can retrieve the result:
# print(result.get())
Selitys:
add.delay(4, 5): Lähettääadd-tehtävän Celery-työntekijälle argumenteilla 4 ja 5.delay()-metodia käytetään tehtävän suorittamiseen asynkronisesti. Se palauttaaAsyncResult-olion.result.id: Antaa tehtävän yksilöllisen tunnisteen, jota voidaan käyttää sen edistymisen seurantaan.result.get(): Odottaa, kunnes tehtävä on valmis, ja palauttaa tuloksen. Käytä tätä varoen pääsäikeessä, sillä se kumoaa asynkronisen tehtävien käsittelyn tarkoituksen.
7. Seuraa tehtävien tilaa (valinnainen)
Voit seurata tehtävien tilaa AsyncResult-olion avulla. Sinun täytyy poistaa kommentit ja ajaa `result.get()` yllä olevassa esimerkissä nähdäksesi palautetun tuloksen, kun tehtävä on valmis, tai käyttää toista seurantamenetelmää.
Celery tarjoaa myös työkaluja, kuten Flower, reaaliaikaiseen seurantaan. Flower on verkkopohjainen seuranta- ja hallintatyökalu Celerylle.
Asenna Flower:
pip install flower
Käynnistä Flower:
celery -A tasks flower
Flower toimii tyypillisesti osoitteessa http://localhost:5555. Voit sitten seurata tehtävien tilaa, työntekijöiden tilaa ja muita Celeryn mittareita Flowerin verkkokäyttöliittymän kautta.
Celeryn edistyneet ominaisuudet
Celery tarjoaa laajan valikoiman edistyneitä ominaisuuksia tehtäväjonon hallintaan ja optimointiin:
Tehtävien reititys
Voit reitittää tehtäviä tietyille työntekijöille niiden nimen, jonojen tai muiden kriteerien perusteella. Tämä on hyödyllistä tehtävien jakamiseen resurssivaatimusten tai prioriteetin perusteella. Tämä saavutetaan käyttämällä `CELERY_ROUTES`-asetusta `celeryconfig.py`-tiedostossasi. Esimerkiksi:
# celeryconfig.py
CELERY_ROUTES = {
'tasks.add': {'queue': 'priority_high'},
'tasks.send_email': {'queue': 'emails'},
}
Sitten, kun käynnistät työntekijän, määritä jonot, joita sen tulisi kuunnella:
celery -A tasks worker -Q priority_high,emails --loglevel=info
Tehtävien ajoitus (Celery Beat)
Celery Beat on ajoitusohjelma, joka lisää tehtäviä jonoon säännöllisin väliajoin. Sitä käytetään tehtäviin, jotka on suoritettava tietyin väliajoin (esim. päivittäiset raportit, tunneittaiset varmuuskopiot). Se konfiguroidaan `CELERY_BEAT_SCHEDULE`-asetuksella `celeryconfig.py`-tiedostossasi.
# celeryconfig.py
from celery.schedules import crontab
CELERY_BEAT_SCHEDULE = {
'add-every-30-seconds': {
'task': 'tasks.add',
'schedule': 30.0,
'args': (16, 16)
},
'send-daily-report': {
'task': 'tasks.send_email',
'schedule': crontab(hour=7, minute=30), # Executes every day at 7:30 AM UTC
'args': ('reports@example.com', 'Daily Report', 'Here is the daily report.')
},
}
Käynnistä Celery Beat:
celery -A tasks beat --loglevel=info
Huom: Beat tarvitsee paikan, johon se tallentaa, milloin se viimeksi ajoi ajoitetun tehtävän. Oletuksena se käyttää tiedostopohjaista tietokantaa (celerybeat-schedule), joka ei sovellu tuotantoympäristöihin. Tuotannossa käytä tietokantapohjaista ajoitinta (esimerkiksi Redis).
Tehtävien uudelleenyritykset
Celery voi automaattisesti yrittää epäonnistuneita tehtäviä uudelleen. Tämä on hyödyllistä väliaikaisten virheiden (esim. verkkohäiriöt, väliaikaiset tietokantakatkokset) käsittelyssä. Voit konfiguroida uudelleenyritysten määrän ja viiveen niiden välillä käyttämällä retry_backoff- ja max_retries-vaihtoehtoja @app.task-dekoraattorissa.
@app.task(bind=True, max_retries=5, retry_backoff=True)
def my_task(self, arg1, arg2):
try:
# Some potentially failing operation
result = perform_operation(arg1, arg2)
return result
except Exception as exc:
self.retry(exc=exc, countdown=5) # Retry after 5 seconds
Selitys:
bind=True: Sallii tehtävän pääsyn omaan kontekstiinsa (mukaan lukienretry-metodi).max_retries=5: Asettaa uudelleenyritysten enimmäismääräksi 5.retry_backoff=True: Ottaa käyttöön eksponentiaalisen viiveen uudelleenyrityksille (viive kasvaa jokaisen yrityksen myötä). Voit myös määrittää kiinteän viiveen käyttämällä `retry_backoff=False` yhdessä `default_retry_delay`-argumentin kanssa.self.retry(exc=exc, countdown=5): Yrittää tehtävää uudelleen 5 sekunnin kuluttua. `exc`-argumentti on poikkeus, joka aiheutti virheen.
Tehtävien ketjutus ja työnkulut
Celeryn avulla voit ketjuttaa tehtäviä yhteen luodaksesi monimutkaisia työnkulkuja. Tämä on hyödyllistä tehtävissä, jotka riippuvat toisten tehtävien tuloksista. Voit käyttää chain-, group- ja chord-primitiivejä työnkulkujen määrittämiseen.
Chain (ketju): Suorittaa tehtävät peräkkäin.
from celery import chain
workflow = chain(add.s(4, 4), multiply.s(8))
result = workflow.delay()
print(result.get()) # Output: 64
Tässä esimerkissä add.s(4, 4) luo allekirjoituksen add-tehtävästä argumenteilla 4 ja 4. Vastaavasti multiply.s(8) luo allekirjoituksen multiply-tehtävästä argumentilla 8. chain-funktio yhdistää nämä allekirjoitukset työnkuluksi, joka suorittaa ensin add(4, 4) ja välittää sitten tuloksen (8) multiply(8)-tehtävälle.
Group (ryhmä): Suorittaa tehtävät rinnakkain.
from celery import group
parallel_tasks = group(add.s(2, 2), multiply.s(3, 3), send_email.s('test@example.com', 'Parallel Tasks', 'Running in parallel'))
results = parallel_tasks.delay()
# To get results, wait for all tasks to complete
for res in results.get():
print(res)
Chord (sointu): Suorittaa ryhmän tehtäviä rinnakkain ja suorittaa sitten takaisinkutsutehtävän ryhmän tuloksilla. Tämä on hyödyllistä, kun sinun täytyy yhdistää useiden tehtävien tulokset.
from celery import group, chord
header = group(add.s(i, i) for i in range(10))
callback = send_email.s('aggregation@example.com', 'Chord Result', 'Here are the aggregated results.')
workflow = chord(header)(callback)
result = workflow.delay()
# The callback task (send_email) will execute after all tasks in the header (add) are completed
# with the results passed to it.
Virheiden käsittely
Celery tarjoaa useita tapoja käsitellä virheitä:
- Tehtävien uudelleenyritykset: Kuten aiemmin mainittiin, voit konfiguroida tehtävät yrittämään automaattisesti uudelleen epäonnistumisen jälkeen.
- Virheiden takaisinkutsut: Voit määrittää virheiden takaisinkutsuja, jotka suoritetaan, kun tehtävä epäonnistuu. Ne määritellään `link_error`-argumentilla `apply_async`- tai `delay`-metodissa tai osana ketjua.
- Globaali virheiden käsittely: Voit konfiguroida Celeryn lähettämään virheraportteja seurantapalveluun (esim. Sentry, Airbrake).
@app.task(bind=True)
def my_task(self, arg1, arg2):
try:
result = perform_operation(arg1, arg2)
return result
except Exception as exc:
# Log the error or send an error report
print(f"Task failed with error: {exc}")
raise
@app.task
def error_handler(request, exc, traceback):
print(f"Task {request.id} failed: {exc}\n{traceback}")
#Example usage
my_task.apply_async((1, 2), link_error=error_handler.s())
Parhaat käytännöt Celeryn ja Redisin käyttöön
Varmistaaksesi optimaalisen suorituskyvyn ja luotettavuuden, noudata näitä parhaita käytäntöjä:
- Käytä luotettavaa Redis-palvelinta: Tuotantoympäristöissä käytä erillistä Redis-palvelinta, jossa on asianmukainen valvonta ja varmuuskopiot. Harkitse Redis Sentinelin käyttöä korkean saatavuuden varmistamiseksi.
- Säädä Redisin konfiguraatiota: Säädä Redisin konfiguraatioparametreja (esim. muistirajat, poistokäytännöt) sovelluksesi tarpeiden mukaan.
- Valvo Celery-työntekijöitä: Valvo Celery-työntekijöidesi kuntoa ja suorituskykyä tunnistaaksesi ja ratkaistaksesi ongelmat nopeasti. Käytä työkaluja, kuten Flower tai Prometheus, valvontaan.
- Optimoi tehtävien serialisointi: Valitse sopiva serialisointimenetelmä (esim. JSON, pickle) tehtäväargumenttiesi ja tulostesi monimutkaisuuden ja koon perusteella. Ole tietoinen tietoturvavaikutuksista, kun käytät pickleä, erityisesti epäluotettavan datan kanssa.
- Pidä tehtävät idempotentteina: Varmista, että tehtäväsi ovat idempotentteja, eli ne voidaan suorittaa useita kertoja aiheuttamatta tahattomia sivuvaikutuksia. Tämä on erityisen tärkeää tehtävissä, joita saatetaan yrittää uudelleen epäonnistumisen jälkeen.
- Käsittele poikkeukset siististi: Toteuta asianmukainen virheidenkäsittely tehtävissäsi estääksesi odottamattomat kaatumiset ja varmistaaksesi, että virheet kirjataan tai raportoidaan asianmukaisesti.
- Käytä virtuaaliympäristöjä: Käytä aina virtuaaliympäristöjä Python-projekteissasi riippuvuuksien eristämiseksi ja konfliktien välttämiseksi.
- Pidä Celery ja Redis ajan tasalla: Päivitä säännöllisesti Celery ja Redis uusimpiin versioihin hyötyäksesi virheenkorjauksista, tietoturvakorjauksista ja suorituskyvyn parannuksista.
- Asianmukainen jononhallinta: Määritä tietyt jonot eri tehtävätyypeille (esim. korkean prioriteetin tehtävät, taustakäsittelytehtävät). Tämä mahdollistaa tehtävien priorisoinnin ja hallinnan tehokkaammin.
Kansainväliset näkökohdat
Kun käytät Celeryä kansainvälisissä yhteyksissä, ota huomioon seuraavat seikat:
- Aikavyöhykkeet: Varmista, että Celery-työntekijäsi ja Redis-palvelimesi on konfiguroitu oikealla aikavyöhykkeellä. Käytä UTC-aikaa yhdenmukaisuuden varmistamiseksi eri alueiden välillä.
- Lokalisaatio: Jos tehtäväsi käsittelevät tai tuottavat lokalisoitua sisältöä, varmista, että Celery-työntekijöilläsi on pääsy tarvittaviin paikallistietoihin ja kirjastoihin.
- Merkistökoodaus: Käytä UTF-8-koodausta kaikissa tehtäväargumenteissa ja tuloksissa tukeaksesi laajaa valikoimaa merkkejä.
- Tietosuoja-asetukset: Ole tietoinen tietosuoja-asetuksista (esim. GDPR), kun käsittelet henkilötietoja tehtävissäsi. Toteuta asianmukaiset turvatoimet arkaluonteisten tietojen suojaamiseksi.
- Verkon viive: Ota huomioon verkon viive sovelluspalvelimesi, Celery-työntekijöiden ja Redis-palvelimen välillä, erityisesti jos ne sijaitsevat eri maantieteellisillä alueilla. Optimoi verkkokonfiguraatio ja harkitse maantieteellisesti hajautetun Redis-klusterin käyttöä suorituskyvyn parantamiseksi.
Esimerkkejä todellisesta maailmasta
Tässä on joitakin esimerkkejä todellisesta maailmasta, kuinka Celeryä ja Redisiä voidaan käyttää yleisten ongelmien ratkaisemiseen:
- Verkkokauppa-alusta: Tilausten käsittely, tilausvahvistusten lähettäminen, laskujen luominen ja varaston päivittäminen taustalla.
- Sosiaalisen median sovellus: Kuvien latausten käsittely, ilmoitusten lähettäminen, personoitujen syötteiden luominen ja käyttäjätietojen analysointi.
- Rahoituspalvelusovellus: Tapahtumien käsittely, raporttien luominen, riskinarviointien suorittaminen ja hälytysten lähettäminen.
- Koulutusalusta: Tehtävien arviointi, todistusten luominen, kurssimuistutusten lähettäminen ja opiskelijoiden suoritusten analysointi.
- IoT-alusta: Sensoritietojen käsittely, laitteiden ohjaus, hälytysten luominen ja järjestelmän suorituskyvyn analysointi. Esimerkiksi, harkitse älymaatalouden skenaariota. Celeryä voitaisiin käyttää käsittelemään sensorilukemia maatiloilta eri alueilta (esim. Brasilia, Intia, Eurooppa) ja käynnistämään automaattisia kastelujärjestelmiä näiden lukemien perusteella.
Yhteenveto
Celery yhdessä Redisin kanssa tarjoaa tehokkaan ja monipuolisen ratkaisun hajautettuun tehtävien käsittelyyn. Siirtämällä aikaa vieviä tai resurssi-intensiivisiä tehtäviä Celery-työntekijöille voit parantaa sovelluksen reagoivuutta, skaalautuvuutta ja luotettavuutta. Rikkaiden ominaisuuksiensa ja joustavien konfigurointivaihtoehtojensa ansiosta Celery voidaan mukauttaa monenlaisiin käyttötapauksiin, yksinkertaisista taustatehtävistä monimutkaisiin työnkulkuihin. Celeryn ja Redisin omaksuminen avaa mahdollisuuden rakentaa erittäin suorituskykyisiä ja skaalautuvia sovelluksia, jotka pystyvät käsittelemään monipuolisia ja vaativia työkuormia.