TCP는 신뢰성 있는 통신을 위해 자신이 보낸 패킷에 대해 ACK 확인 → 보낸 쪽에서는 반드시 받는 쪽이 잘 받았다는 신호를 주어야 다음 전송을 하게 됨
TCP는 송신에 대한 응답이 오지않는 경우 일정시간을 대기 후에 다시 재전송함
송신자는 패킷을 송신하고 나면 별도로 정의된 Timer를 시작 → Timer의 시간이 만료되면 다시 패킷을 전송
TCP Retransmission과 RTO(Retransmission Timeout)과 RTT(Round Trip Time)를 학습하는 이유
- 서버와 네트워크 장비의 성능이 좋은 환경에서는 사실 200ms의 RTO_MIN 값은 너무 큰 값일 수 있음
- RTO_MIN이 너무 작으면 재전송이 너무 자주 일어나게 됨 → 재전송이 자주 발생하면, 부하를 일으켜 시스템의 성능과 서비스 응답 속도에 악영향을 끼칠 수 있음
- 서버와 네트워크 환경에 따라서 RTO 값을 조절 필요
- ACK 패킷 손실에 따른 재전송
- Client가 보낸 SYN에 대한 ACK를 받지 못하면 보냈던 SYN을 다시 보내게 됨
- Retransmission Timer라는 커널 타이머에 의해 동작 SYN 재전송 시간 결정
Retransmission 종류
- Retransmission이 발생하는 3가지 상황에서 공통점 → "Timeout 시간 안에 ACK를 받지 못했다."
- Retransmission이 발생하는 경우에 TCP Protocol이 할 수 있는 최선의 방법은 Timeout 시간을 정의하는 것
- Timeout 시간이 지나치게 짧으면 재전송 패킷의 낭비 발생
- Timeout 시간이 지나치게 길면 패킷이 손실되었을 때 에도 기다려야하는 시간이 너무 길어짐
- Timeout 기간에 대한 기준을 정의할 때 적절한 기준 시간 → RTO(Rtransmission Timeout)라는 개념을 사용
1. Retransmission : Packet lost
- 재전송이 발생할 수 있는 첫 번째 상황
- 송신자는 패킷을 보냈지만, 어떤 이유에서인지 중간에 유실되어 수신측에 도달하지 못함
- 수신측은 당연히 패킷이 도착하지 않았으므로 ACK를 보내줄리가 없고, 송신자의 Timer는 만료됨
2. Rertransmssion : ACK lost
- 재전송이 발생할 수 있는 두 번째 상황
- 송신자가 패킷을 보냈고, 수신 측 또한 응답으로 ACK를 보냄
- 수신자의 ACK 응답이 중간에 유실되어 송신자에게 도착하지 못하고, 송신자의 Timer는 만료됨
3. Retransmission : Early Timeout
- 재전송이 발생할 수 있는 세 번째 상황.
- 송신자가 패킷을 보냈고, 수신 측에서 응답으로 ACK를 보냄
- 네트워크 지연이 발생해서 송신자의 Timer가 만료되어버린 후에 ACK가 송신자에게 도착함
RTO(Retransmission Timeout)과 RTT(Round Trip Time)
RTO(Retransmission Timeout) → 타이머가 작동하는 시간을 의미
RTT(Round Trip Time) → 네트워크 통신을 하는 두 노드 간에 패킷이 전달되는데 소요된 시간을 의미
종단 간 거리가 멀면 멀수록 RTT 값을 커지게 됨
RTT는 RTO의 값을 결정하는데 아주 중요한 요소가 됨
RTO는 내부적으로 복잡한 계산식을 거친 후 동적으로 설정 → RTT 값을 기반으로 계산함
- 두 종단 간 통신이 이루어지는 첫 번째 SYN 패킷에 대한 RTO는 어떻게 결정되는가?
- TCP Handshake를 하기 위한 첫 번째 SYN 패킷은 상대방과의 RTT에 대한 정보가 전혀 없기 때문에 계산이 불가능 → 지정된 값을 사용
- 최초의 RTO 값을 InitRTO이라고 부름 → OS 마다 값이 조금씩 다르지만, Linux에서는 1초로 되어 있음
- 1초 → 2초 → 4초 이런 식으로 InitRTO 값은 2의 제곱수로 늘어남
- RTO는 운영체제 커널에 정의 → 운영체제 별로 초기값을 갖고 있지만, 모든 네트워크 상황은 다르므로 RTO는 동적으로 변함
- RTO 참고 자료 → https://www.rfc-editor.org/rfc/rfc6298.txt
1. SRTT(SampleRTT)
- RTO는 RTT에 의해서 변하는데, RTT는 호스트 간 송신에 대한 응답을 받기까지 걸리는 시간을 의미
- SampleRTT를 측정된 RTT → 송신자의 Original Transmission에 대한 ACK를 받기까지의 시간을 SampleRTT로 설정
- ACK 받기까지 시간이 오래 걸려 재전송이 발생했을 경우, 응답해온 ACK가 초기 응답인지 재전송에 대한 응답인지 구분하기가 어렵움 → Retranmission에 대한 ACK인지 송신자는 판단 불가
2. Karn / Partridge Algorithm
- RTO Timer가 만료되면 RTO 값을 2배로 늘어남 → Exponential Backoff 라고함
- SampleRTT는 송/수신이 완료된 전송에 대해서만 값을 기록
- SampleRTT 값을 Computed RTO를 도출하는 데 사용
애플리케이션 타임아웃
- InitRTO의 경우는 1초로 설정되어 있기 때문에 애플리케이션의 타임아웃은 1초보다 큰 값으로 설정 필요 (InitRTO는 TCP의 시간)
- 세션이 연결된 상황에서 재전송은 RTT를 기반으로 생성되기 때문에 대부분 1초를 넘기지 않음
- 세션이 연결되어 있지 않는 상황에서는 TCP Handshake를 맺는 과정에서의 재전송은 최소 1초 소요되기 때문에 애플리케이션에서 타임아웃을 1초로 설정한다면 재전송으로 커버 가능한 통신을 타임아웃 에러로 끊어 버리게 됨
- 커넥션 풀 방식으로 네트워크 세션을 미리 만들어 두고 통신하는 경우에는 InitRTO가 발생할 일이 없기 때문에 더 작은 값으로 설정해도 됨
RTO_MIN
RTO 값에 영향을 주는 다른 요소 → RTO_MIN 값으로 RTO의 최솟값을 의미
별도로 설정하지 않았다면, RTO_MIN의 기본 값은 200ms로 되어 있음 → RTT가 아무리 작아도 RTO값은 200ms 밑으로 내려갈 수 없음을 의미
RTO_MIN 변경 URL : https://unix.stackexchange.com/questions/210367/changing-the-tcp-rto-value-in-linux
현재 설정되어 있는 RTO값 확인 → Linux에서는 ss -i 명령을 이용해서 현재 통신 중인 세션의 RTO 값을 확인 가능(RTO 값이 235)
$ ss -i tcp ESTAB 0 2384 211.212.37.175:snapenetio 1.214.216.250:linktest-s cubic wscale:8,7 rto:235 rtt:34.161/18.592 ato:40 mss:1460 rcvmss:1168 advmss:1460 cwnd:8 ssthresh:7 bytes_acked:25341 bytes_received:11268 segs_out:275 segs_in:383 send 2.7Mbps lastsnd:2 lastrcv:6 lastack:6 pacing_rate 5.5Mbps unacked:8 retrans:0/1 rcv_space:29200
RTO_MIN 변경은 ip route 명령어를 통해 변경 → 100ms로 RTO_MIN을 변경한 후에 ss -i 명령으로 RTO 값이 변해있는 것을 확인(RTO값이 120)
- ip route 명령어를 통해 기존 게이트웨이 rto_min 확인
$ ip route default via 211.212.37.161 dev eno3 proto static metric 100 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 211.212.37.160/27 dev eno3 proto kernel scope link src 211.212.37.175 metric 100
- ip route 명령어를 통해 기존 게이트웨이의 rto_min 변경
# 형식 : ip route change default via <default gw> dev <ethernet> rto_min 100 $ ip route change default via 211.212.37.161 dev eno3 proto static metric 100 rto_min 100ms
- ip route를 통해 게이트웨이 RTO_MIN 추가 확인
$ ip route default via 211.212.37.161 dev eno3 proto static metric 100 rto_min lock 100ms 172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 211.212.37.160/27 dev eno3 proto kernel scope link src 211.212.37.175 metric 100
- RTO_MIN이 100ms으로 변경하였기에 RTO 값이 기본 RTO_MIN값인 200ms보다 떨어져 있음을 확인
$ ss -i tcp ESTAB 0 1168 211.212.37.175:snapenetio 1.214.216.250:linktest-s cubic wscale:8,7 rto:145 rtt:44.372/5.203 ato:40 mss:1460 rcvmss:1168 advmss:1460 cwnd:6 ssthresh:5 bytes_acked:103277 bytes_received:63924 segs_out:1502 segs_in:2153 send 1.6Mbps lastrcv:8 pacing_rate 3.2Mbps unacked:5 retrans:0/2 rcv_rtt:535816 rcv_space:29364
- ip route 명령어를 통해 기존 게이트웨이 rto_min 확인
참고 URL : https://pcmc.tistory.com/entry/190618-TCP-Retransmission
참고 URL : https://brunch.co.kr/@alden/15
'Network(네트워크)' 카테고리의 다른 글
Fast Retransmit, Flow Control 과 Congestion Control (0) | 2022.06.26 |
---|---|
Network Ring Buffer Size 설정하기 (0) | 2022.06.26 |
TOE(TCP offload engine) (0) | 2022.06.26 |
점보프레임(Jumbo Frame)으로 전송속도 높이기(MTU 9000)메타 데이터의 끝으로 건너뛰기 (0) | 2022.06.26 |
패킷사이즈가 MTU 1500 바이트를 넘는 경우 -> TOE 기능 ON (0) | 2022.06.26 |