· 박준성 (CEO / Junsung Park) · Technology · 11 min read
통계가 아닌 구조로: 최악의 경우에도 지연 상한을 보장하는 법
지난 글에서는 체류 시간이 길어진 요청을 차단하는 '시간 상한 게이트'를 지연이 발생하는 최종 지점 뒤로 옮긴 과정을 다루었습니다. 이번 글에서는 이 게이트가 제공하는 '보장'이 과연 어떤 성격인지 이야기해 보려 합니다.

지난 글에서는 체류 시간이 길어진 요청을 차단하는 ‘시간 상한 게이트’를 지연이 발생하는 최종 지점 뒤로 옮긴 과정을 다루었습니다. 이번 글에서는 이 게이트가 제공하는 ‘보장’이 과연 어떤 성격인지 이야기해 보려 합니다.
p99와 최악 경우는 다른 약속이다
Latency를 논할 때 우리는 보통 분포를 이야기합니다. “p99가 몇 밀리초다”, “꼬리 지연이 어떻다” 하는 식입니다. 하지만 p99 지표가 훌륭하다는 것과 ‘최악의 경우를 통제한다’는 것은 완전히 다른 종류의 약속입니다. 전자는 시스템을 거쳐 간 요청들을 사후에 관찰하고 그린 히스토그램에 불과합니다. 반면 후자는 타임아웃이 임박한 요청이 아예 밖으로 나갈 수 없도록 시스템 구조적으로 사전 차단하는 것을 뜻합니다.
비더 입장에서 이 차이는 매우 큽니다. p99가 아무리 좋아도, 그 밖의 1%가 마감을 넘긴 입찰이라면 후속 머신러닝 파이프라인은 그 연산 결과를 통째로 버리게 됩니다. 우리가 후속 시스템에 약속해야 했던 것은 평균이 아니라 컷오프(최댓값)였습니다.
구조적 보장이란
정의는 단순합니다. “밖으로 나간 요청은 무조건 체류 시간이 상한선(T) 이하”라는 것입니다. 체류 시간이 T를 넘은 요청은 나갈 경로 자체가 없습니다. 폐기되거나, 상한선 이내로 나가거나 둘 중 하나일 뿐 그 중간은 없습니다.
이는 측정을 통해 확인되는 통계적 사실이 아니라, 게이트의 구조가 강제하는 명제입니다. 통계적 보장은 지표가 나빠진 뒤에야 경고를 보내주지만, 구조적 보장은 지표가 나빠질 경로를 애초에 원천 봉쇄합니다. 둘은 모니터링과 물리적 차단만큼이나 다릅니다.
이 명제가 성립하려면 게이트가 지연이 발생할 수 있는 ‘최종 지점’ 뒤에 있어야 합니다. 그 앞에 두면 게이트를 통과한 뒤에도 요청은 큐에서 더 대기할 수 있고, 우리가 세운 정의는 조용히 깨지게 됩니다. 지난 글에서 게이트를 세 번이나 옮긴 이유가 바로 이 때문이었습니다.
또한, 우리가 측정하는 것은 요청이 ‘우리 시스템 안’에 머문 시간입니다(도착부터 물리 송신까지). 들어오는 네트워크 구간, 나간 뒤의 네트워크 구간, 그리고 후속 시스템 자신의 연산 시간은 우리가 통제할 대상이 아니라 후속 시스템에 남겨진 예산입니다. 우리의 경계 안에서만큼은, 내보내는 요청의 체류 시간이 상한 이하임을 보장하는 것입니다.
경계와 실패 모드를 정직하게
구조적 보장의 진가는 경계 조건에서 시험받습니다. 우리는 두 가지 상황에서 명확한 원칙을 세워야 했습니다.
첫째, 체류 시간이 정확히 상한(T)과 같을 때. 이 경우는 통과시킵니다. T는 초과하면 안 되는 값이고, 정확히 T인 요청은 아직 선을 넘지 않았기 때문입니다.
둘째, 서버 간 시계가 어긋나(Clock Drift) 체류 시간 계산 자체가 불가능해질 때. 도착 시각과 현재 시각이 어긋나면 체류 시간이 음수로 나오는 등 비정상적인 값이 될 수 있습니다. 이때 저희는 요청을 통과시키는 대신 가차 없이 버리기로 했습니다. 체류 시간을 0으로 보정해서 통과시키는 대안도 있었으나 기각했습니다. 어긋남이 클 경우, 실제로는 만료된 요청을 신선한 요청으로 착각해 시스템의 보장을 조용히 깨뜨릴 위험이 컸기 때문입니다. 우리가 택한 원칙은 ‘Fail-Safe’입니다. 판단이 애매할 때는 과잉 차단을 할지언정, 보장을 위반하지는 않겠다는 것입니다. 보장을 내건 시스템에서 최악의 실패 모드는, 지연된 요청을 정상인 척 내보내면서 겉으로는 멀쩡해 보이는 것입니다. 그럴 바에는 차라리 애매한 것을 버리는 편이 낫습니다.
상한 T에는 보편 최적값이 없다
T를 얼마로 설정할지는 우리가 결정하지 않습니다. T는 후속 머신러닝 시스템이 tmax 예산 안에서 얼마나 시간을 쓸지에 따라 배포마다 달라집니다. 우리가 확신할 수 있는 것은 트레이드오프의 방향성뿐입니다. T를 낮게 잡으면 지연 상한은 엄격해지지만 더 많은 요청을 버리게 됩니다. 반대로 높이면 덜 버리는 대신 상한은 느슨해집니다. 이 트레이드오프의 규칙은 어디서나 동일하며, 곡선 위의 어느 점을 고를지는 해당 배포 환경의 후속 예산이 결정합니다. 구체적인 폐기율(Drop Rate)과 T 값은 트래픽과 환경에 종속된 수치이므로 이곳에 적지는 않겠습니다. 중요한 것은 환경마다 달라지는 특정 수치(좌표)가 아니라, 이 일관된 트레이드오프의 경향성(곡선의 모양) 자체입니다.1
마무리
이 보장이 실제로 유효한지는 두 번에 걸쳐 교차 검증했습니다. 한 번은 실제 파일럿 트래픽의 도착 타이밍을 게이트가 적용된 경로에 그대로 리플레이하여 검증했고, 또 한 번은 라이브 실행 환경에서 게이트가 실제로 읽어들인 체류 시간으로 확인했습니다. 양쪽 모두 밖으로 나간 요청의 체류 시간이 상한을 넘긴 경우(위반)는 0건이었습니다.2
한 줄로 요약하겠습니다. 보장은 측정으로 알아내는 것이 아니라 구조로 강제하는 것이며, 측정은 그 구조가 제대로 서 있음을 증명하는 도구일 뿐입니다.
우리는 실시간 입찰 인프라에서 꼬리 지연을 구조적으로 통제하는 저지연 트래픽 필터링 시스템을 만들고 있습니다.
이 게이트를 실제 서비스 트래픽에 영향 없이 테스트해 보고 싶다면, 트래픽 미러링 기반의 섀도 모드 파일럿으로 시작해 보실 수 있습니다.
Footnotes
상한선에 따른 폐기율은 파일럿 리플레이에서 실제로 측정했으나, 그 값은 해당 트래픽과 환경에 국한된 숫자입니다. 여기서 얻을 수 있는 유의미한 정보는 “T를 낮추면 더 버리고 높이면 덜 버린다”는 트레이드오프의 방향성이지 특정 좌표값이 아니므로 별도의 표로 싣지는 않았습니다. ↩
위반 0건은 두 가지 측정 방식을 통해 확인했습니다. 하나는 파일럿 타이밍 리플레이입니다. 실제 파일럿 트래픽의 기록된 타이밍에서 레코드별 체류 값을 복원한 뒤, 게이트가 적용된 송신 경로에 주입하여 송신 직전의 총 체류 시간이 상한을 넘는지 전수 조사했습니다. 이 체류 값은 송신기에서 수신기까지의 네트워크 구간을 포함한 End-to-End 측정값이므로, 시스템 내부의 체류 시간만 고려하면 이보다 더 여유가 있는 보수적인 기준입니다. 다른 하나는 베어메탈 라이브 경로 실행입니다. 게이트가 실제로 측정한 시스템 내부 체류 시간이 상한 이하임을 직접 확인했습니다. 양쪽 모두 위반은 0건이었으며, 절대적인 수치는 테스트 환경에 종속되므로 다른 환경에 단순 대입하여 예측할 수는 없습니다. ↩