[Python] Celery란 무엇인가? (Python 비동기 작업 큐 정리)

류지수·2025년 7월 17일
0

최근 작업에서는 텍스트를 전처리한 후, GPU 서버에 있는 LLM 모델을 호출해 분석하는 태스크를 처리하고 있다. 그런데 이 과정에서 동시에 여러 개의 요청이 들어오면 500 에러가 발생하는 문제가 있었다.

서버 리소스를 보호하기 위해 asyncio.Semaphore를 적용해 작업의 동시 실행 수를 제한했다. 이 방법 덕분에 한 번에 너무 많은 작업이 실행되는 것을 막을 수 있었고, 즉각적인 메모리 과부화(OOM)는 방지할 수 있었다.

하지만 요청이 많아지면 전체 처리 속도가 느려졌고, 결국 Semaphore는 "한 호출 내의 동시성"을 제한할 뿐, 여러 사용자의 요청이 동시에 들어오는 상황 자체는 여전히 컨트롤할 수 없었다.

이러한 구조의 한계 때문에 자연스럽게 Celery라는 도구를 검토하게 되었다.


Celery란?

Celery는 Python에서 널리 사용되는 비동기 작업 큐(Task Queue) 시스템이다.

웹 서버로 들어온 무거운 작업을 큐에 넣어, 웹 프로세스와는 분리된 워커(worker)가 비동기적으로 실행하도록 해준다. 이 과정에서 Redis, RabbitMQ 같은 메시지 브로커(Broker)를 통해 작업 요청과 실행을 안전하게 분리한다.

어떤 상황에 유리한가?

다음과 같은 작업은 서버에서 직접 처리하면 무겁고, 응답 지연 또는 서버 과부하를 초래할 수 있다:

  • LLM 기반 텍스트 분석
  • 외부 API 호출 (ex. AI inference, OCR 등)
  • 대용량 파일 처리 및 변환
  • 이메일 발송, 슬랙 알림 전송
  • PDF 문서 변환 및 임베딩 처리
문제설명
느린 응답작업 완료까지 대기해야 하므로 사용자 경험 저하
서버 과부하CPU, 메모리 과도하게 사용됨
장애 가능성동시에 여러 요청이 몰릴 경우 OOM 발생
확장 어려움단일 서버나 프로세스 수준에서 동시성 제어 한계

Celery의 구성 요소

  • Producer (FastAPI 등): 작업 요청을 큐에 넣는다.
  • Broker (Redis, RabbitMQ 등): 작업을 큐 형태를 저장하고 전달
  • Worker: 큐에서 작업을 꺼내서 실행
  • Result Backend (선택): 작업 결과를 저장하거나 추적

*이 구조를 따르면 요청과 실행이 분리되고, 작업은 워커가 필요한 만큼만 꺼내서 처리하므로 동시 처리량 제한이나 분산 처리도 쉽게 가능해진다.


구조 요약

[ FastAPI 서버 ] → [ Redis (Broker) ] → [ Celery 워커 ] → [ 결과 저장 (선택) ]
  • 서버는 요청을 큐에 넣고 즉시 응답
  • 워커는 큐에서 하나씩 꺼내서 백그라운에서 처리
  • 결과는 Redis, DB 등에 저장하거나 추후 조회 가능

간단 코드

1. Celery 설정

# celery_app.py
from celery import Celery

celery_app = Celery(
    "worker",
    broker="redis://localhost:6379/0",
    backend="redis://localhost:6379/1"
)

2. Task 정의

# tasks.py
from celery_app import celery_app

@celery_app.task
def slow_add(x, y):
    import time
    time.sleep(5)
    return x + y

3. FastAPI 연동

# main.py
from fastapi import FastAPI
from tasks import slow_add

app = FastAPI()

@app.get("/add")
def add(x: int, y: int):
    task = slow_add.delay(x, y)
    return {"task_id": task.id, "status": "processing"}

마무리

Celery를 도입하면 복잡하거나 무거운 작업을 비동기적으로 분리할 수 있어 웹 서버의 안정성과 응답 속도를 개선할 수 있다. 단순한 asyncio.Semaphore 기반의 동시성 제어가 구조적으로 한계를 가지는 상황이라면, Celery는 훨씬 확장 가능한 대안이 될 수 있다.

profile
끄적끄적

0개의 댓글