큐와 비동기 API · 백프레셔와 처리량 · 실습
백프레셔와 처리량 다루기
목표
큐 깊이를 지연 시간으로 번역하는 법을 익히고, 상한과 부하 차단으로 시스템이 스스로를 지키게 만든 뒤, 동시성 조절로 처리율을 실제로 올린다.
왜 중요한가
큐를 넣은 시스템의 사고는 대부분 "큐가 쌓이는데 아무도 몰랐다"입니다. API 대시보드는 전부 초록색이고, 응답 시간도 정상이고, 사용자만 결과를 못 봅니다. 큐 깊이를 지연으로 번역하지 못하면 이 상황이 얼마나 심각한지 판단할 수 없습니다. 리틀의 법칙 W = L / λ 한 줄이면 됩니다 — 깊이 3,000, 처리율 초당 50건이면 지금 접수하는 사용자는 60초를 기다립니다. 그리고 이용률이 100% 에 가까워질수록 대기 시간이 선형이 아니라 폭발적으로 자란다는 사실을 그래프로 한 번 보면, 왜 워커 용량을 유입의 딱 100% 로 맞추면 안 되는지가 몸에 남습니다.
단계
1. /opt/app/loadgen.py 로 q:work 에 초당 200건씩 10초간 넣는다. LLEN q:work 가 1500 이상이어야 한다.
2. /root/qb/measure.sh 로 1초 간격 10회 큐 깊이를 재어 /root/qb/depth.csv 에 t,depth 헤더와 함께 11줄로 남긴다.
3. /root/qb/little.txt 에 L=<깊이> lambda=<초당 처리 건수> W=<초> 세 값을 적는다. W 는 L 을 lambda 로 나눈 값이며 소수 첫째 자리까지 맞아야 한다.
4. /root/qb/api.py 를 127.0.0.1:8142 에 띄운다. POST /enqueue 는 큐 길이가 1000 이상이면 429 를 준다. 그 미만이면 202 를 준다.
5. 429 응답에 Retry-After 헤더를 정수 초로 담는다. /root/qb/shed.out 에 status=429 retry_after=<정수> 를 적는다.
6. 같은 500건을 워커 1개와 4개로 각각 처리하고 /root/qb/concurrency.txt 에 workers=1 seconds=<값> 과 workers=4 seconds=<값> 두 줄을 적는다. 4개 쪽이 더 빨라야 한다.
7. /root/qb/report.md 에 ## 안정 조건, ## 목표 이용률, ## 상한 정책 세 제목을 넣고 각 절을 25자 이상 쓴다.
참고
- 안정 조건: λ < μ. 이용률 ρ = λ/μ 는 0.7~0.8 을 목표로 둡니다.
- 리틀의 법칙: L = λ x W, 뒤집으면 W = L / λ
- 큐 깊이 알림은 절대값보다 "5분간 계속 증가" 같은 추세가 신뢰할 만합니다.
- 흔한 실수: 워커만 늘려 놓고 그 뒤의 DB 가 새 병목이 된 것을 확인하지 않는 것.
단계 7개
- 부하를 넣어 큐 채우기
- 큐 깊이 시계열 기록하기
- 리틀의 법칙으로 대기 시간 추정하기
- 큐 상한과 429 붙이기
- Retry-After 로 재시도 시점 알려 주기
- 워커 동시성 올려 처리율 개선하기
- 안정 조건 정리하기