http://www.kocw.net/home/cview.do?mty=p&kemId=1169634
Congestion Control이란?
이전에도 봤듯이, 모두가 함께 사용하는 네트워크를 혼잡하게 만들면 안된다. 즉, 요청(=전송량)을 나 혼자 살자고 네트워크에 쏟아부으면 안된다는 것이다. 이기적으로 행동해서 많은 양을 한 번에 전송하게 되면 결국 네트워크가 막히게 되고, 본인에게도 좋지 않은 결과를 가져다주게 된다. 결론적으로 전송량을 관리하는 것은 매우 중요한 요소 중 하나라는 것이다.
이에 등장하는 개념이 TCP Congestion Control, 말 그대로 TCP의 혼잡을 제어하는 역할을 한다. 즉 전송량을 결정하는 것을 TCP Congestion Control이라고 한다. 이러한 TCP Congestion Control에는 크게 3단계가 있는데 하나씩 살펴보자!
잠깐! 용어를 짚고 넘어가보자.
전송량을 결정하는 것은 무엇일까?
바로 이전에 배웠던 window의 크기이다. congestion control 단계에서는 congestion window (=congwin)이라고 불리며, 이 크기가 곧 전송량을 의미한다.
congestion window의 단위는 무엇일까?
MSS (Maximum Segment Size)로 표기하며 약 500byte 정도 된다고 한다.
이제 알아보겠지만, 1단계(slow start)를 위해 처음에는 무조건 congestion window의 크기를 1 MSS로 정해두고 시작한다.
그러면 이제 세 가지 단계에 대해서 본격적으로 알아보자.
TCP Congestion Control의 단계
1. Slow Start
일상생활에서 파이프의 두께를 모르는 상태에서는 물을 함부로 많이 쏟아 붓기에는 위험성이 있다. 실제로도 어느 정도의 두께를 가지는지 모를 경우, 물을 천천히 흘려보내면서 그 크기를 가늠하기도 하는데 Slow Start는 이와 매우 유사하다! 파이프에 물을 조심스럽게 한 방울씩 흘려보내는 것 처럼, 네트워크에 요청할 때도 적은 양을 조심조심 요청해나가는 단계를 말한다. 즉, 시작하는 과정에서는 네트워크 현재 상황을 모르기 때문에 조심스럽게 요청하며 다가가야 한다는 것이다.
하지만 나중에 맨 아래의 그림을 보게되면 알겠지만, 말이 slow start이지 exponential하게 증가되고 있음을 알 수 있다. 이 부분은 참고만 하면 될 듯 하다.
하지만 이와 같이 계속 조금씩 계속적으로 요청하는 경우에 어떠한 단점이 있을까?
패킷을 1, 2, 4개 보내는 것은 사실네트워크의 입장을 고려했을 때 좋은 행동이지만, 만약 네트워크가 처리할 수 있는 양이 100,000개라고 하면, 조금씩 계속 요청하는 것은 비효율적으로 자원을 사용하고 있다는 것과 같다.
이러한 단점을 보완하기 위해, 다음의 두 번째 단계를 거친다.
2. Additive Increase ( = Congestion-Avoidance )
우선 처음에는 Slow Start를 하기 때문에 천천히 Congestion Window 크기를 늘려나간다. 계속 exponential하게 늘려나가다가 어느 지점부터는 조심해줘야 하는데, 그 지점이 바로 threshold이다. threshold 이후부터는 exponential이 아닌 linear하게 증가되어야 한다. 이 순간을 additive increase라고 한다.
이제 linear하게 계속적으로 congestion winodw를 늘려나가게 되는데 특정 순간에 패킷이 유실되는 등 패킷 로스가 발생하게 된다.
이제 3번째 단계로 진입해야될 시점임을 알 수 있다.
3. Multiplicative decrease
우선 앞에서 배웠던 패킷 로스를 탐지하는 두 가지 방법에 대해서 다시 점검해보자.
- Time-Out
말 그대로 요청 이후에 일정 시간동안 응답이 없을 때 패킷 로스가 일어났다고 판단하는 것이다. 이 경우 특정 시점을 포함한 그 이후까지 유실이 된 상황이다. - 3 dup ACK
3번 요청했음에도 응답을 받지 못할 때 패킷 로스가 일어났다고 판단하는 것이다. Time-out과는 다르게 해당 시점의 ACK만 유실되었다고 판단한다. 즉 ACK 10인 경우, 뒤의 11, 12, 13은 모두 잘 갔는데 10만 잘 가지 않은 상황인 것이다.
위 두 개의 상황을 봤을 때 어떤 상황이 더 심각한 상황으로 보일까??
바로 1번 상황이다. 2번의 경우 특정 하나의 패킷만이 유실된 것이나, 1번의 경우 특정 패킷을 포함하여 그 이후부터 모두 유실된 것이기에 이에 대한 Congestion Control의 리액션 또한 달라야 한다.
자 여기서 다시 돌아와서 Multiplicative decrease에 대해 알아보자.
말 그대로 절반으로 감소시킨다라는 것이다. 하지만 위에서 봤듯이 상황에 따라 다른 방법을 적용시켜줘야 한다.
[Time-Out인 경우]
우선 패킷 유실이 일어난 시점의 Congestion Window를 절반으로 나누어 이를 새로운 threshold로 지정한다.
즉 threshold = congestion window / 2 가 되는 것이다.
그리고 congestion window는 다시 처음부터 slow start를 하기 위해 처음 지점으로 돌아가게 된다.
줄일 때 처음으로 가는 것 처럼 왜 이렇게 과격하게 줄일까?
왜냐하면 네트워크는 공유자원이고 막힌 상황을 푸는게 더 어렵기 때문에 확 줄이는 것 이다. 즉, 막힐때까지는 조심조심 행동하지만, 네트워크가 막혔다 싶으면 요쳥량을 확 줄여서 부하를 줄이는 것이다.
그렇게 다시 1단계부터 진행하며 네트워크 요청을 하게 된다.
[3 dup ACK]
이 경우 특정 패킷만 유실한 케이스이기 때문에, 굳이 맨 처음으로 돌아갈 필요가 없다. 그렇기에 1번의 경우에는 congestion window / 2의 값을 threshold와 출발선으로 삼는다. 그리고 다시 linear하게 congestion window 크기를 늘려나간다.
즉 상황에 따라 다르게 행동해야한다는 것이 핵심이고, 사실 1번 방식은 사용되지 않고 있다고 한다. 발전사 정도만 기억해두면 좋을 듯 하다.
TCP Congestion Control Details
위의 3단계처럼 congestion window 크기가 왔다갔다 하기 때문에 파일 전송을 받거나, 웹 브라우징 할 때 전송 속도가 왔다갔다하게 된다고 한다.
왔다갔다하지 않고 최적의 수준으로만 보내면 안되는지 궁금증이 생길 수 있다.
결론부터 이야기하면 “그럴 수 없다” 왜냐하면 정확한 패킷 유실 지점이나 threshold를 알 수 없고, 그 지점이 계속 변하기 때문에 더더욱 알 수 없다! 그 지점을 모르기 때문에, 지점을 찾아가는 과정이 congestion control 3단계이며 계속 반복할 수 밖에 없다.
(threshold 같은 경우도 초기 설정이 어려우며, 패킷이 유실되었을 때 절반의 지점으로 사용하는 방식을 쓴다.)
그리고 전송 속도는 congestion window에 의해서 결정된다는 것을 알 수 있다.
RTT (round trip time)
CongWin (Congestion Window)
RTT보다는 CongWin이 변화가 더 심한 편이다. 왜 인지는 위 3단계만 봐도 알 수 있을 것이다. 즉, 전송속도는 곧 CongWin에 의해 좌우되는 것이라고 봐도 무방하다.
CongWin의 사이즈를 결정하는 것은 네트워크이다. 네트워크 상황에 따라 결정이 되면, 모두의 전송속도 또한 정해지게 된다. 만약 네트워크가 지금 많이 붐비는 상황이라면 CongWin 값이 작아지고, 한산하다면 CongWin 값이 커지게 된다. 이에 따라 전송속도도 변화하게 되는 것이다!
여기서 신기한 점이 있다. 앞에서 말했을 때는 "우리의 행동이 네트워크 속도를 정한다"라고 했었다. 하지만 방금 전에는 네트워크 상황이 각자의 네트워크 상황을 정한다고 했다. 즉, 네트워크가 우리의 속도를 정하기도 하나, 우리 모두의 행동이 전송속도를 결정하는 것과 같은 것이다. 그러니 아이러니하게도 내가 적당히 사용하는 행위가 모두를 위하는 행위이자, 곧 나를 위한 행위가 되는 것이다.
자 이제 Congestion Control의 흐름을 한 번 정리해보자.
x축은 시간이고, y축은 congestion window의 크기이다.
[Slow Start]
1. 처음에는 Congestion Window가 1 MSS에서 시작한다.
2. threshold까지 exponential하게 증가한다.
[Additive Increase (= congestion-avoidance)]
3. threshold 이후부터는 linear하게 증가한다.
[Multiplicative Decrease]
4. 패킷 유실이 일어난 경우
4-1. Time-Out 때문이라면? (= TCP Tahoe (하늘색 선))
4-1-a. threshold는 유실 시점의 CongWin 크기의 절반으로 설정하고, CongWin의 크기는 다시 1 MSS로 설정한다.
4-2. 3 dup ACK 때문이라면? (= TCP Reno (검정색 선))
4-2-a. threshold와 시작 지점을 유실 시점의 CongWin 크기의 절반으로 하고, 이후 linear하게 CongWin을 증가시킴
TCP의 공평성
지금까지는 두 개의 tcp 사이의 전송량을 조절하는 이야기를 한 것이다. 하지만 실제로 네트워크는 모두가 사용하는 것이기에, 모양은 사실 1:1로 생겼다기보다는 거미줄처럼 얽혀있을 것이다.
이 상황에서 모든 사람들이 독립적으로 congestion control한다고 했을 때, 자원을 동등하게 사용한다고 말할 수 있는데 실제로도 공평하게 사용하고 있는게 맞을까?
예를 들어, A가 먼저 네트워크를 사용하여 전체 수용량인 R만큼 혼자 사용했다고 해보자. 만약 중간에 B가 끼어들어서 네트워크에 요청을 하게 된다면? A와 B는 동등하게 R/2씩 사용하게 될까??
사실 이 부분은 직관적이지 않은 문제였으나 정해진 결론이 있다.
결론적으로는 공평하게 된다는 것이다!
x축은 A 컴퓨터의 전송량, y축은 B 컴퓨터의 전송량이다.
초기에는 B가 더 쓰고있는 것을 볼 수 있지만 교차하는 지점을 바로 알아볼 수 있다.
빨간색 선을 보면, 처음에는 R보다 작으니 우상향 방향으로 늘려준다. 그 다음 패킷 유실이 탐지되어 반으로 줄이게 된다. 그 다음 다시 linear하게 증가하고, 또 반으로 줄이게된다. 이렇게 계속 반복하다보면 중간지점으로 수렴된다는 것을 알 수 있다.
그래서 여러모로 좋다는 것이다. 나 하나 살기 위해서 전송량을 줄이는게 모두를 위한 길이 되는 것이기 때문이다!
그래서 더더욱 따르기 싫어도 따를 수 밖에 없는 상황이다.
TCP가 공평하다는 것에 한 가지 맹점이 있는데 바로, TCP의 관점에서 공평하다는 것이다.
위에서 봤듯이 결론적으로 모든 TCP는 공평하게 bandwidth를 갖게 된다. 하지만 A라는 사람이 2개의 TCP를 열고, B라는 사람이 TCP를 1개 열었을 때도 공평하게 될까??
아니다. 누구 하나가 TCP를 더 열게 되면, TCP 커넥션을 더 많이 열었던 사람이 더 많이 쓰게 된다. 즉 위에서 말했던 공평함이란, TCP 그 자체끼리의 공평함을 이야기하는 것이다.