Celery
- 분산 작업 시스템을 구성할 때 쓰일 수 있는 도구 중 하나 이다.
- 웹 클라이언트의 요청에 대해, 비동기로 작업을 실행하고자 할 때 주로 쓰인다.
- 웹 서버는 기본적으로 동기적인 흐름으로 동작한다.
웹 클라이언트가 request를 보내면, 이에 대한 처리를 하고 나서, response 하게 된다.
하지만 만약 그 request가, 오랜 시간이 소요되는 작업을 요구하는 경우,
해당 작업을 마치고 동기적으로 response를 하게 되면 너무 늦어 UX를 해친다.
이러한 경우에 대비해, 실제적인 작업은 백그라운드에서 진행하면서
웹 클라이언트에는 우선 실시간으로 처리(repsonse)를 하도록 한다.
(즉, 웹 클라이언트의 요청에서 비롯된 작업이 아직 실제로 끝나지 않았지만
repsonse를 하는 형태라는 점에서, 비동기(로 작업을 실행한다)라 한다.)
- Celery beat를 통하여, 정기적인 작업을 위한 스케줄링도 가능하다.
- Celery Flower는 task와 worker에 대한 시각적 모니터링을 지원하는 툴이다.
- client <-> worker는, 쉽게 말해 producer/consumer (내지는 publisher/subscriber) 구조이다.
- message를 send하거나 receive하기 위해,
message broker라는 transport(운송 수단)를 필요로 한다.
- 다수의 worker 및 broker 들로 구성할 수 있어,
HA(High Availability. 고가용성)와 scale out(수평적 확장)이 가능하다.
client
- 이 때의 client는 웹 클라이언트(browser)를 일컫는 것이 아니라,
Flask 등과 같은 application을 일컫는다.
- client는 broker(queue)에 message를 전달한다.
- 여러 개의 client를 둘 수도 있다.
message broker
- client로부터 message를 받아와서,
worker가 작업(task)을 할 수 있도록 message를 전달한다.
- 주로 RabbitMQ나 Redis가 쓰이며, SQS 등도 가능하다.
- RabbitMQ
- Redis보다, 더 큰 message들을 잘 처리하지만
많은 message들이 매우 빠르게 들어온다면 확장에 문제가 있을 수 있다.
이에 따라, 만약 RabbitMQ가 매우 큰 규모에서 사용되지 않는 한,
Redis나 SQS 사용을 고려하는 편이 좋다.
- AMQP을 기반으로써, at least once를 충족한다.
- Redis
- 작은 message를 빠르게 전송하고자 할 때 적합하다.
- Redis는 데이터 검색을 하는 데에 있어서,
DB(하드디스크)가 아니라 cache(메모리)에 접근한다는 점에서 빠르다.
- 기본적으로, message loss를 방지하지 않는다.
- Redis는 in-memory(host 컴퓨터의 memory 이용) cache DB이며,
worker에 task를 보내고 나면 해당 task에 대한 key를 제거하는 방식으로 동작한다.
- SQS
- AWS에 의해, 확장성이 뛰어나고 완벽하게 관리되며
RabbitMQ와 유사하게 task 위임을 관리한다.
- RabbitMQ의 특징 중 하나인, worker를 원격으로 제어하는 명령은 지원하지 않는다.
- 여러 개의 broker(queue)를 둘 수 있다.
worker
- Celery 자체는 queue라기 보단 worker이며, broker로부터 message를 받아와 task를 수행한다.
- 여러 개의 worker를 둘 수 있다.
(result) backend
- worker가 작업을 끝낸 후 그 결과를 저장하는 곳이다.
- 종류
- Redis
- 매우 빠른 Key/Value 형태 저장소로써,
task 호출의 결과를 가져오는 데에 효율적이다.
- Redis를 사용할 때 설계하는 것과 마찬가지로,
데이터를 저장하는 데에 이용 가능한 메모리 한도와
데이터 persistence(영속성)에 관한 처리를 고려해야 한다.
- 결과의 persistence가 중요하다면, 또 다른 DB 사용을 고려하도록 한다.
- SQLAlchemy
- Celery가 MySQL, PostgreSQL, SQLite 등과 상호작용 할 수 있게 해준다.
즉, 이로 인해 Celery가 SQL DB를 backend로써 사용할 수 있는 것이다.
- 가장 안정된 backend는 아니므로, 이에 주의해야 할 필요가 있긴 하다.
- RabbitMQ
rpc://
를 통해 결과를 저장할 수도 있긴 하다.
이 backend는, 각 client마다 별도의 임시 큐를 생성한다.
- broker로는 RabbitMQ를, backend로는 Redis의 조합이 가장 흔하게 사용된다.
이 때, 결과 저장에 대해 장기간의 persistence이 보장되어야 한다면,
MySQL(SQLAlchemy를 통해야 함), PostgreSQL, Cassandra 등을 고려하도록 한다.