지연(Latency)이 만드는 서비스 안정성의 마법
'의도적인 지연' 전략
컴퓨터 사이언스 전공자나 소프트웨어 엔지니어들에게 지연(Latency)는 '안 좋은', '일어나지 않아야 할', '줄여야 하는' 것으로 인식됩니다. 서비스 처리 속도는 빠를수록 좋고, 응답 시간은 짧을수록 좋다는 것을 모르거나 부인하는 사람은 없을 것입니다.
하지만, 트래픽이 순간적으로 몰리는(폭증: Traffic Spike, Surge Traffic) 서비스에서는 역설적으로 '의도적인 지연'이 서비스 전체의 안정성을 높이는 전략이 될 수 있습니다. 이 마법같은 현상을 1) 안정적인 서비스와 2) 사용자 경험 측면에서 살펴보겠습니다.
트래픽 스파이크 시 동반되는 현상들
트래픽 스파이크란 갑작스럽게 네트워크나 웹사이트의 트래픽이 폭발적으로 증가하는 현상을 뜻합니다. 특히, 서비스를 제공하고 있는 시스템의 자원을 초과하는 방대한 양의 트래픽이 발생하는 경우에 다양한 이슈가 발생할 수 있습니다.
트래픽 스파이크와 서비스 시스템
트래픽이 급격히 증가할 때 컴퓨팅 관점에서 어떤 일들이 일어날 지, 아래와 같은 몇 가지 사례를 생각해볼 수 있습니다.
DB Connection Pool은 평소에 40개면 충분한 데 0.1초의 단시간 내에 200개가 쏟아지면 병목이 발생한다.
Redis는 초당 30,000QPS의 처리를 할 수 있지만 50ms에 5,000건의 요청이 몰리면 lock 경합이 폭증한다.
CPU 사용률이 30%로 안정적이어도, 20ms의 짧은 순간에 1,000개 스레드가 동시에 wake-up 하면 Run Queue가 폭증한다.
TCP 커널 큐가 평소에 비어있어도 수백 개의 소켓에서 동시에 ACK를 보내면 re-transmission과 RTT 증가가 생긴다.
이러한 일들이 벌어질 때, 대체로 대기 시간이 들쑥날쑥해지고, 응답 시간이 흔들리는 경우가 많습니다. 물론, 충분한 검증 과정이 있어야겠지만, 앞선 사례들의 다양한 병목 지점들을 볼 때 ‘시스템은 평균이 아니라 스파이크(Spike)에 의해 망가질 수 있다’고 생각해볼 수 있으며, 운영 측면에서 트래픽 스파이크에 대한 관리가 필요하다는 결론을 얻어내기에 충분합니다.
트래픽 스파이크와 사용자 경험
이번에는 사용자 경험 관점에서 일어나는 일들을 살펴보고자 합니다.
잠깐 퀴즈! 다음 두 서비스 중, 더 나은 사용자 경험을 제공하는 서비스 환경은 무엇일까요?
구분 | 평균 응답시간 | 응답시간 표준편차 |
|---|---|---|
A 서비스 | 120ms | 300ms |
B 서비스 | 230ms | 20ms |
A 서비스는 대체로 0.1초 정도의 빠른 응답 시간을, B 서비스는 그것의 약 2배에 해당하는 응답 시간을 보이고 있습니다. 그런데 실측된 응답시간의 표준 편차를 보면 A 서비스는 최대 400ms 정도의 응답 시간을 보일 수 있고, B 서비스는 늦어도 250ms 내에 응답을 받을 수 있는 것으로 파악됩니다.
서비스 이용자(End-User)의 사용성을 고려하는 APDEX*의 관점에서 볼 때, 위 예시에서처럼 2초 미만의 응답시간은 모두 양호한 것으로 판단할 수 있습니다. 하지만, 실제로 평균 응답시간이 초 단위에 형성되고 표준편차 역시 큰 값일때는 이러한 들쑥날쑥한 응답시간 분포는 사용자 경험에서 있어 치명적입니다.
*APEDX에서의 사용자 경험 판별식(w/응답시간)
: 2초 미만 GOOD / 8초 이상 FRUSTRATED / 그 외 TOLERANT
예컨대, '원래 2초 정도 걸리는 서비스인데 나는 3초 걸렸어'와 '원래 2초 걸리는데 나는 5초 혹은 10초 걸렸어'의 차이라고 볼 수 있습니다. 사용자 경험 측면에서는 가급적이면 평균 응답 시간 근처에게 개별 응답 시간이 분포할 수 있도록 서비스하는 것이 중요합니다.
(정답: B 서비스가 전체적으로 더 안정적이다.)
의도된 지연이 가져오는 마법
결국 서비스를 운영할 때 고려해야할 점들을 상기해보면, 시스템은 트래픽 스파이크가 일어나지 않도록 운영하는 것이 중요하며, 사용자 경험 측면에서도 고른 분포의 응답 시간을 가지는 서비스를 제공하는 것이 사용자 만족도를 높이는 데 효과적이라고 할 수 있습니다.
서두에 이야기한 '의도된 지연'은 트래픽 스파이크가 일어나지 않도록 시스템 자원을 활용할 수 있는 요인이고, 전체적인 평균 응답 시간은 살짝 증가할 수 있지만 대다수의 클라이언트에게 동일한 사용자 경험을 제공할 수 있는 방법입니다.
실제로, 의도된 지연이 가져오는 서비스 시스템에서의 효과는 다음과 같은 것이 있습니다.
커널 레벨에서의 Run Queue 폭증 억제와 Context Switching 강화
TCP 레이어에서의 RTT 안정화
로드 밸런서에서의 균일한 부하 분산 효과
DB와 캐시에서의 Lock 경합 감소
이러한 것들을 보았을 때, 지연은 서비스를 느리게 만드는 요인이면서도 어쩌면 안정화를 위한 필터의 역할도 하는 것이 아닐까 싶습니다.
안정성과 서비스 품질의 균형, 유의미한 지연
트래픽 제어 관점에서 초과된 트래픽을 아예 틀어막는 것(Rate Limiting 등)은 서비스 인프라에 부담을 주지 않기 위해 생각해볼 수 있는 방법입니다. 그러나 이러한 방식은 최적화의 관점에서 적절한 값을 찾는 것이 너무나도 어렵기 때문에 우리는 절충안을 모색해야 합니다. 그것은 바로 트래픽 제어를 통해 서비스 응답시간과 시스템 자원 사용량을 Trade-off 하는 것입니다.
기존의 Layer7 영역에서 사용되는 프록시 서버나 API GW의 트래픽 제어는 상당히 불친절하고, 너무나도 운영자 개인의 경험에 의존적인 문제가 있습니다. 운영 경험이 없으면 적절한 값을 설정하는 것이 어렵고, 경험이 있더라도 차세대 프로젝트 등으로 서비스가 개편되거나 비즈니스 로직이 변경되면 경험치를 활용하기 어렵다는 아쉬운 점이 있습니다.
에스티씨랩(STCLab)이 API 넷퍼넬(API NetFUNNEL)을 통해 제시하고자 하는 바는 뚜렷합니다!
우리는 다양한 도메인 환경에서의 트래픽 매니지먼트 경험을 통해, 서비스 관점에서 ‘유의미한 지연’이 있다는 것을 이미 알고 있습니다. 그리고, API 넷퍼넬이 제공하는 기능 역시 시스템의 안정성과 서비스 품질 사이에서 최적화된 형태로 균형을 지키며 작동하고 있다는 것을 다시 한번 강조합니다.