흐름 제어 — TCP 의 슬라이딩 윈도우
수신 측은 ACK 마다 「앞으로 몇 바이트 받을 수 있는가」를 광고하고, 송신 측은 ACK 대기 바이트 수를 그 범위 안에 담는다. 이 창의 미끄러짐이 스루풋의 상한을 정한다.
빠른 송신 측은 느린 수신 측을 익사시킨다
재전송 구조가 갖춰져도 아직 약속은 완성되지 않습니다. 송신 측 서버가 고성능이고, 수신 측이 비력한 모바일 단말이라면? 도착한 데이터는 일단 수신 측의 수신 버퍼에 놓여, 앱이 recv() 로 읽어내기를 기다립니다. 앱의 읽기가 송신 페이스를 따라잡지 못하면 버퍼는 넘치고, 모처럼 도착한 데이터를 버리고 재전송을 받는 처지가 됩니다. 이래서는 본말전도입니다.
그래서 TCP 는 약속 그 3 의 전반, 흐름 제어를 넣습니다. 구조는 제 3 장의 ACK 에의 합승입니다. 수신 측은 ACK 를 돌려줄 때마다 「확인한 위치에서 앞으로 이만큼이라면 받을 수 있다」는 빈 용량 — 윈도우(rwnd) — 를 함께 신고합니다. 송신 측은 송신 완료이면서 아직 ACK 가 돌아오지 않은 바이트 수(in-flight)가 이 범위를 넘지 않는 한도 내에서만 보내 나아갑니다.
확인 완료의 끝(ack = 20001)에서 윈도우 5000 바이트 분량이 「보내도 좋은 범위」. ACK 가 나아가면 창째로 오른쪽으로 미끄러지므로, 슬라이딩(미끄러지는) 윈도우라고 부릅니다.
바이트열을 4 가지 색으로 칠해 나눈다
송신 측에서 보면, 바이트의 나열은 언제나 4 개의 구간으로 칠해 나눌 수 있습니다. ack = 20001, 윈도우 5000, 바이트 23000 까지 송신 완료, 라는 예로 살펴봅시다.
윈도우가 0 으로 광고되는 일도 있습니다(제로 윈도우). 수신 앱이 버퍼를 읽어내지 않고 있는 상태로, 송신 측은 송신을 멈추고 윈도우 프로브라는 작은 문의로 가끔 상황을 물으면서 기다립니다. 캡처에 제로 윈도우가 줄지어 있다면, 의심할 것은 네트워크가 아니라 수신 측 앱의 처리 정체입니다.
소문제 4-1 — 윈도우의 끝을 손으로 계산한다
「어디까지 보내도 좋은가」의 경계선을 바이트의 번호로 정확히 그을 수 있게 합니다.
Q1. 수신 측이 ACK 에 실어 광고하는 윈도우(rwnd)의 값이 나타내는 것은 어느 것입니까.
rwnd 는 수신 버퍼의 빈 용량입니다. 수신 측은 「도착했지만 앱이 아직 읽지 않은 데이터」를 버퍼에 안고 있으며, 그 남은 용량을 매번의 ACK 로 신고합니다. 송신 측은 ACK 대기(in-flight)의 바이트 수가 이 범위를 넘지 않도록 보냅니다. 대역폭이나 경로의 혼잡은 rwnd 에는 나타나지 않습니다 — 그쪽의 사정을 다루는 것이 제 5 장의 혼잡 제어입니다.
Q2. 송신 측은 ack = 20001(20000 까지 확인 완료), 광고 윈도우 5000 바이트의 ACK 를 받았습니다. 이미 바이트 23000 까지 송신 완료했습니다. 지금 추가로 보내도 좋은 것은 몇 바이트입니까.
보내도 좋은 오른쪽 끝은 「확인 완료의 끝 + 윈도우」= 20000 + 5000 = 25000 입니다. 23000 까지 송신 완료이므로, in-flight 는 20001〜23000 의 3000 바이트. 남은 범위는 25000 − 23000 = 2000 바이트입니다. ACK 가 나아갈(왼쪽 끝이 오른쪽으로 움직일) 때마다 오른쪽 끝도 미끄러져 전진한다 — 이 움직임이 슬라이딩 윈도우라는 이름의 유래입니다.
Q3. 수신 측이 윈도우 0 을 광고해 왔습니다(제로 윈도우). 송신 측의 올바른 행동은 어느 것입니까.
제로 윈도우는 「수신 버퍼가 가득 참 — 앱이 데이터를 읽어낼 때까지 1 바이트도 받을 수 없다」는 신고이므로, 송신 측은 기다리는 것이 정답입니다. 다만 말없이 기다리기만 하면 「윈도우가 열렸다」는 통지가 소실되었을 때 영원한 대기가 되므로, 윈도우 프로브로 정기적으로 상황을 물어봅니다. 장애 조사에서는, 제로 윈도우의 주범은 네트워크가 아니라 수신 측 앱의 읽기 느림이라는 점이 급소입니다(제 7 장).
창의 크기가 속도의 상한을 정한다 — 윈도우 ÷ RTT
흐름 제어에는 중요한 부작용이 있습니다. 송신 측은 ACK 대기의 양을 윈도우 이하로 유지하므로, 1 RTT 동안 보낼 수 있는 것은 최대라도 윈도우 1 잔 분량입니다. 즉, 아무리 대역폭이 굵어도
스루풋 상한 = 윈도우 ÷ RTT
를 넘을 수 없습니다. 윈도우 100 KB·RTT 100 밀리초라면, 100,000 바이트 ÷ 0.1 초 = 1 MB/초가 천장입니다. 회선을 빈틈없이 다 쓰려면 대역폭 × RTT(대역폭 지연 곱, BDP) 이상의 윈도우가 필요해집니다. 「가까운 서버에서는 빠른데, 해외 서버에서만 느리다」의 대부분은 이 식으로 설명할 수 있습니다.
시뮬레이터의 동작 개요(텍스트판): RTT·윈도우·대역폭의 3 개 슬라이더를 움직이면, 1 RTT 에 보낼 수 있는 양(= 윈도우), 윈도우 ÷ RTT 로 정해지는 스루풋 상한, 대역폭 × RTT(BDP), 실효 스루풋(윈도우 제약과 대역폭 제약 중 작은 쪽)이 수치로 갱신됩니다. 아울러, 경로라는 파이프에 in-flight 세그먼트가 어느 정도 차 있는가(충전율과 비행 중 세그먼트 수의 기준)가 가로 막대로 표시되고, 지금의 상한을 정하고 있는 것이 윈도우인지 대역폭인지가 문장으로 표시됩니다.
시뮬레이터로 시험해 봤으면 하는 3 가지 실험
- RTT 만 10 배로 한다 — 윈도우와 대역폭은 그대로. 상한이 10 분의 1 로 떨어지고, 파이프가 텅텅 비는 것을 확인해 주세요.
- 윈도우를 BDP 에 맞춘다 — 충전율이 딱 100% 가 되어, 제약이 「윈도우」에서 「대역폭」으로 바뀌는 경계를 찾아 주세요. 소문제 4-2 의 제 3 문의 답과 같은 값이 될 것입니다.
- 윈도우를 BDP 보다 크게 한다 — 상한은 더 이상 늘지 않습니다. 창을 넓혀도 파이프보다 굵게는 흐르지 않는 것을 확인해 주세요.
소문제 4-2 — 윈도우와 RTT 가 스루풋을 정한다
시뮬레이터의 계산식을 자신의 손으로도 확인합니다. 1 MB = 100 만 바이트로 합니다.
Q4. 윈도우 100 KB(100,000 바이트), RTT 100 밀리초의 커넥션에서 낼 수 있는 스루풋의 상한은 몇 MB/초입니까. (1 MB = 100 만 바이트)
송신 측은 ACK 가 돌아올 때까지 최대라도 윈도우 분량(100,000 바이트)밖에 보낼 수 없고, ACK 가 돌아오는 것은 1 RTT(0.1 초) 후입니다. 즉 1 RTT 당 최대 윈도우 1 잔으로, 100,000 바이트 ÷ 0.1 초 = 1,000,000 바이트/초 = 1 MB/초. 스루풋 상한 = 윈도우 ÷ RTT — 이 강좌에서 실무에 가장 많이 쓰는 식입니다.
Q5. 대역폭 1 Gbps 의 고속 회선인데도, 원거리(RTT 가 큰)의 전송만 느리다, 는 일이 일어납니다. 이유로 올바른 것은 어느 것입니까.
윈도우 1 잔을 보내고는 ACK 를 1 왕복 기다리는, 그 반복이므로 상한은 윈도우 ÷ RTT. RTT 5 밀리초라면 충분해도, 같은 윈도우로 RTT 150 밀리초라면 상한은 30 분의 1 이 됩니다. 회선이 아무리 굵어도 창이 작으면 물은 흐르지 않습니다. 대책은 윈도우를 크게 하는 것(근래의 OS 는 윈도우 스케일링으로 자동 조정합니다)이며, 프로토콜이 전환되거나 하지는 않습니다.
Q6. 대역폭 10 MB/초·RTT 100 밀리초의 경로를 빈틈없이 다 쓰려면, 최소 몇 MB 의 윈도우가 필요합니까. (대역폭 × RTT 를 계산한다. 1 MB = 100 만 바이트)
경로를 채우는 데 필요한 in-flight 양은 대역폭 × RTT(대역폭 지연 곱, BDP)입니다. 10,000,000 바이트/초 × 0.1 초 = 1,000,000 바이트 = 1 MB. 윈도우가 BDP 이상이면 대역폭이 상한이 되고, BDP 미만이면 윈도우 ÷ RTT 가 상한이 됩니다. 시뮬레이터에서 「윈도우 제약」과 「대역폭 제약」의 경계가 바로 이 값이 되는 것을 확인해 주세요.
이 장에서 가져갈 것
- 흐름 제어는 수신 측의 사정에 맞추는 구조. rwnd 는 수신 버퍼의 빈 공간의 신고
- 보내도 좋은 오른쪽 끝 = 확인 완료의 끝 + 윈도우. in-flight 가 윈도우를 넘지 않도록 보낸다
- 스루풋 상한 = 윈도우 ÷ RTT. 다 쓰려면 윈도우 ≥ 대역폭 × RTT(BDP)
- 제로 윈도우의 주범은 수신 측 앱의 읽기 정체. 네트워크를 의심하기 전에 앱을 본다
다만, 상대의 사정에 맞추는 것만으로는 아직 부족합니다. 다음 장은 약속 그 3 의 후반 — 도중의 네트워크의 사정에 맞추는 혼잡 제어입니다. 또 하나의 창 cwnd 가 등장합니다.