π [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 μ€μ κ°λ₯)
λκΈλ¨κΈ°κΈ°