※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)
드디어 네트워크의 마지막을 장식할 시간이 왔다. 그렇다고 큰 거는 아니고 스스로 계획해놨던 포스팅의 가장 마지막 포스팅까지 왔다는 것이다. TCP/IP를 전체적으로 다른 포스팅에 비해서 꽤나 자세하게 다뤄놓을 계획이었는데 그 마지막까지 온 것이다.
지난 번에 설명했듯이 이번 포스팅에서 설명할 이야기는 Congestion Control이다. Error Control, Flow Control에 이어 TCP의 중요 기능 중에 하나이다. Congestion Control이란 무엇을 뜻하는 말인가? 말 그대로 혼잡을 제어하는 것이다. TCP는 신뢰성를 기반으로 하기 때문에 그 신뢰성을 만족시키면서 최고의 속도를 내기 위해 Congestion Control을 하는 것이다.
TCP의 Congestion Control은 다음의 세 단계를 거친다.
Slow Start → Congestion Avoidance → Congestion Detection
마지막 Congestion Detection, 즉, Congestion을 탐지했으면 경우에 따라 Slow Start로 돌아갈 수도 있고 Congestion Avoidance로 돌아갈 수도 있다.
각 단계별로 설명을 하기 전에 Congestion Control에서 직접적으로 다룰 window라는 것을 이야기해보자. 우선 100MB의 파일을 보낸다고 가정하자. 이 파일을 한 패킷에 넣어서 보낼 수 있을까? 당연히 불가능하다. 그래서 이것을 전송가능한 최대치로 나눈다. 그 최대치를 Maximum Segment Size 즉, MSS라고 한다. 이 사이즈대로 100MB를 아래와 같이 나눈다. 이제 sender의 TCP는 이 각각의 MSS를 receiver에게 보내면 된다. window는 TCP가 보낼 MSS 또는 보냈는데 아직 receiver로부터 ACK를 받지 않은 MSS들의 집합이라고 보면 된다. 아래와 같다.
위의 그림에서 MSS가 1MB라고 가정하여 100칸의 segment가 있다고 치자.(100MB를 보내야 하는 상황이므로) 그 중에서 30MB는 TCP가 보냈고 ACK도 받았다. 30MB부터 보낼 차례인데, TCP는 현재 window size를 10으로 두고 있다. 즉, 지금 현재 TCP가 작업할 segment는 30MB부터 40MB까지 10MB이다. 40MB부터 100MB까지는 아직 untouched 하게 내버려둔다. 자 지금 현재 TCP가 작업하고 있는 10MB 정도의 영역을 우리는 window라고 한다. 조금 더 정확히 말하면 opened window, 즉 열린 window이다. 지금 현재 이 부분으로 작업을 하고 있다는 뜻이다. 그렇다면 closed window는 어디일까? 0MB부터 30MB까지이다. 즉 지금 현재 이미 작업을 마친 부분을 의미한다.
opened window 부분을 조금 더 자세하게 보자. 빨간 segment 들은 이미 receiver에게 전송을 마친 부분이다. 그러나 아직 ACK를 받지 않아서 opened window 에 포함되어있는 것이다. 주황색 segment들은 아직 receiver에게 보내지 않은 segment들이다. 40MB부터 100MB까지도 아직 보내지 않은 segment들이나 그 부분은 아직은 TCP가 신경쓸 부분이 아니므로 untouched하게 내버려둔다. (여기서 untouched라는 용어는 내가 표현하는 방법일 뿐이지 학술적으로 그렇게 설명하고 있는 용어는 아니다.) window size라는 것은 바로 여기서 말하는 opened window 안에 있는 segment 개수를 의미한다. 여기서는 10개가 되겠다.
자 이제 window 의 개념은 자세하게 설명한 것 같으니 TCP Congestion Control의 첫 단계 SLOW START를 공부해보자. 이 부분은 바로 window size를 1부터 시작하겠다는 뜻이다. 대신에 1부터 exponential 하게 증가하여 congestion window size(cwnd)가 1, 2, 4, 8, 16 .... 과 같이 기하 급수적으로 증가하게 된다. 이렇게 어디까지 증가하는가? ssthresh까지 증가한다. 이는 slow start threshold의 약자이다.
이 값을 초과하기 전까지 Slow Start를 한다. ssthresh값이 16이라고 가정하고 시간에 따른 Slow Start의 전송량(단위;window)을 보자.
ssthresh값에 도달한 후에는 이제 더이상 Slow Start를 쓰지 말고 Congestion Avoidence를 쓰게 된다. Slow Start에서 window size를 두배씩 급격하게 늘려갔다면 Congestion Avoidence에서는 cwnd를 1씩 차근 차근 늘려간다. 위의 그래프를 이어서 그리면 아래와 같이 그려진다.
Congestion Avoidance는 TCP Timeout이 발생하거나 3 ACKs가 발생할 때까지 지속된다. 3 ACKs가 뭐냐고 물어보는 사람은 아래의 링크를 참고하라.
http://operatingsystems.tistory.com/entry/NW-Flow-Control-and-Error-Control
위의 링크에서 설명하는 3 duplicated ACK를 의미하는 것이다.
Congestion Avoidance는 TCP Timeout이 발생하거나 3 ACKs가 발생하면 멈춘다고 했다. 그 후에 진행되는 것이 Multiplicative Decrease이다. 이 과정이 위에서 말했던 Congestion Detection이다. TCP Timeout이 발생했을 경우에는 Multiplicative Decrease가 발생하면서 cwnd가 1이 되고 Slow Start 부터 다시 시작한다. 반면, 3 ACKs가 발생했을 경우에는 Multiplicative Decrease가 발생하면서 cwnd가 현재 cwnd의 절반이 된다. 그리고 Congestion Avoidance를 시작한다. 이를 그래프로 그리면 아래와 같다.
위의 모든 과정을 Algorithm으로 나타내면 아래와 같다.
요약하면 이러하다. TCP는 데이터를 보낼 때 Slow Start를 통해서 기하급수적으로 보내는 데이터의 양을 늘려간다. 그러다가 어느 수치에 다달으면(threshold) 보내는 데이터의 양을 Congestion Avoidance를 통해 서서히 즐가시킨다. 이 때 마주칠 수 있는 두 가지 경우가 있는데, 첫째로 Timeout이 발생하면 cwnd가 1로 되면서 Slow Start를 다시 시작하고 두번째로 3 ACKs가 발생하면 cwnd가 현재의 cwnd의 절반으로 되면서 Congestion Avoidance를 수행하게 된다.
이게 실제로 쓰이는지 궁금해 사람들을 위해 한가지 예시를 들어보자. 파일 다운로드 받을 때 전송 속도를 보면 답이 나온다. 처음에는 초당 수십 KB씩 받으면서 기하 급수적으로 초당 몇 MB 수준으로 올라온다. 그러다가 전송 속도가 줄었다 늘었다 한다. 그 과정이 결국 TCP의 Congestion Control 과정이다.
아, 드디어 TCP/IP에서 내가 공부한 부분은 다 설명했다. 사실 하나 더 올리고 싶은 부분이 있다. TCP/IP 관련이 아니라 2계층인 Datalink layer 부분이다. 이 계층은 Error Correction을 지원한다. 즉, 전송 도중에 Error가 발생해서 올바르지 못한 데이터가 도착해도 receiver가 알아서 제대로 고친다는 뜻이다. 막 공부하고 싶어지지 않나?
'Computer Networks' 카테고리의 다른 글
| [NW] Congestion Control (12) | 2013.10.01 |
|---|---|
| [NW] TCP Flag (0) | 2013.09.22 |
| [NW] Flow Control and Error Control (1) | 2013.09.17 |
| [NW] TCP and UDP (1) | 2013.09.02 |
| [NW] Transport Layer (1) | 2013.08.25 |
| [NW] Type of Service (Differentiated Service) (2) | 2013.08.21 |




댓글을 달아 주세요
헬렌켈러 2013.10.23 20:29 댓글주소 수정/삭제 댓글쓰기
막 시작하는 저에게 정말 많은 도움이 됬습니다.
너무너무 감사하고 고생하셨습니다
열공하세요!!ㅋㅋㅋ 아 이렇게 좋은 말씀써주시면 뿌듯~~하네요ㅋㅋㅋ
잉잉 2013.10.27 15:56 댓글주소 수정/삭제 댓글쓰기
처음부터 정독했네요:) 네트워크 전공 학생인데 몇몇 이해안갔던 부분 이해하고 갑니다. 좋은 포스팅 감사해요!!
크~~ 처음부터 정독하셨다니.. 또 감동이네요... 요즘 정말 블로그 뎃글에 힘많이 얻고 삽니다ㅋㅋㅋㅋㅋ 네트워크 전공이시더라도 다른 부분은 꼭 공부하셔야 할 때가 올 거에요ㅋㅋ 다른 부분도 자세하게 정성껏 설명해놨으니 많이 읽어보고 가세요 :-)
기묘한 2013.12.07 09:42 댓글주소 수정/삭제 댓글쓰기
잘보고 갑니다
근데 혹시 두번째 slow start에서는 threshold가 절반이 되었는데 이것에 대한 알고리즘 좀 알려주실 수 있나요? 왜 저기서는 threshold가 절반일때 congestion avoidence로 진입한건가요
안녕하세요!! 우선 이와 같은 질문을 해결하기 위해서 최고의 방법을 알려드릴게요~ 답은 간단합니다. 무조건 커널 소스 들여다보시면 됩니다ㅋㅋㅋ 그 어느 누구의 말보다도 정확한 거라고 생각해요..
TCP flow control은 커널에서 아래의 경로에 구현되어있어요.
/net/ipv4/tcp_cong.c
여기에 보시면 tcp_slow_start라는 함수로 slow start가 구현되어있고, tcp_cong_avoid_ai라는 함수로 congestion avoidance 가 구현되어있어요~
(참고로 /net/ipv4/tcp_vegas.c에 보시면 베가 알고리즘이라고 해서 베가 알고리즘 만의 congestion avoidance가 구현되어있네요...tcp_vegas_cong_avoid라는 이름으로요)
아무튼 threshold가 절반으로 되어있는 알고리즘은 /net/ipv4/tcp_cong.c에서 tcp_slow_start 함수를 보시면 되는데요
if(sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tp_max_ssthresh)
cnt = stsctl_tcp_max_ssthresh >> 1;
이렇게 구현되어있네요.... 즉, max_ssthresh가 0보다 크고!! sender의 congestion window가 slow start의 최대 임계치 (ssthresh) 보다 크면 무조건 최대치를 절반으로 줄이네요...
그리고 왜 threshold가 절반일 때 congestion avoidance로 진입하느냐는 질문에 대해서 추측을 해보면...(이부분은 저도 정확히는 못 봤으나)
분명 어딘가에 slow_start에서 congestion avoidance를 call하는 부분이 있을 겁니다... slow_start 함수에서 이미 절반을 했고(위의 코드에서 >>1 을 했었죠?) 그 다음에 congestion avoidance 함수를 호출했겠죠? 그러면 자연스럽게 threshold가 절반일 때 congestion avoidance로 진입하게 되겠네요~ (이 부분은 확실히 소스코드로부터 확인한게 아니라서 확신은 못 하겠네요ㅋㅋㅋ)
커널 소스 보시고 연구해보시면 답이 나올겁니다!! 열공하세요!!
bandsi 2014.03.28 11:23 댓글주소 수정/삭제 댓글쓰기
처음부터 정독했는데,
알기 쉽게 설명을 잘 해놓으신 것 같습니다.
(그래도 아직 잘 모르겠는게 많은건 함정..)
공부하고싶어요!!
2014.12.08 21:25 댓글주소 수정/삭제 댓글쓰기
비밀댓글입니다
김원철 2015.04.12 16:14 댓글주소 수정/삭제 댓글쓰기
congestion control에서 왜 transport layer에서 하는 건가요?
network layer와 비교해서 장단점이 무엇인지 알수 있을까요?
network layer의 역할을 생각해보시면 답이 나올 것 같습니다!!
network layer는 오로지 데이터 전달하는 역할입니다
우체부가 받은 소포에 내용 검사안하죠? 그런거와 같습니다.
김원철 2015.04.12 16:16 댓글주소 수정/삭제 댓글쓰기
현재 인터넷에서는 RFC793을 사용하는 것으로 알고 있습니다.
그렇다면,, RFC 793에서 다음의 RTO를 계사는데에 있어서 jacobson의 알고리즘을 사용하는데..
그에 대한 변수를 g= 0.125, h= 0.25, f=4 그리고 exponential averaging에서도 alpha = 0.8~0.9,
beta = 1.3~2로 추천을 하는데.. 그에 대한 근거가 무엇인지 궁금합니다....
RFC793.. TCP네요....
jacobson 알고리즘은... 저도 잘모르겠습니다ㅋ
아마 data communications and networking 라는 책을 찾아보시면 아마 있지 않을까 싶네요.. (확인해본 사항은 아닙니다)