순간이 영원해 지는 곳
TCP 세션 당 이론적인 max throughput 계산 본문
UDP 는 Flow Control 기능이 없기 때문에 보내는 쪽에서 전송 시작과 동시에 Physical Layer 에서 지원 가능한 최대 속도(max throughput)로 데이터를 전송할 수 있다.
반면 TCP의 경우 재전송 기능(ACK 패킷의 사용)과 Flow Control 기능(수신측에서 처리할 수 있는 속도이상으로 데이터를 보내지 않도록 조정) 때문에 전송 시작과 동시에 최대 속도로 데이터를 보낼 수 없으며, End to End 지연시간(delay)이 길면 1 session(1개의 TCP 연결)으로는 최대 속도로 데이터를 보내지 못할 수 있다.
전송 시작과 동시에 최대 속도로 데이터를 보낼 수 없는 것은, TCP가 window 라는 개념을 사용하기 때문이다. TCP는 ACK 패킷을 수신해야 그 다음 패킷을 전송할 수 있고, window의 크기는 ACK를 받기전에 보낼 수 있는 패킷의 수를 의미한다. 전송이 성공(timer 만료 전에 ACK 패킷 수신)해야 window의 크기가 늘어나며, 데이터 또는 ACK 패킷의 손실(timer 만료 후 ACK 패킷 도착 포함) 이 발생한 경우에는 window 의 크기가 줄어들기도 한다.
TCP 1 session 이 해당 링크(Physical layer)에서 지원하는 최대 속도를 낼 수 없는 것은 ACK 패킷을 수신해야 그 다음 데이터 패킷을 보낼 수 있는 절차 때문이다. window의 크기가 무한대라면 ACK 패킷을 받지 않고도 데이터를 지속적으로 보낼 수 있기 때문에 최대 속도를 낼 수 있지만, window의 크기가 한정적인 이상, 데이터를 보내고 ACK 패킷을 기다려야 하므로, 기다리는 시간 동안은 데이터를 전송하지 않게 된다.
결국 ACK 패킷을 기다리는 시간이 길면 길어질 수록 데이터를 보내는 속도도 느려지게 된다.
그래서 TCP 1 session Max throughput 은 패킷 하나가 End to End를 왕복하는데 걸리는 시간인 Round Trip Time(RTT)에 영향을 받는다. (편도 시간은 delay)
RTT 는 간단히 ping 테스트를 해보는 것으로 확인할 수 있다.
TCP 1 session Max throughput 에 영향을 주는 요소는 수신측의 buffer size 이다. 위에서 말한 것 처럼 TCP는 수신측에서 처리할 수 있는 속도 이상의 데이터를 전송하지 않으며, 수신측은 TCP 헤더의 Window Size 필드에 수신 Buffer 의 여유크기를 표시하여 송신측에 전달한다.(ACK 패킷을 이용)
< TCP Header Format >
0 1 2 3 |
수신 window 크기는 ACK 패킷을 받기 전에 연속해서 보낼 수 있는 데이터의 크기(송신 window 크기) 의 최대값으로 볼 수 있다. TCP 헤더의 window 필드는 16 bits 이며, 표현할 수 있는 가장 큰 숫자는 65,535 이다.
하지만 65Kbyte 가 표현 가능한 수신측 window의 최대 값은 아니다. TCP connection setup 과정에서 주고 받는 [SYN], [SYN,ACK], [ACK] 패킷 중에서 [SYN] 패킷의 Options 필드에 window scale 이라는 값이 들어가는 경우가 있다. 아래 Wireshark 로그에서 window scale 값은 2 이다. 2는 window 값을 왼쪽으로 2회 shift 연산을 수행하는 의미이며, 결과적으로 곱하기 4 를 한 것과 같다.
그 결과 아래 ACK 패킷에서 처럼 window size는 16,425 이지만 TCP Connection setup 시에 window scale 값을 적용하여 곱하기 4를 한 calculated window size 65,700 이 표시된다. – (wireshark 를 이용한 패킷 캡춰)
따라서 window scale 값이 있는 경우, 이를 고려하여 TCP 1 session 당 max throughput 을 계산해야 한다.
자, 이제 계산을 해보자!
* 참고 : http://en.wikipedia.org/wiki/TCP_window_scale_option
위의 링크 글에는 아래와 같은 예가 있다.
The TCP window scale option is needed for efficient transfer of data when the bandwidth-delay product is greater than 64K. For instance, if a T1 transmission line of 1.5Mbits/second was used over a satellite link with a 513 millisecond round trip time (RTT), the bandwidth-delay product is (1500000 * 0.513) = 769,500 bits or 96,188 bytes. Using a maximum buffer size of 64K only allows the buffer to be filled to (65535 / 96188) = 68% of the theoretical maximum speed of 1.5Mbits/second, or 1.02 Mbit/s. |
T1 회선(최대 속도 1.5Mbps)의 최대 성능을 이끌어 내는데 필요한 버퍼 크기를 알기 위한 내용이지만, TCP max throughput 을 계산하는 부분만 이해해보면 다음과 같다.
TCP max throughput 계산에 사용되는 파라미터는 세 가지이다.
1. Round Trip Time (RTT) : Ping 치면 나오는 밀리초(ms)로 보통 표시되는 시간이며, End to End 에서 패킷을 한번씩 주고 받는데 걸리는 시간을 의미한다.
2. 링크 속도 : 예를 들어 T1 회선의 이론적인 최대 전송 속도는 1.5Mbps 이다. Fast Ethernet 으로만 연결되어 있다면 100Mbps. 10MHz TM3 LTE 라면 Downlink 최대 속도는 약 73Mbps 정도. 물론 이는 단일 링크(1홉 떨어진)인 경우이고, 실제 우리가 집에서 사용하는 인터넷 환경이라면 집에서 인터넷 회사망까지의 링크속도와 거기서 TCP Server 까지의 링크속도가 다를 텐데(End to End 가 여러 홉 떨어진 경우) 가장 느린 링크의 속도를 사용한다. End to end 최대속도는 가장 느린 링크의 속도를 넘지 못할 것이므로.
3. 버퍼 사이즈 : 운영체제 마다 default TCP buffer size 는 달라질 것이나, scale 이 없는 경우는 최대 64Kbyte, scale이 있는 경우에는 TCP 연결설정 및 데이터 전송 후 최초 ACK 패킷 안에 window size 로 계산하면 된다. 응용 프로그램에서 TCP window 사이즈(socket buffer)를 변경한 경우에는 그 값을 사용한다.
Windows 에서 socket buffer 크기는 XP 포함 이전 버전은 8K, 이후 버전은 16K 정도라고 한다. google에서 WSAEWOULDBLOCK buffer size 로 검색~ |
Round Trip Time : 20ms, Link Speed : 100Mbps, Buffer Size : 65,535 bytes 인 경우
1. Link Speed 에 RTT를 곱한다. RTT는 데이터 패킷을 보내고 ACK를 받는데 걸리는 시간으로 이해할 수 있으며, 이렇게 계산한 값은 첫 ACK를 받기전(여기선 20ms)까지 보낼 수 있는 데이터의 양이다. 즉, 1초에 100Mbits를 보낼 수 있으므로 20ms 동안은 약 2 Mbits 를 전송할 수 있다.
100 Mbps X 20 ms = 104,857,600 bps X 0.02 s = 2,097,152 bits = 262,144 bytes
2. 버퍼크기를 위 결과값으로 나눈 비율을 구한다. TCP 프로토콜은 Sender 가 ACK를 받기전에 Receiver의 남은 버퍼크기 이상으로 보낼 수 없으므로, ACK를 받기전에 가장 많이 보낼 수 있는 데이터양은 버퍼크기이다. 이 계산 값은 ACK를 받기전에 Link Speed 기준으로 보낼 수 있는 데이터에 비해 실제 최대로 보낼 수 있는 데이터 크기의 비를 구하는 것이다.
65,535 bytes / 262,144 bytes = 0.24999 = 약 0.25 = 25%
3. Link Speed 에 비를 곱한다. Receiver 버퍼 크기가 항상 65,525 bytes 이고 패킷 loss가 없는 경우를 가정하였을 때 TCP 1 세션당 최대 속도는 25 Mbps 이다.
100 Mbps X 0.25 = 25 Mbps = 3.125 Mbytes/s
--> 결국, 이 경우 100 Mbps 라는 속도를 모두 사용하기 위해서는 TCP buffer 크기를 늘리거나(262,144 bytes 로 하는 경우 100% 속도를 이끌어 낼 수 있음) TCP 세션의 개수를 최소 4개로 늘려야 한다.
* TCP buffer tuning 에 관한 이야기 : http://onlamp.com/onlamp/2005/11/17/tcp_tuning.html
위 링크에 따르면 리눅스 커널 버전 2.6.7 이상은 TCP sender와 receiver 양쪽 버퍼 크기에 대한 autotuning을 지원한다고 하니 응용프로그래머 입장에서 한결 편할 듯 하다.
* 내가 자동으로 최대 속도로 데이터를 전송하는 프로그램을 만든다면?
서버와 클라이언트에서 RTT를 측정
링크속도는 100Mbps 로 가정. 또는 UDP 100Mbps 속도로 전송을 해보고 수신측에서 속도를 측정.
서버와 클라이언트에서 소켓의 send, recv buffer를 최대로 설정해 보고, 다시 get 해서 실제 얼마로 설정됐는지 확인.
둘 중 작은 버퍼의 크기를 기준으로 1세션당 max throghput 을 계산
100Mbps 또는 측정된 링크 속도를 1세션당 max throghput 으로 나눈 뒤, 소수점이면 올림한 수 만큼의 세션(소켓 및 스레드)으로 데이터를 전송
* 개인적인 궁금함과 추측 : TCP window 의 크기변화
TCP 윈도우 크기는 slow start 로 증가하고, threshold 를 넘어서면 congestion avoidance 구간에서 선형으로 증가하는데, 패킷 로스가 없다고 해도 무한으로 늘어나진 않을 것이다. 그래서 어느 순간에는 일정 크기를 유지할텐데 그때가 언제인지 TCP를 처음 배울때는 몰랐다. 웹에서 파일을 다운로드 받는 경우 속도를 살펴보면 속도가 증가하다가 어느정도 시간이 지나면 속도가 유지되는 것을 볼 수 있다. 지금 보니 그 일정크기는 수신측의 buffer size 가 되어야 옳다. 그래서 TCP 윈도우 크기의 그래프는 아래 그림과 같은 모양이 될 것이다.
그림 출처 : http://fengnet.com/book/CNF/ch02lev1sec3.html
※ 개인적인 참고용으로 작성한 글이며, 잘못된 내용이 있을 수 있습니다. 틀린 부분에 대해서 지적해 주시면 감사히 반영하도록 하겠습니다.
'통신 & 네트워크' 카테고리의 다른 글
LTE에서 IPv4, IPv6 주소 할당 방법 (0) | 2013.01.04 |
---|---|
TCP delayed ACK time (0) | 2013.01.04 |
RTP, RTCP, RTSP 정리 (4) | 2011.01.26 |
리눅스로 AP 만들기 (hostapd 설치) (8) | 2011.01.03 |
WFQ 동작 과정 (패킷 처리 예제) (5) | 2009.08.17 |