π [Python] Celeryμ λν΄μ
Celeryλ?
Celery λ, λμμ± νλ‘κ·Έλλ°μμ κ°μ₯ λ§μ΄ μ¬μ©νλ κΈ°λ² μ€ νλμ.
λΆμ° λ©μμ§ μ λ¬μ κΈ°λ°μΌλ‘ λμνλ λΉλκΈ° μμ ν λΌκ³ νλ€.
- μ¦, μ€μκ° μ²λ¦¬μ μ€μ μ λκ³ μμ
μμ½μ μ§μνλ μμ
ν μΈκ±°μ!!
- μ€μΌμ€λ§λ μ§μνκΈ΄ ν¨
Celeryλ λ©μμ§λ₯Ό μ λ¬νλ μν (Publisher)κ³Ό λ©μμ§λ₯Ό Message Broker μμ κ°μ Έμ μμ
μ μννλ Worker μ μν μ λ΄λΉνλ€.
Worker?
Worker λ μΉ μλΉμ€μμ λ°±μλμ μμ
μ μ²λ¦¬νλ λ³λμ Frame μ!
μ΄λ‘ μΈν΄ μ¬μ©μμκ² μ¦κ°μ μΈ λ°μμ 보μ¬μ€ νμκ° μλ μμ λ€λ‘ μΈν΄ μ¬μ©μκ° λλΌλ μκ° μ§μ°μ μ΅μν ν μ μμ.
μ΄μ²λΌ Celery λ₯Ό μ¬μ©νλ©΄, API μλ²λ₯Ό κ°λ°νκ³ μ΄μνλ©΄μ μ¬μ©μ μμ²μ ν¬ν¨λ νμκ° μλ λΆνμν κ³Όμ μ΄λ λ¬΄κ±°μ΄ μΏΌλ¦¬ μ€ν λ±μ μμ
μ Celery Task λ‘ μ μν΄μ Broker(RabbitMQ, Redis λ±) μ Consumer(Celery Worker) λ₯Ό μ΄μ©ν΄ λΉλκΈ° μ²λ¦¬νμ¬ μ¬μ©μμκ² λΉ λ₯΄κ² μλ΅μ μ 곡ν μ μλ€!!
[μ¬μ©μ μμ²μ ν¬ν¨λ νμ μλ μμ μμ]
- νμκ°μ
μΆν μ΄λ©μΌ λ°μ‘
- μ£Όλ¬Έ λ΄μ λ€μ΄λ‘λ
Celery κ΅¬μ± μμ
Broker
Broker λ Task(Message)λ₯Ό Worker μκ² μ λ¬νλ μν μ
Client
Client λ Taskλ₯Ό μμ± νλ μν μ
Worker
Worker λ Taskλ₯Ό μ€ννκ³ μ²λ¦¬νλ μν
Celery νΉμ§?
ClientλWorkerλ μ°κ²° μ μ€μ΄λ μ€ν¨μ λν΄ μλμΌλ‘ μ¬μλ νλ©°,Broker,Workerλ₯Ό HA ꡬμ±νμ¬ κ³ κ°μ©μ±μ΄ λ°μ΄λλ€!- HA ꡬμ±:
High Availavilityβ κ³ κ°μ©μ± μ΄λΌλ λ»μ
- HA ꡬμ±:
- λ¨μΌ
Celeryνλ‘μΈμ€λ μ΅μ ν μ€μ μ ν΅ν΄msλ¨μ μ λμ λκΈ° μκ°μΌλ‘ λΆλΉ μλ°±λ§ κ°μ μμ μ μ²λ¦¬ν μ μμ μ λλ‘ λΉ λ¦ Celeryλ νμ₯μ±μ΄ λ§€μ° λ°μ΄λ κ±°μ λͺ¨λ λΆλΆμ 컀μ€ν νμ¬ μ¬μ©ν μ μλ€!
Celery λμ ꡬ쑰
Celeryλ μΉ μλ²μμ λ°μν μμ²(Task) μ Message Broker μμ λ°μ Celeryλ₯Ό μ΄μ©ν΄ λΆμ° μ²λ¦¬ν¨!
Celeryμμλ μμ μ΄ μλ£λλ μ΄λ²€νΈμ λν΄ DB Taskλ₯Ό μνν¨!
Celery Broker?
Broker λ Client μ Worker μ¬μ΄μμ λ©μμ§λ₯Ό μ λ¬νλ μν μ!
5.0 λ²μ κΈ°μ€μΌλ‘ λ€μκ³Ό κ°μ Broker λ₯Ό μ§μνλ€κ³ νλ€.
- RabbitMQ
- RabbitMQμ μΈμ¦ λ° μΈκ° λ°©μμ κ·Έλλ‘ μ¬μ©ν μ μλ€!
- λ§€μ° ν¨μ¨μ & κ΄λ²μν λ°°ν¬ λ° ν μ€νΈλ λ©μμ§ λΈλ‘컀μ
- κ³ κΈ λΌμ°ν μꡬ μ¬νμ΄ μλ μν°νλΌμ΄μ¦ λ©μμ§μ μ 곡νλλ°μ μ ν©
- Redis
- μμμ΄ λΉ λ₯΄κ³ κ°λ²Όμ΄
Broker - νμ§λ§ μμ μ μΈ μ λ¬μ μ§μνμ§λ μλλ€
- μμ€ν μ΄ μ’ λ£λλ κ²½μ°, λͺ λΆ λμ μμ μ λν μ λ³΄κ° μμ€λλ κ²μ΄ μ€μνμ§ μμ μ ν리μΌμ΄μ μ μ ν©
Redisμμ²΄κ° λ©λͺ¨λ¦¬λ₯Ό μ¬μ©νμ¬ μ μ₯νλ λ°©λ²μ΄λΌ, λ©λͺ¨λ¦¬κ° λΆμ‘±ν μν©μμλ μμλ‘Keyκ° μμ λ μ μμ βTaskλ₯Ό λ°μλ μμ λ μ μμ- λ©μμ§ μμ€ λ°©μ§ κΈ°λ²μ΄ μμγ γ
- μμμ΄ λΉ λ₯΄κ³ κ°λ²Όμ΄
- Amazon SQS
- Zookeeper
Celery μ¬μ© μμ
μ§ν μ€μΈ νλ‘μ νΈμμ Celeryλ₯Ό μ¬μ©νκ² λμλ€.
μ²μ μ¨λ³΄λ κΈ°μ μ΄κΈ° λλ¬Έμ μ μ μ‘°μ°¨ λ―μ€κ³ μ΄λ €μ λ€.
λ€μμ νλ‘μ νΈμ μΆκ°ν Celery μ
μ
μ½λμ΄λ€.
config/celery.py
import os
from celery import Celery
from celery.schedules import crontab
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery("hellotarot")
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
@app.task(bind=True)
def debug_task(self):
print("Request: {0!r}".format(self.request))
app.conf.beat_schedule = {
"update-status-5-minutes": {
"task": "check_game_status",
"schedule": crontab(second="*/1")
}
}
μ½λ ν΄μ
import os
from celery import Celery
from celery.schedules import crontab
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery("hellotarot")
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
crontab: μ λ¬λ¦¬ μ€μΌμ€μμcronμμ κ³Ό μ μ¬ν μ€μΌμ€μ μ μνλ λ° μ¬μ©νλ€.cron: μ λμ€ κΈ°λ° μμ€ν μμ μκ° κΈ°λ°μ μμ μ€μΌμ€λ¬λ‘, μ¬μ©μκ° μ§μ ν μκ°μ μλμΌλ‘ μ€ν¬λ¦½νΈ μ€ν, λͺ λ Ήμ΄ μ€ν λ±μ μ μ μ λ°λ³΅μ μΌλ‘ μννλλ‘ μμ½νλ€.
- κΈ°λ³Έ Django μ€μ λͺ¨λμ
config.settingsλ‘ μ€μ νλ€.configλλ ν 리μsettings.pyκ° μκ³ , ν΄λΉ νμΌμ νλ‘μ νΈ κ΅¬μ±μ΄ ν¬ν¨λμ΄ μμ΄μΌ νλ€.
hellotarotμ΄λΌλ μ΄λ¦μΌλ‘Celery μΈμ€ν΄μ€λ₯Ό μμ±νλ€.- Django νλ‘μ νΈ μ€μ μμ Celery μ€μ μ λ‘λνλ€. νΉν
CELERYλ€μμ€νμ΄μ€ λ΄μ μ€μ μ λ‘λνλ€. - μ΄λ κ² νλ©΄ Django μ€μ μμ μ μν λͺ¨λ μ¬μ©μ μ§μ Celery μ€μ μ΄ μ μ©λλ€.
- νλ‘μ νΈ λ΄μμ μμ
μ μ(
@app.taskλ‘ λ°μ½λ μ΄μ λ ν¨μ)λ₯Ό μλμΌλ‘ κ²μνμ¬ μμ λ±λ‘μ κ°μν νλ€!
@app.task(bind=True)
def debug_task(self):
Β Β print("Request: {0!r}".format(self.request))
@app.task(bind=True):debug_taskλΌλ μ΄λ¦μ μμ μ μ μν¨. 첫 λ²μ§Έ μΈμλ‘selfλ₯Ό νμ©νκ³ ,bind=Trueλ°μ½λ μ΄ν°λ μμ λ©νλ°μ΄ν°(selfμΈμ)μ λν μμΈμ€λ₯Ό νμ©νλ€.print("Request: {0!r}".format(self.request)): μμ λ΄μμ μμ μμ²μ μΈλΆ μ 보λ₯Ό μΆλ ₯νλ μ©λμ΄λ©°, λλ²κΉ μ μ©μ΄νκ² μ°μΈλ€.
app.conf.beat_schedule = {
Β Β "update-status-5-minutes": {
Β Β Β Β "task": "check_game_status",
Β Β Β Β "schedule": crontab(second="*/1")
Β Β }
}
app.conf.beat_schedule: μ΄ μ¬μ μ Celery Beatλ₯Ό μ¬μ©νμ¬ μ£ΌκΈ°μ μΈ μμ μ μν μ€μΌμ€μ μ μνλ€.update-status-5-minutes: μμ½λ μμ μ μ΄λ¦μtask: μ€νν μμ μ μ΄λ¦μschedule:crontabμ μ¬μ©ν΄ μ€μΌμ€μ μ μν¨crontab(second="*/1"): μμ μ 1μ΄λ§λ€ μ€ν (second, minute, hour μ€μ κ°λ₯)
λκΈλ¨κΈ°κΈ°