2006년 11월 8일

30바이트 전송하는데 1분이나 걸릴까?

TCP를 통해 작은 데이타 패킷을 보내야 하는 어플리케이션을 제작하려고 할 때, 발생할수있는 치명적인(?) 성능저하에 대해 이야기 해보자.

M$의 윈속을 사용할경우를 살펴보도록 하자.

윈속에서는 세그먼트를 수신하게 되면, 곧바로 응답을 주지 않고 일정시간(200ms이며 레지스트리값으로 변경가능)동안 보낼것이 없는지 대기하다가 ACK 세그먼트로 응답한다. 왜 그럴까?

바로 응답(delayed ACK)을 지연시켜 보내주기 위해서다.
지연된 응답이라는 것은 잘 받았다는 세그먼트를 곧바로 보내지 말고(TCP 헤더 플래그의 1비트를 SET한 세그먼트를 보내것), 좀(200ms 동안) 기다렸다가 내가 보낼 데이타가 생겼을때 ACK 임을 SET하여 같이 보내(이를 piggybacked ACK라 한다), 결국 세그먼트 두개가 아닌 한개로 응답과 전송을 모두 하려는 것이다.
효율적이지 않은가?

그러나 문제점은 바로 해당 어플리케이션이 작은 데이타를 보내고 응답을 받은후(ACK 세그먼트)에 다시 작은 데이타를 보내는 일을 수행하도록 디자인 되었다는데 있다.
응답이 200ms 정도 걸린다는 말은, 보내는 송신측에서 다음 데이타를 보내는데 최소 200ms 동안 대기되어야 함을 의미한다.
결국 1초동안 5번정도밖에 전송을 하지 못함을 의미한다.

자 계산해 보자. 해당 어플리케이션이 100바이트를 보내도록 디자인 되었다면, 아무리 빨라봐야 1초동안 500바이트를 전송한다는 것이다.

500bytes/sec 라니... 당장 시말서를 써야할지도 모른다.

자 정리를 해보도록 하자.

윈속의 경우 세그먼트를 수신하게 되면 곧바로 200ms 짜리 타이머가 가동된다.
상대방으로 전송할 세그먼트가 없으면 200ms 타이머가 만료된후 ACK세그먼트로 응답된다.
200ms 내에 상대방으로 전송할 세그먼트가 있으면 곧바로 ACK를 SET하고 응답 세그먼트를 보낸다. (piggy backed)

결국 이 delayed ACK란 것이 네트웍크에서 자잘한 세그먼트들이 넘치지 못하게 하는 일종의 SWS(Silly Window Syndrome) 현상을 예방하기위한 한 종류임을 알수 있다. 우리는 이미 Nagle 알고리즘역시 이와 비슷한 역할을 한다는 사실도 알고있다.

차이점은 Nagle 알고리즘은 송신측에서 적용되고, delayed ACK는 수신측에서 적용된다는 것이다.

게다가 소켓을 생성할때 Nagle 옵션(TCP_NODELAY)이 On 되었다면 상황은 더욱 악화된다. 왜냐하면, Nagle 알고리즘은 전송을 지연하는것이 목적이기 때문이다.

물론 송신할 데이터가 MTU 를 초과할경우, 잘받았다는 응답(ACK)이 없어도 해당 세그먼트를 즉시 송신하기는 하지만, 우리가 보내는 데이타는 MTU 크기를 훨씬 밑도는 100바이트가 아니던가...!!

결국 송신 데이타도 지연되고 수신데이타도 지연되는 이 같은 상황에서 우리가 디자인한 어플리케이션이 원하는 성능을 내줄거라는 희망은 사라지는 셈이다.

자 그럼 해당 어플리케이션이 왜 이런식으로 동작하는지 분석해 보도록 하자.

1. 네트웍 혼잡보다 처리 시간이 더 중요한 (time critical) 어플리케이션이라면 송신측에서 지연을 유발하는 Nagle 알고리즘의 사용을 자제해야한다.

2. 만약 1번 처럼 Nagle 알고리즘을 껏다면, 송신측은 MTU보다 작은 크기일 지라도 즉시 첫번째 세그먼트를 보내고, 두번째 세그먼트도 곧바로 전송하게 될것이다.

3. 수신측은 첫번째 세그먼트를 받은후 200ms 타이머를 가동시켜 delayed ACK를 시도하겠지만, 두번째 세그먼트가 곧바로 오기때문에 해당 타이머는 리셋(reset)되고 곧바로 응답 ACK 세그먼트를 보내주게 된다.

참고) MSDN: Design issues - Sending small data segments over TCP with Winsock
링크) http://support.microsoft.com/default.aspx?scid=kb;en-us;214397

댓글 2개:

  1. 트랙백을 남기는 법을 찾지 못해서 댓글로 남깁니다. 잘 참고하였습니다. 감사합니다.

    http://elenoa.tistory.com/109

    답글삭제
  2. 안녕하세요 혹시 이 질문의 답을 아실거같아 댓글로 여쭙니다

    마이크로소프트 문서 KB328890 을 보면 Delayed ACK를 해제할 수 있는 레지스트리 키가 있습니다

    적용범위는 Windows XP까지라고 되어있는데, Windows 7,8,10도 적용은 되더군요

    하지만 적용은되나 똑같진않습니다 200ms의 지연시간이 없어지는것이아니라 그냥 줄여주는정도인 느낌입니다 즉, Windows XP를 제외한 OS에서는 간헐적인 지연이 생기는데 혹시 답을알고계신가요?ㅠㅠ

    답글삭제

시리우스 라이브러리 홈페이지 오픈

현재 시리우스(Sirius) 라이브러리라는 제품을 개발하고 이를 소개하는 홈페이지를 오픈 하였습니다. 관심있는 분들의 많은 방문 요청드립니다. 앞으로 업데이트 소식및 변경사항은 스파이럴랩 홈페이지를 통해 진행할 예정입니다. 스파이럴랩 홈페이지 :  h...