핵심 인사이트 (3줄 요약)
- 본질: 임계치(ssthresh)는 TCP 혼잡 제어 과정에서 "미친 듯이 배수로 뻥튀기하는 슬로우 스타트(Slow Start)의 폭주를 어디서 멈출 것인가"를 결정하는 가속 중단 커트라인이자 안전 방어선이다.
- 초기값과 변동: 통신을 처음 시작할 땐 이 커트라인이 수신자가 허락한 창문 크기(보통 65535바이트, 무한대)로 널널하게 잡혀 있다가, 한 번이라도 패킷이 유실되어 사고가 터지면 "앗! 아까 그 속도의 딱 절반(1/2)이 진짜 안전선이었구나!"라고 깨닫고 커트라인을 대폭 깎아 내린다.
- 기어 변속의 기준점: 송신자의 속도(CWND)가 계속 올라가다가 이 ssthresh 숫자와 딱 부딪히는 순간, 배수(x2)로 오르던 속도는 덧셈(+1)으로 찔끔찔끔 오르는 '혼잡 회피(Congestion Avoidance)' 모드로 강제 기어 변속이 일어난다.
Ⅰ. 개요 및 필요성 (Context & Necessity)
-
개념: TCP 송신 측이 네트워크 혼잡 발생 가능성을 최소화하기 위해 설정하는 변수로, 슬로우 스타트 단계(지수적 증가)에서 혼잡 회피 단계(선형적 증가)로 전환되는 기준점.
-
필요성: 차를 샀다. 액셀을 밟으니 시속 10km, 20km, 40km, 80km, 160km로 무섭게 가속(Slow Start)이 붙는다. 문제는 이 차가 시속 320km를 밟는 순간 엔진이 터진다는 것이다. "야! 어디까지 액셀을 밟아도 되는지 '안전 커트라인'을 정해둬야지! 커트라인에 도달하면 그때부터는 시속 1km씩만 조심조심 올려!" 이 커트라인이 없다면 TCP는 1초 만에 기가비트를 쏘아대며 모든 라우터를 터뜨려버릴 것이다.
-
💡 비유: ssthresh는 고무풍선을 불 때의 **"풍선 표면 장력 한계선"**과 같습니다.
- 처음엔 에어 펌프로 공기를 훅훅(배수) 불어 넣어도 풍선이 잘 커집니다.
- 하지만 풍선이 터지기 직전 크기(ssthresh)에 도달하면, 그때부터는 공기를 훅훅 불어 넣으면 풍선이 터집니다.
- 이 커트라인부터는 입으로 아주 조심스럽게 호~ 호~(1씩 더하기) 불어 넣어야 풍선을 최대한 크고 안전하게 부풀릴 수 있습니다.
📢 섹션 요약 비유: 임계치(ssthresh)는 과속 방지 카메라가 찍히는 **"단속 규정 속도"**입니다. 규정 속도까지는 시원하게 밟고(Slow Start), 규정 속도 근처에 다다르면 단속에 안 걸리게 눈치를 보며 브레이크를 살살 밟아(혼잡 회피) 정속 주행을 유지하게 만드는 기준점입니다.
Ⅱ. ssthresh의 실무적 동작과 갱신 (Deep Dive)
1. ssthresh의 작동 시퀀스
- 초기 상태: 연결이 갓 맺어지면, 내 컴퓨터는 길이 빵빵 뚫려있다고 믿으므로
ssthresh를 엄청나게 큰 값(예: 65,535 바이트)으로 둔다. - 1단계 (Slow Start):
CWND=1부터 시작해서2, 4, 8, 16...미친 듯이 뻥튀기를 시전한다. - 사고 발생 (Drop):
CWND=32를 쐈는데 영수증이 안 온다(Timeout). - 2단계 (ssthresh의 갱신): "앗! 32개 쐈더니 터지네! 그럼 32개의 절반인 16개가 이 도로의 안전선이구나!" ──▶ 즉시 **
ssthresh = 16**으로 수정해버린다! (이것이 가장 중요한 갱신 룰이다). - 3단계 (재출발과 기어 변속): 타임아웃이 났으므로
CWND=1로 곤두박질친다. 다시1, 2, 4, 8로 가속한다.- 드디어
CWND = 16이 되었다! - 뇌구조: "앗! 아까 새로 그어둔 커트라인(16)에 도달했다! 여기서 또 32로 두 배 뛰면 아까처럼 또 사고 나겠지? 이제부터는 곱하기(x2) 금지! 더하기(+1)로 바꾼다!!" ──▶
17, 18, 19...로 조심스레 올라간다.
- 드디어
┌─────────────────────────────────────────────────────────────┐
│ ssthresh의 갱신과 기어 변속 시각화 │
├─────────────────────────────────────────────────────────────┤
│ CWND │
│ 32 | /(사고 펑!!) │
│ | / | │
│ 16 | / | * ─ * ─ * ◀ 혼잡 회피(+1) │
│ | / | / ◀ 여기서 기어 변속!! (ssthresh = 16) │
│ 8 | / | / │
│ 4 |/ | / │
│ 2 | | / │
│ 1 | * ─ * ─ * ◀ 다시 Slow Start 시작 │
│ |____________________________________ 시간(RTT) │
│ │
│ ▶ "ssthresh = MAX( 사고 났을 때의 CWND / 2, 2 MSS )" │
│ ▶ "최소한 2개(2 MSS) 밑으로는 커트라인을 깎지 않는다." │
└─────────────────────────────────────────────────────────────┘
2. TCP 성능 튜닝의 관건
이 ssthresh 값이 너무 빨리 깎이면(네트워크가 조금만 덜컹거려도 깎임), 내 컴퓨터는 평생 속도를 못 내고 계속 17, 18, 19로 기어가게 된다(다운로드 속도 저하). 반대로 너무 늦게 깎이면 버퍼가 계속 터져서 패킷이 다 죽는다.
리눅스 엔지니어들은 이 깎이는 비율(1/2)을 BBR, CUBIC 같은 최신 TCP 알고리즘으로 튜닝하여 고속망에서 속도 저하를 막아내고 있다.
📢 섹션 요약 비유: ssthresh의 갱신 룰은 **"술자리 주량 계산법"**과 똑같습니다. 소주 4병(CWND 32)을 마시고 필름이 끊겨 응급실에 실려 갔다면(Timeout), 다음번 술자리에선 "아, 내 진짜 주량은 4병의 절반인 2병(ssthresh 16)이구나!"라고 깨닫고, 2병을 넘기는 순간부터는 원샷(지수 증가)을 멈추고 반 잔씩 끊어 마시는(선형 증가) 생존 본능입니다.