Celery의 기본구성요소와 일반적인 Producer/Consumer 기반의 task queue에 대해 보겠습니다.
목표
- Celery 같은 task queue 사용 이유에 대해 알 수 있습니다.
- producer/consumer 모델을 알아보고, Celery와의 관련성을 알 수 있습니다.
Celery 사용 이유
Celery는 FastAPI, Django, Flask와 같은 Python 기반 웹 프레임워크와 자주 연동되는 오픈 소스, 비동기 태스크 큐입니다. 이는 전형적인 요청/응답 주기 외부에서 백그라운드 작업을 관리하기 위한 것입니다. 즉, 사용자가 작업이 끝나기를 기다리게 하지 않고 즉시 HTTP 응답을 반환한 다음, 프로세스를 백그라운드 태스크로 실행할 수 있습니다.
사용 케이스
- 댓글 기능에서 "@사용자이름"을 언급하면 언급된 사용자는 그 후 이메일 알람을 받습니다.
예를들어, '@홍길동'과 같이 한 명만 언급되었다면 동기적으로 처리하는 것이 괜찮습니다.
하지만 열명 이상이라면, 열 개의 다른 이메일을 보내야 합니다. 외부 API를 이용하여 처리하므로 network I/O가 발생하므로
이를 백그라운드로 처리하면 메인 프로세스에서 blocking이 생기지 않을 것입니다. - 프로필 이미지 업로드 시, 썸네일 생성을 위해서는 background로 process로 처리 할 수 있습니다.
웹앱을 구축 할 때 요청과 응답의 시간은 통상 500ms미만인지 확인해야 합니다.
New Relic이나 Scout과 같은 애플리케이션 성능 모니터링 도구를 사용하여 잠재적인 문제를 파악하고, Celery를 통해서 오랫동안 처리되는 프로세스를 별도로 격리하여 백그라운드 프로세스로 옮겨 처리 할 수 있습니다.
Celery vs FastAPI의 백그라운드 테스크
Starlette 에서 직접 제공되는 FastAPI의 BackgroundTasks 클래스를 활용하여 백그라운드에서 작업을
실행할 수 있다는 점은 주목할 가치가 있습니다.
from fastapi import BackgroundTasks
def send_email(email, message):
pass
@app.get("/")
async def ping(background_tasks: BackgroundTasks):
background_tasks.add_task(send_email, "email@address.com", "Hi!")
return {"message": "pong!"}
그럼 언제 BackgroundTasks
대신 Celery를 사용 할 까요?
"CPU intensive tasks"와 "Task queue"는 Celery를 사용하는 두 가지 다른 시나리오를 나타냅니다. 각각의 케이스가 다루는 문제와 필요성이 다릅니다:
CPU Intensive Tasks (CPU 집약적 작업)
이 경우는 백그라운드에서 무거운 계산을 수행해야 할 때 Celery를 사용하는 것이 좋습니다. 예를 들어, 비디오 인코딩, 대규모 데이터 처리, 과학적 계산 등 CPU 자원을 많이 소모하는 작업이 여기에 해당됩니다. 이러한 작업은 애플리케이션의 메인 이벤트 루프나 메인 스레드에서 처리할 경우 애플리케이션의 반응성과 성능에 부정적인 영향을 줄 수 있습니다. 따라서, 이러한 작업을 별도의 백그라운드 프로세스나 워커로 분리하여 처리함으로써, 애플리케이션의 메인 이벤트 루프가 사용자 요청에 더 빠르고 효율적으로 반응할 수 있도록 합니다.
Task Queue (태스크 큐)
태스크 큐 사용 시나리오는 작업의 실행을 조정하고 관리할 필요가 있을 때 적합합니다. 이는 단순히 CPU 집약적인 작업뿐만 아니라, 이메일 전송, 정기적인 데이터베이스 정리, 사용자 알림 발송 등 다양한 종류의 백그라운드 작업을 포함할 수 있습니다. 태스크 큐를 사용하면 작업을 비동기적으로 실행할 수 있을 뿐만 아니라, 작업의 상태를 추적하고, 성공 또는 실패 시 특정 액션을 취할 수 있는 등의 복잡한 워크플로우를 구현할 수 있습니다. 예를 들어, 작업이 실패했을 때 재시도 로직을 구현하거나, 작업 완료 후 사용자에게 알림을 보내는 등의 처리가 가능합니다.
요약하면
- CPU Intensive Tasks : CPU 자원을 많이 사용하는 작업을 백그라운드에서 처리하기 위해 Celery를 사용합니다. 이는 애플리케이션의 성능을 유지하면서 무거운 작업을 효과적으로 처리하기 위함입니다.
- Task Queue : 복잡한 작업 흐름과 상태 관리가 필요한 경우에 Celery를 사용합니다. 태스크 큐는 작업의 실행을 조정하고, 성공/실패에 따른 후속 처리를 가능하게 합니다.
두 시나리오 모두 Celery를 사용함으로써 애플리케이션의 성능과 사용자 경험을 개선할 수 있지만, 각각의 사용 사례에 따라 구체적인 이유와 방식이 다릅니다.
메시지 브러커 and Result backend
메시지 브로커
: 작업을 생성하거나 소비하기 위한 전송으로 사용되는 중개 프로그램입니다Result backend
: Celery task 결과를 저장하는데 사용됩니다.
Celery client는 메시지 브로커를 통해 대기열에 새 작업을 추가하는 생산자입니다.
Celery woker는 메시지 브로커를 통해 대기열의 새 작업을 사용합니다. 처리된 결과는 Result backend
에 저장됩니다.
'프로그래밍 언어 > 파이썬' 카테고리의 다른 글
Celery와 FastAPI - 3 (0) | 2024.03.23 |
---|---|
Celery와 FastAPI - 2 (1) | 2024.03.22 |
classmethod와 staticmethod의 차이 (0) | 2024.03.21 |
파이썬에서 접근제어 지시자 (0) | 2024.03.20 |
Call by Assignment란? (0) | 2024.03.20 |