Celery, FastAPI, Redis, Flower를 이용한 비동기 분산처리 구현

Celery 란?
비동기 분산 처리를 위한 프레임워크
- 장,단점
- 장점
- 비동기 처리를 지원하여 작업이 완료될 때까지 기다리지 않고 다른 작업을 처리할 수 있다.
- 분산 처리를 지원하여 여러 서버에서 작업을 분산하여 처리하고, 결과를 수집할 수 있다.
- 작업 큐를 이용하여 작업 요청을 저장하고, 순서대로 처리할 수 있다.
- 작업 스케줄링을 이용하여 작업 요청을 일정한 시간 간격으로 처리할 수 있다.
- 작업 모니터링을 이용하여 작업의 진행 상황을 실시간으로 확인할 수 있다.
- 다양한 프로그래밍 언어와 데이터베이스를 지원하여 대규모 분산 처리 시스템을 구축하는 데 사용.
- 단점
- 분산 처리를 위한 인프라와 기술을 충분히 이해하고, 이를 구현하는 데 필요한 지식과 경험이 필요합니다.
- 비동기 처리를 사용하기 때문에, 작업이 완료되는 시간이 예상보다 오래 걸릴 수 있다.
- 분산 처리를 위한 네트워크 통신이 필요하기 때문에, 네트워크 지연이 발생할 수 있다.
- 작업 모니터링을 위한 추가적인 자원이 필요.
- 설정이 복잡하여 초보자가 사용하기 어려울 수 있다.
- Celery, Redis의 통신 방식
- FastAPI에 있는 Celery task의 작업이 메시지 형태로 Redis에 전달
- Celery worker가 정기적으로 Redis를 확인해 task가 있는지 확인을 하고 작업을 가져와 실행
- 작업 실행이 완료 되면 결과를 백엔드에 저장
- 클라이언트가 백엔드를 조회해 결과를 받아간다.(task.id로 조회)
- Celery worker의 작업 방식
- Prefork(=Multi Processing)
- Eventlet
- 동기 HTTP 요청과 같은 이벤트 기반 I/O 작업을 처리할 때 효과적
- Thread fool
- Gevent
- 이벤트 기반 I/O 작업, 특히 많은 수의 동시 네트워크 연결을 처리해야 하는 경우에 유리
Celery, FastAPI, Redis, Flower를 이용한 비동기 분산처리 구현
- Gtihub 링크 : https://github.com/highfreshness/demo.celery-fastapi-redis-flower
- 목적
- AI 모델을 서빙하는 API를 비동기 분산처리 구현
- 조건
- FastAPI, Redis, Celery worker, Flower 모두 다른 환경에서 동작하며 중복되는 코드를 최대한 제거한다.
- TIP
- 테스트 시 task.delay의 결과를 어떻게 받을 것인가에 따라 요청의 처리속도가 달라지는 것을 확인했다.
- 요청의 응답으로 ID를 반환(=get() 사용 X)
- 장점 : 요청의 개수에 관계 없이 빠르게 worker에 분배되며 FastAPI 엔드 포인트에서도 바로 ID를 통해 응답 받을 수 있다.(비동기식 처리가 가능)
- 단점 : 유저 입장에서는 ID를 받아서 FastAPI 다른 엔드포인트에서 작업에 대한 상태 값을 직접 확인해 완료 상태일 때 결과를 확인할 수 있다.(유저 편의성 하향)
- 요청의 응답을 바로 출력(=get() 사용 O)
- 장점 : 요청 시 작업 처리되는 시간만 기다리면 결과가 바로 보이기 때문에 편의성이 올라간다.
- 단점 : 요청 시 worker의 개수에 따라 한번에 처리할 수 있는 양이 정해져있으며 요청이 쌓여 처리가 안되면 timeout 시간에 따라 500 HTTP response를 받을 수 있다.
- 기존 FastAPI 컨테이너에서 Celery task 정의 없이 worker에 작업을 전달하기 위해
signature 함수에 인자와 worker에 정의된 task의 이름을 입력하면 FastAPI 컨테이너에서 별도의 task 정의 없이 worker로 작업에 필요한 값만 보낼 수 있다.
- ✨ 의문점
- Celery worker의 concurrency 증가 // Celery worker 컨테이너 scale 증가 중 병렬 처리에 더 유효한 방법은 ?
- 벙렬처리 방법 중 어떤 것이 더 좋은지 고민해봤으나 상황에 따라 다를 것 같다고 판단했다.
- 단일 환경, CPU 및 자원에 여유가 있는 경우 worker의 동시성 증가가 구성이 유리
- AWS의 EC2 처럼 자원이 한정되어 있고 scale out이 사용 가능한 환경일 땐 컨테이너의 증가가 더 유리