큐 길이
큐 길이는 큐에서 차례를 기다리는 일이 몇 건인지 세는 값입니다. 들어오는 일이 처리되는 일보다 많으면 이 값이 커집니다. 그래서 서비스가 밀리기 시작했는지를 일찍 알려 주는 지표로 봅니다.
쉽고 빠른 이해
무슨 일을 하는 값인가 — 줄에 선 일이 몇 건인지 알려 줍니다. 메일 발송 일감이 300건 쌓여 있으면 그 큐의 길이는 300 입니다.
왜 재나 — 처리가 들어오는 속도를 못 따라가면 이 값이 먼저 오릅니다. 사용자가 느려졌다고 느끼기 전에 밀림을 알아챌 수 있습니다.
어떻게 도나
- 일이 들어와 줄 끝에 붙으면 길이가 하나 늡니다
- 일을 꺼내 처리를 시작하면 길이가 하나 줄어듭니다
- 들어오는 쪽이 꾸준히 빠르면 길이가 계속 늘어납니다
대가 — 줄을 길게 허용하면 일을 버리지 않는 대신 기다리는 시간과 메모리가 늘어납니다. 짧게 막으면 기다림은 짧아지지만 넘친 일을 거절해야 합니다.
상세
이 절은 큐 길이가 무엇을 세는지, 왜 늘고 줄어드는지부터 봅니다. 사용률과 얽히는 모양은 표 하나로 보입니다. 이어서 이 값을 기다리는 시간으로 바꿔 읽는 법과 이 값만으로는 안 보이는 것을 짚습니다. 끝으로 맨 앞 한 건이 줄을 막는 경우, 상한을 두는 까닭, 큐 길이를 재는 곳을 봅니다.
줄에 선 건수
은행에 들어가면 벽에 「대기 인원 7명」이 떠 있습니다. 창구에서 상담 중인 손님은 이 숫자에 들지 않습니다. 번호표를 뽑고 의자에 앉아 부르기를 기다리는 사람만 셉니다.
큐 길이는 이 숫자를 프로그램의 큐에 대해 잰 값입니다. 큐에 들어왔지만 아직 처리를 시작하지 않은 항목이 몇 개인지 셉니다. 백그라운드에서 일감을 처리하는 작업 큐에 이미지 변환 일감이 50건 대기 중이면 큐 길이는 50 입니다.
큐는 일을 받는 쪽이 한꺼번에 다 처리하지 못할 때 생깁니다. 일을 꺼내 처리하는 쪽을 워커라고 부릅니다. 워커가 바쁜 동안 새로 온 일은 큐에서 차례를 기다립니다.
세는 범위 두 가지
큐 길이를 말할 때 세는 범위가 둘로 갈립니다. 하나는 기다리는 일만 세는 것입니다. 다른 하나는 워커가 지금 처리하고 있는 일까지 더해 세는 것입니다.
둘째 범위는 줄과 워커를 합친 전체를 봅니다. 이 전체를 흔히 「시스템」이라고 부릅니다. 그래서 둘째 값은 시스템 안에 든 일의 건수입니다.
대시보드나 문서에서 「큐 길이」를 만나면 어느 쪽인지 확인합니다. 워커가 열 개인 시스템이라면 두 값은 최대 열 건까지 차이가 납니다. 이 편은 따로 밝히지 않으면 기다리는 일만 센 값을 가리킵니다.
들어오는 속도와 나가는 속도
큐 길이는 두 속도의 차이로 움직입니다. 들어오는 쪽의 속도는 단위 시간에 들어오는 일의 수로 잽니다. 이 값이 도착률입니다.
나가는 쪽의 속도는 워커가 단위 시간에 끝낼 수 있는 일의 수입니다. 이 값이 서비스율입니다. 이 편에서 서비스율은 워커 전체가 끝내는 양을 말합니다. 워커가 여럿이면 각 워커가 끝내는 양을 모두 더합니다.
도착률이 서비스율보다 크면 차이만큼 쌓입니다. 초당 100건이 들어올 때 초당 80건을 끝낸다면 1초마다 20건이 남습니다. 1분이면 1200건이 쌓입니다. 들어오는 양이 안 줄면 줄은 끝없이 길어집니다.
도착률이 서비스율보다 작아도 큐 길이가 0 에 머물지는 않습니다. 일은 고른 간격으로 오지 않고 몇 건씩 몰려 옵니다. 몰린 순간에는 잠깐 줄이 생깁니다. 워커에게 여유가 생기면 그 줄이 빠집니다.
사용률이 오를 때
워커가 얼마나 바쁜지를 나타내는 값이 사용률입니다. 도착률을 서비스율로 나눈 값입니다. 초당 80건이 들어오는 큐를 워커가 초당 100건까지 끝낼 수 있으면 사용률은 0.8 입니다.
사용률은 1 을 넘을 수도 있습니다. 앞 절처럼 초당 100건이 들어와 80건을 끝내는 경우가 1.25 입니다. 1 을 넘으면 줄은 끝없이 자랍니다. 이 절은 사용률이 1 아래일 때를 봅니다.
사용률이 1 보다 작아도 큐 길이는 사용률을 따라 급하게 불어납니다. 몰려 온 일을 빼 줄 빈 시간이 점점 모자라지기 때문입니다.
이 모양은 큐잉 이론으로 셈해 볼 수 있습니다. 큐잉 이론은 일이 줄을 서고 처리되는 모습을 수식으로 다루는 분야입니다. 이 분야 덕분에 줄이 얼마나 길어질지를 겪기 전에 가늠할 수 있습니다.
가장 단순한 모형을 보겠습니다. 이 모형에서 워커는 하나입니다. 일은 서로 상관없이 도착합니다. 한 건을 처리하는 시간도 들쭉날쭉합니다.
사용률을 기호 ρ(로)라고 적으면, 이 모형에서 기다리는 일의 평균 건수는 ρ²/(1−ρ) 입니다. 분모의 1−ρ 가 0 에 가까워질수록 값이 커집니다. 사용률마다 셈하면 아래와 같습니다.
| 사용률 | 기다리는 일의 평균 건수 |
|---|---|
| 0.5 | 0.5 |
| 0.7 | 약 1.6 |
| 0.8 | 3.2 |
| 0.9 | 8.1 |
| 0.95 | 약 18 |
| 0.99 | 약 98 |
표에서 볼 것은 아래로 갈수록 벌어지는 간격입니다. 0.5 에서 0.8 로 가는 동안 줄은 2.7건 늡니다. 0.9 에서 0.99 로 가면 90건 가까이 늡니다. 사용률이 1 에 가까운 워커 앞에서는 일이 조금만 몰려도 큐 길이가 크게 튑니다.
기다리는 시간으로 바꿔 읽기
큐 길이는 건수입니다. 사용자가 겪는 것은 기다린 시간, 곧 대기 시간입니다. 둘을 잇는 셈이 있으면 대시보드의 건수를 사용자의 기다림으로 바꿔 읽을 수 있습니다.
리틀의 법칙이 그 셈을 줍니다. 평균 큐 길이는 도착률에 평균 대기 시간을 곱한 값과 같습니다. 큐에 평균 600건이 있고 초당 200건이 들어온다면 한 건은 평균 3초를 기다립니다.
이 셈은 재는 동안 줄이 계속 길어지지도 계속 짧아지지도 않을 때 맞습니다. 이런 상태를 정상 상태라고 부릅니다. 줄이 꾸준히 길어지는 중이면 평균을 말할 수 없습니다.
그럴 때는 지금 줄 끝에 선 일을 기준으로 가늠합니다. 먼저 들어온 것을 먼저 꺼내는 큐라면 이 일은 앞의 일이 다 빠질 때까지 기다립니다. 큐에 600건이 있고 워커가 초당 150건을 끝내면 줄 끝의 일은 4초쯤 기다립니다.
큐 길이가 가리는 것
큐 길이는 건수만 셉니다. 한 건이 얼마나 오래 걸리는지는 이 값에 안 나옵니다. 열 건만 기다려도 한 건에 1분씩 걸리면 줄 끝의 일은 10분을 기다립니다.
일이 큐에 들어온 뒤 지난 시간을 그 일의 나이라고 합니다. 그래서 큐 길이와 함께 가장 오래 기다린 일의 나이를 봅니다. 길이는 얼마나 밀렸는지를 알려 줍니다. 가장 오래 기다린 일의 나이는 사용자가 결과를 얼마나 늦게 받는지를 알려 줍니다.
큐 길이를 한 번씩 찍어 모으는 방식도 짧게 튄 순간을 가립니다. 1분마다 한 번 재면 그 사이에 몇 초 동안 줄이 길어졌다 빠진 일이 안 보입니다. 이 몇 초 사이에 들어온 일이 응답 시간 분포의 끝, 곧 꼬리 지연을 만듭니다.
맨 앞이 막힌 큐
큐 길이는 들어오는 쪽이 빨라서만 오르지 않습니다. 이 소절은 들어오는 양이 그대로인데도 줄이 길어지는 경우를 봅니다.
먼저 들어온 일부터 차례대로 끝내야 하는 큐가 있습니다. 이런 큐에서는 맨 앞의 일이 끝나야 다음 일을 꺼낼 수 있습니다. 워커가 맨 앞의 일을 붙잡고 실패와 재시도를 되풀이하면 뒤의 일은 하나도 꺼내지지 않습니다. 그사이 새로 온 일만 줄 끝에 붙어 큐 길이가 오릅니다.
이렇게 앞의 한 건이 뒤를 막는 현상이 헤드 오브 라인 블로킹입니다. 워커 사용률은 낮은데 큐 길이만 오른다면 이 현상을 먼저 의심합니다.
상한을 둔 큐와 없는 큐
큐 길이에 상한이 없으면 도착률이 서비스율을 넘는 동안 줄이 끝없이 자랍니다. 큐에 든 일마다 메모리를 차지하므로 결국 메모리가 바닥납니다. 그 전에 줄 끝의 일은 이미 쓸모없어질 만큼 오래 기다립니다.
상한을 두면 넘친 일을 어떻게 할지 정해야 합니다. 새 일을 거절할 수 있습니다. 넣는 쪽을 기다리게 할 수도 있습니다. 받는 쪽이 넣는 쪽의 속도를 늦추는 이 조절을 백프레셔라고 부릅니다.
flowchart TD
A["일이 들어온다"] --> B{"도착률이 서비스율보다 큰가"}
B -->|아니오| C["몰렸던 줄이 빠진다"]
B -->|예| D["큐 길이가 늘어난다"]
D --> E{"상한이 있나"}
E -->|없다| F["메모리가 바닥날 때까지 쌓인다"]
E -->|있다| G["넘친 일을 거절하거나 넣는 쪽을 기다리게 한다"]
그림은 두 번 갈립니다. 첫 갈림은 두 속도를 견줍니다. 둘째 갈림은 줄이 자랄 때 멈출 곳이 있는지를 봅니다. 상한은 일을 거절하거나 넣는 쪽을 늦추는 대가로 기다림과 메모리가 끝없이 불어나는 것을 막습니다.
상한 대신 워커를 늘려 대응하기도 합니다. 큐 길이가 정해 둔 값을 넘으면 워커를 더 띄우는 오토스케일링이 그렇습니다. 사용률보다 큐 길이를 기준으로 삼으면 밀린 일이 실제로 쌓였을 때 늘어납니다.
큐 길이를 재는 곳
백엔드에서 줄이 생기는 곳은 여럿입니다. 무엇이 줄을 서는지만 다릅니다. 세는 방식은 같습니다.
| 큐 | 무엇이 기다리나 |
|---|---|
| CPU(Central Processing Unit, 중앙 처리 장치)의 실행 큐 | 실행할 준비가 끝났지만 CPU 차례를 기다리는 스레드 |
| 디스크의 요청 큐 | 디스크에 보냈지만 아직 끝나지 않은 읽기·쓰기 요청 |
| 스레드 풀의 작업 큐 | 스레드가 비기를 기다리는 작업 |
| 커넥션 풀의 대기열 | 커넥션을 빌리려고 기다리는 스레드 |
| 메시지 큐 | 소비하는 쪽이 아직 가져가지 않은 메시지 |
어느 큐든 길이가 오르면 그 앞의 자원이 들어오는 일을 못 따라가고 있다는 뜻입니다. 여러 큐 가운데 가장 먼저 길어지는 큐가 병목을 가리킵니다.
관련 항목
큐 길이를 정하는 입력값
도착률 · 서비스율 · 서비스 시간 · 사용률 · 처리량
큐 길이를 다루는 이론
큐잉 이론 · 리틀의 법칙 · 켄달 표기법 · 정상 상태
큐 길이가 늘 때 함께 나빠지는 지표
대기 시간 · 체류 시간 · 응답 시간 · 지연 · 꼬리 지연
큐 길이와 나란히 보는 지표
포화 · 백분위수 · USE 방법 · 골든 시그널 · 컨슈머 랙 · 로드 애버리지
큐 길이를 늘리는 장애
병목 · 헤드 오브 라인 블로킹 · 과부하 · 재시도 폭풍 · 락 경합 · 기아
줄이 생기는 큐와 풀
큐 · 작업 큐 · 메시지 큐 · 실행 큐 · 스레드 풀 · 커넥션 풀
큐 길이를 조절하는 수단
백프레셔 · 유계 큐 · 부하 차단 · 스로틀링 · 오토스케일링 · 수평 확장 · 용량 계획
큐 길이가 속하는 상위 분류
다른 이름: queue length · queue depth · 큐 깊이 · 대기열 길이 · 대기 건수