Celery worker concurrency가 낮아 보일 때, 겉으로 보이는 문제는 worker count가 적은 것 같지만 실제로는 pool model, task 형태, prefetch 동작, broker 흐름, blocking dependency 때문에 체감 병렬성이 훨씬 낮아지는 경우가 많습니다.
짧게 말하면, 설정된 concurrency 숫자만 보지 말고 실제로 동시에 진전되는 task 수를 먼저 확인한 뒤, task duration, prefetch, blocking dependency를 봐야 합니다.
먼저 설정된 slot 수와 실제 throughput을 구분하세요
worker가 높은 concurrency를 광고하더라도 실제 throughput이 낮을 수 있습니다.
task가 길거나, 분배가 나쁘거나, downstream system에 막히거나, prefetch 때문에 특정 worker에 치우치면 설정된 숫자보다 훨씬 약하게 보입니다. 그래서 raw worker count는 표면적인 숫자일 뿐입니다.
concurrency가 낮아 보이는 흔한 이유
1. task가 예상보다 오래 block 됨
database wait, 외부 API call, filesystem 작업, CPU-heavy section이 worker slot을 오래 점유할 수 있습니다.
그러면 사용 가능한 병렬 capacity가 빠르게 사라집니다.
2. pool choice가 workload와 맞지 않음
prefork, threads, gevent, eventlet 계열은 CPU-heavy인지, I/O block이 많은지, 혼합형인지에 따라 체감 성능이 달라집니다.
workload에 맞지 않는 pool model은 설정 숫자보다 훨씬 약한 concurrency로 보이게 만듭니다.
3. prefetch가 작업 분배를 왜곡함
worker가 task를 너무 많이 먼저 잡아두면 다른 worker는 덜 쓰이는데도 전체 시스템은 병렬성이 낮아 보일 수 있습니다.
이때는 queue가 길고 분배가 끈적하게 보이는 현상이 같이 나옵니다.
4. broker나 downstream pressure가 실제 진행을 늦춤
queue는 꽉 차 있지만 worker는 실질적으로 일을 끝내기보다 다른 곳을 기다리며 시간을 보내고 있을 수 있습니다.
5. memory와 worker model tradeoff를 무시하고 있음
기술적으로 concurrency를 더 높일 수 있어도 memory duplication, process churn, downstream pressure 때문에 운영적으로는 나쁜 선택일 수 있습니다.
그래서 concurrency 조정은 memory와 dependency 동작과 함께 봐야 합니다.
실전 점검 순서
1. 설정된 concurrency와 실제 active task progress를 비교하세요
가장 먼저 “동시에 몇 개가 진짜로 전진하고 있는가”를 봐야 합니다. 종이 위에 slot이 16개여도 실제로 몇 개만 계속 진전된다면 병목은 다른 곳에 있습니다.
2. task duration과 blocking call을 측정하세요
특히 아래를 확인합니다.
- 긴 database wait
- 느린 external API
- 큰 CPU-heavy section
- task가 다른 시스템을 기다리는 구간
Celery concurrency 문제는 결국 task shape에서 시작되는 경우가 많습니다.
3. pool type과 prefetch를 같이 검토하세요
prefetch를 보지 않고 pool setting만 바꾸면 착시 같은 개선이나 더 나쁜 분배가 생길 수 있습니다.
아래 같은 baseline은 예약 분배가 문제인지 확인하는 데 도움이 됩니다.
celery -A app worker --loglevel=info --concurrency=4 --prefetch-multiplier=1
4. queue backlog와 worker utilization을 같이 보세요
backlog는 큰데 worker가 충분히 생산적이지 않다면, 단순히 worker 수 부족이 아니라 completion을 늦추는 다른 병목이 있다는 뜻입니다.
5. bottleneck이 보인 뒤에만 scale 하세요
task가 독립적이고 downstream이 충분히 버틴다면 worker 증설이 도움이 됩니다. 반대로 contention이나 memory cost만 키운다면 scaling은 오히려 악화 요인입니다.
패턴을 찾은 뒤 어떻게 바꿀지
task가 너무 느리거나 blocking이 큰 경우
task scope를 줄이고, heavy task를 분리하고, task body에서 불필요한 blocking을 줄이세요.
pool type이 workload와 맞지 않는 경우
기본값이 아니라 실제 workload shape에 맞는 pool model을 선택해야 합니다.
prefetch가 분배를 왜곡하는 경우
prefetch를 낮추거나 reservation 동작을 조정해 worker 하나가 너무 많은 작업을 선점하지 않게 해야 합니다.
worker를 늘릴수록 memory cost가 너무 커지는 경우
더 늘리기 전에 Python worker memory duplication을 같이 보세요.
빠른 체크리스트
Celery concurrency가 낮아 보일 때는 아래 순서가 가장 실용적입니다.
- 설정된 concurrency와 실제 active progress를 비교한다
- task duration과 blocking dependency를 확인한다
- pool type과 prefetch를 같이 검토한다
- queue backlog와 worker utilization을 본다
- bottleneck을 이해한 뒤에만 scale 한다
FAQ
Q. worker 수를 늘리면 가장 빨리 해결되나요?
그럴 때도 있지만, task가 block되거나 분배가 나쁘면 그렇지 않습니다.
Q. 가장 빠른 첫 단계는 무엇인가요?
queue backlog, active worker progress, task duration을 동시에 보는 것입니다.
Q. worker가 많은데도 queue가 긴 이유는 뭔가요?
worker가 block되었거나, task를 선점만 하고 있거나, 같은 downstream system을 기다리고 있기 때문일 수 있습니다.
Q. concurrency를 올리자 memory가 더 나빠진 이유는 뭔가요?
worker 수 증가가 process memory duplication과 dependency pressure를 함께 키웠기 때문일 수 있습니다.
Read Next
- 한 프로세스가 막힌 문제라면 Python asyncio event loop blocked를 보세요.
- task 실행이 memory cost를 크게 키운다면 Python worker memory duplication을 확인하세요.
- 더 넓은 흐름은 Python troubleshooting guide에서 볼 수 있습니다.
Related Posts
- Python worker memory duplication
- Python asyncio event loop blocked
- Python Celery tasks stuck
- Python troubleshooting guide
Sources:
- https://docs.celeryq.dev/en/stable/userguide/workers.html
- https://docs.celeryq.dev/en/stable/userguide/optimizing.html
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.
먼저 읽어볼 가이드
검색 유입이 많은 핵심 글부터 이어서 보세요.
- 미들웨어 트러블슈팅 가이드: Redis vs RabbitMQ vs Kafka 개발자를 위한 미들웨어 트러블슈팅 허브 글입니다. Redis, RabbitMQ, Kafka 중 어떤 증상부터 먼저 봐야 하는지와 어떤 문제 패턴이 각 시스템에 가까운지 정리합니다.
- Kubernetes CrashLoopBackOff: 먼저 볼 것들 startup failure, probe, config, resource limit 관점에서 CrashLoopBackOff를 어떻게 나눠서 봐야 하는지 정리한 가이드입니다.
- Kafka consumer lag가 계속 늘 때: 트러블슈팅 가이드 Kafka consumer lag가 계속 늘어날 때 무엇부터 봐야 하는지 정리합니다. poll 주기, 처리 속도, rebalance, consumer 설정까지 실전 기준으로 다룹니다.
- Kafka Rebalancing Too Often 가이드 Kafka consumer group에서 rebalance가 너무 자주 일어날 때 membership flapping, poll timing, protocol, assignment churn을 어떤 순서로 봐야 하는지 설명하는 실전 가이드입니다.
- Docker container가 계속 재시작될 때: 먼저 확인할 것들 exit code, command failure, environment mistake, health check 관점에서 Docker restart loop를 푸는 실전 가이드입니다.
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.