TCP 성능 관련 중요 요소

2021. 1. 29. 15:40

아래 내용은 HTTP 완벽 가이드 4장 내용을 일부 정리한 것.

1. TCP 커넥션의 헨드쉐이크 설정

크기가 작은 http 트랜잭션은 처리 시간의 50%이상이 TCP를 구성하는데 사용된다.
이를 TCP 구성으로 인한 지연 이라한다.

2. 인터넷의 혼잡을 제어하기 위한 TCP의 느린 시작(slow start)

TCP 커넥션이 만들어진 지 얼마나 지났는지에 따라 TCP의 데이터 전송 속도는 달라질 수 있다.

혼잡제어 알고리즘에 의해 TCP는 시간이 지남으로써 `튜닝` 되어 진다.

처음에는 커넥션의 최대 속도를 제한하고 데이터가 성공적으로 전송됨에 따라서 속도 제한을 높여나간다.

(한번에 전송할 데이터 량을 조절함으로써 속도를 제한하는 것)

이렇게 조율하는 것을 TCP slow start 라 한다.

패킷을 주고 받으면서 한번에 전송할 패킷이 늘어나는 것을 `혼잡 윈도우를 연다` 라고 한다.

혼잡제어 기능때문에 막 연결된 커넥션 보다 이미 어느 정도 데이터를 주고받은 `튜닝`된 커넥션이 더 빠르기 때문에 HTTP에서는 이미 존재하는 커넥션을 재사용하는 기능이 있다.

3. 데이터를 한데 모아 한 번에 전송하기 위한 네이글(Nagle) 알고리즘

TCP는 어플리케이션이 어떤 크기의 데이터든지 TCP스택으로 전송할 수 있도록 데이터 스트림 인터페이스를 제공한다. TCP 세그먼트는 40바이트 상당의 플래그와 헤더를 포함하여 전송되기 때문에, 작은 크기의 데이터를 포함한 많은 수의 패킷을 전송한다면 네트워크 성능은 크게 떨어진다.

네이글(Nagle) 알고리즘은 네트워크 효율을 위한 것으로, 패킷을 전송하기 전에 TCP 데이터를 모아서 한 개의 덩어리로 합친다. - RFC896, "Congestion Control in IP/TCP Internetworks"에 설명되어있다 한다.

(나중에 읽어봐야지)

네이글 알고리즘은 세그먼트가 최대 크기 (LAN상에서 1500바이트, 인터넷상에서는 수백 바이트)가 되지 않으면 전송을 하지 않는다. 다만 다른 모든 패킷이 확인 응답을 받았을 경우에는 최대 크기보다 작은 패킷의 전송을 하도록 되어있다. 다른 패킷들이 아직 전송 중이라면 버퍼에 저장된다.

네이클 알고리즘은 HTTP 성능 관련해 여러 문제를 발생시킨다.

1. 크기가 작은 HTTP 메시지는 패킷을 채우지 못하기 때문에, 앞으로 생길지 생기지 않을지 모르는 추가적인 데이터를 기다리며 지연된다.

2. 확인 응답 지연과 함께 쓰일 경우 매우 느리다. 네이글 알고리즘은 확인응답이 도착하기 할때까지 데이터 전송을 멈추고 있는 반면, 확인응답 지연 알고리즘은 확인응답을 100~200 미리초 지연시키기 때문이다.

HTTP 어플리케이션은 성능향상을 위해서 HTTP 스택에 TCP_NODELAY 파라미터 값을 설정하여 네이글 알고리즘을 비활성화하기도 한다. 다만 이설정을 하였다면 너무 작은 패킷이 너무 생기지 않도록 하여야 한다.

4. TCP의 편승(piggyback) 확인응답(acknowledgment)을 위한 확인 응답 지연 알고리즘

확인응답 패킷은 단순 목적의 패킷이며 크기가 매우 작기때문에 TCP는 같은 방향으로 송출되는 데이터 패킷에 확인응답을 `편승(piggyback)` 시켜 데이터 패킷과 확인응답 패킷을 묶음으로써 네트워크를 좀 더 효율적으로 사용하고자 한다. 확인응답 패킷을 같은 방향으로 가능 데이터 패킷에 더 많이 `편승` 시키기 위해서 확인응답 지연을 시킨다. 이는 확인응답 패킷을 보내야할 때 특정시간(0.1 ~ 0.2초) 버퍼에 저장해 두고, 편승시킬 데이터 패킷을 찾는다. 이 후 편승할 데이터 패킷을 시간내에 찾지못하면 그대로 패킷으로 만들어서 전송한다.

HTTP같은 경우에는 요청과 응답을 번갈아서 진행하기 때문에 확인 응답이 송출 데이터 패킷에 편승할 기회가 적다.

5. TIME_WAIT 지연과 포트 고갈

TCP 커넥션을 끊으면, 종단에서는 커넥션의 IP주소와 포트 번호를 메모리의 작은 제어영역(control block)에 기록한다. 이 정보는 일정 시간이 지나기전까지 새로운 커넥션이 맺어지는 것을 막는다. 보통 세그먼트의 최대 생명주기에 두 배 정도의 시간 동안만 유지한다. 실제로 이 알고리즘은 특정 커넥션이 닫힌 다음 2분 내에 또 생성되는 것을 막아준다.

만약 이전 커넥션의 패킷이 그 커넥션과 같은 연결 값으로 생성된 커넥션에 삽입 되면, 패킷은 중복되고 TCP 데이터는 충돌할 것이다. 

 

각각 한개의 클라이언트와 서버가 있고, TCP 커넥션을 맺기 위한 네 개의 값이 있다고 하자.

<클라이언트 IP, 발신지 PORT, 서버 IP, 서버 PORT> 

클라이언트에서 서버에 접속할 때마다 유일한 커넥션을 생성하기 위해서 새로운 발신지 포트를 쓴다. 하지만 사용할 수 있는 발신지 포트의 수는 약 60000개로 제한되어 있다. 커넥션이 2MSL초 동안 재사용될 수 없으므로 초당 500개 (60,000 / 120s = 500)로 커넥션이 제한된다. 서버가 초당 500개 이상의 트랜젝션을 처리할 만큼 빠르지 않다면 TIME_WAIT 포트 고갈은 일어나지 않는다. 이 문제를 해결하기 위해 부하를 생성하는 장비를 더 많이 사용하거나 클라이언트와 서버가 더 많은 커넥션을 맺을 수 있도록 가상 IP주소를 쓰는 방법도 있다.

 

포트 고갈 문제를 겪지 않더라도, 커넥션이 너무 많이 맺거나 대기 상태로 있는 제어 영역(control block)이 너무 커지면 극심하게 느려지는 OS도 있다.

'통신' 카테고리의 다른 글

RPC vs REST vs GraphQL  (0) 2021.09.23
구글 크롬의 HTTP통신 지속 커넥트, 병렬 커넥트  (0) 2021.09.05
HTTP 커넥션  (0) 2021.02.01
HTTP 1.1  (0) 2020.11.14
HTTP 1.0  (0) 2020.11.11

BELATED ARTICLES

more