사전 MTU
개념

MTU

gabury1고친 사람 github-actions[bot]

MTU 는 네트워크 구간 하나가 한 번에 실어 나를 수 있는 데이터 크기의 상한을 정합니다. 이 상한을 넘는 덩어리는 그 구간을 통째로 지나가지 못합니다. 그래서 보내는 쪽은 데이터를 이 크기에 맞춰 잘라서 내보냅니다.

쉽고 빠른 이해

MTU 는 네트워크 구간 하나가 한 번에 받아 주는 최대 크기입니다. 흔한 유선 랜인 이더넷은 1500바이트입니다.

왜 상한을 두는지는 받는 장비 사정 때문입니다. 장비는 덩어리 하나를 통째로 담을 만큼의 메모리를 미리 잡아 둡니다. 게다가 덩어리가 오다가 깨지면 그 덩어리 전체를 다시 보내야 합니다. 크기를 무한정 키우면 두 값이 같이 커집니다.

어떻게 도는가:

  1. 보내는 쪽이 이 크기에 맞춰 데이터를 잘라 내보냅니다
  2. 크기를 넘긴 덩어리를 만난 장비는 잘게 나누거나 버립니다
  3. 버린 장비는 「너무 크다」는 알림을 보낸 쪽으로 돌려보냅니다

대가도 있습니다. 작게 잡으면 덩어리 수가 늘고, 덩어리마다 붙는 주소 정보의 몫도 같이 늘어납니다. 크게 잡으면 가는 길의 모든 구간이 그 크기를 받아 줘야 하고, 한 덩어리가 깨질 때 다시 보내는 양도 커집니다.

상세

짐을 높이 쌓은 트럭은 가는 길에 낮은 굴다리가 하나만 있어도 그 길을 지나가지 못합니다. 그래서 싣는 사람은 길에서 가장 낮은 굴다리의 높이부터 알아봅니다. 짐은 그 높이 아래로 낮춰 여러 번에 나눠 싣습니다.

MTU(Maximum Transmission Unit, 최대 전송 단위)는 한 링크가 한 번에 실어 나를 수 있는 데이터의 최대 크기입니다. 링크는 장비와 장비를 잇는 한 구간을 말합니다. 내 노트북과 공유기 사이가 링크 하나이고, 공유기와 통신사 장비 사이가 또 다른 링크 하나입니다. 이더넷으로 이어진 링크의 MTU 는 1500바이트입니다.

이 절은 먼저 MTU 가 무엇의 크기를 재는지 못 박고, 그런 상한이 왜 있는지를 봅니다. 이어서 링크마다 값이 다를 때 무엇이 기준이 되는지, 상한을 넘긴 데이터에 무슨 일이 생기는지를 봅니다. 마지막으로 보내는 쪽이 미리 크기를 맞추는 방법과, 상한을 키울 때 내주는 것을 봅니다.

MTU 가 재는 크기

MTU 가 재는 것은 링크 위를 흐르는 덩어리 전체가 아닙니다. 링크 계층이 배달을 위해 앞뒤에 덧붙이는 겉포장을 뺀 알맹이입니다. 이더넷은 이 알맹이를 프레임에 실어 나릅니다.

알맹이 하나는 보통 IP(Internet Protocol, 인터넷 프로토콜) 패킷 하나입니다. 그래서 이더넷에서 MTU 가 1500바이트라는 말은 IP 패킷 하나가 1500바이트까지 된다는 뜻입니다.

이 1500바이트 안에는 IP 가 붙이는 헤더도 들어갑니다. 헤더는 받는 쪽 주소처럼 배달에 필요한 정보를 덩어리 앞에 붙인 토막입니다. 헤더가 앞을 차지하므로 실제 데이터에 쓸 수 있는 몫은 그만큼 줄어듭니다.

한 패킷이 어떻게 나뉘는지를 그림으로 보면 이렇습니다.

block-beta
columns 2
  a["IP 헤더 20바이트"]:1 b["보낼 데이터 1480바이트"]:1
  c["IP 패킷 1500바이트 · 이더넷의 MTU"]:2

헤더가 20바이트를 먼저 쓰고 남은 1480바이트가 데이터 몫입니다. 애플리케이션이 보기에 1480바이트를 보낸 것이지만 선 위로는 1500바이트가 흐르는 셈입니다.

상한이 있는 까닭

상한이 없다면 한 번에 아무리 큰 덩어리라도 보낼 수 있어 편할 것 같습니다. 그러지 못하는 이유가 셋 있습니다.

첫째는 받는 장비의 메모리입니다. 장비는 덩어리 하나를 통째로 담을 만큼의 메모리를 미리 잡아 둡니다. 상한이 없으면 얼마를 잡아 둬야 하는지 정할 수 없습니다.

둘째는 오류를 잡아내는 단위입니다. 선을 지나는 동안 값이 한 군데만 어긋나도 그 덩어리는 전부 버려지고 다시 보내집니다. 덩어리가 클수록 한 번 어긋날 때 다시 보내는 양이 커집니다.

셋째는 뒤에 선 덩어리의 대기입니다. 한 덩어리가 선을 쓰는 동안 뒤의 덩어리는 기다립니다. 큰 덩어리를 허용하면 뒤에 선 작은 요청이 그만큼 오래 기다립니다.

링크마다 다른 값과 경로 MTU

MTU 는 링크 규격이 정합니다. 그래서 가는 길의 구간마다 값이 다릅니다. 특히 터널을 지나는 구간은 겉포장이 한 겹 더 붙는 만큼 알맹이에 쓸 수 있는 크기가 줄어듭니다.

보내는 쪽에 실제로 걸리는 상한은 첫 구간의 MTU 가 아닙니다. 가는 길 전체에서 가장 작은 MTU 입니다. 이 값을 경로 MTU 라고 부릅니다.

flowchart TD
    A["보내는 쪽"] --> B["구간 1 · MTU 1500"]
    B --> C["구간 2 · MTU 1400"]
    C --> D["구간 3 · MTU 1500"]
    D --> E["받는 쪽"]
    C -.-> F["경로 MTU 1400 · 가장 작은 값이 기준"]

가운데에 1400바이트짜리 구간이 하나 끼면 앞뒤가 아무리 넓어도 경로 MTU 는 1400바이트가 됩니다. 곤란한 대목은 보내는 쪽이 이 값을 처음부터 알 수 없다는 것입니다. 각 구간의 사정은 그 구간을 쥔 장비만 압니다.

상한을 넘긴 패킷의 처리

상한을 넘긴 패킷을 만난 라우터에게는 길이 둘입니다. 하나는 패킷을 작은 조각으로 나누어 보내는 것입니다. 이 나누는 일을 단편화라고 하고, 조각을 모아 원래 패킷으로 되돌리는 일을 재조립이라고 합니다. 재조립은 목적지가 합니다.

다른 하나는 나누지 않고 버리는 것입니다. 대신 버린 장비가 「너무 커서 못 보냈다」는 알림을 보낸 쪽으로 돌려줍니다. 이 알림을 나르는 것이 ICMP(Internet Control Message Protocol, 인터넷 제어 메시지 프로토콜)입니다.

둘 중 어느 길로 가는지는 IP 판본에 따라 갈립니다. IPv4에서는 중간 라우터도 패킷을 나눌 수 있습니다. IPv6에서는 중간 라우터가 나누지 않습니다. 나누는 일은 보내는 쪽만 하고 중간 라우터는 버린 뒤 알림만 돌려줍니다. 대신 IPv6 는 모든 링크가 1280바이트 이상의 MTU 를 갖기를 요구합니다.

단편화에는 값이 붙습니다. 조각 가운데 하나만 사라져도 목적지는 원래 패킷을 되살리지 못합니다. 조각 열 개 중 하나를 잃으면 열 개를 다시 받아야 합니다. 그래서 요즘 설계는 중간에서 나누기보다 처음부터 맞춰 보내는 쪽을 고릅니다.

상위 계층이 크기를 맞추는 방법

중간에서 나뉘는 것을 피하려면 보내는 쪽이 처음부터 경로 MTU 안에 들어가게 잘라야 합니다. 그 일을 어떻게 하는지는 프로토콜마다 다릅니다.

TCP(Transmission Control Protocol, 전송 제어 프로토콜)는 연결을 맺을 때 한 덩이에 실을 데이터의 최대 크기를 서로 알려 줍니다. 이 값이 MSS(Maximum Segment Size, 최대 세그먼트 크기)입니다. 이더넷이라면 MTU 1500바이트에서 IP 헤더 20바이트와 TCP 헤더 20바이트를 뺀 1460바이트가 됩니다.

UDP(User Datagram Protocol, 사용자 데이터그램 프로토콜)에는 이런 흥정이 없습니다. 애플리케이션이 한 번에 넘긴 만큼이 한 덩이가 됩니다. 그래서 UDP 로 큰 데이터를 보내는 프로그램은 자기가 직접 크기를 챙겨야 합니다.

경로 MTU 를 알아내는 일 자체에도 이름이 있습니다. 경로 MTU 탐색입니다. 나누지 말라는 표시를 붙여 패킷을 보내 보고, 너무 크다는 알림이 오면 크기를 줄이는 식으로 값을 좁혀 갑니다.

큰 응답만 사라지는 증상

경로 MTU 탐색은 알림이 돌아온다는 전제 위에 섭니다. 중간 장비가 보안 설정으로 ICMP 를 막아 버리면 그 전제가 깨집니다.

그러면 설명하기 어려운 증상이 납니다. 연결은 맺어지고 작은 요청은 오갑니다. 그런데 큰 응답이 오는 순간 통신이 멈춥니다. 보낸 쪽은 패킷이 버려진 줄도, 크기를 줄여야 하는 줄도 모른 채 같은 크기로 다시 보냅니다. 이것을 경로 MTU 블랙홀이라고 부릅니다.

백엔드에서 이 증상은 터널을 거치는 구간에서 자주 만납니다. 「짧은 응답은 오는데 목록 조회만 멈춘다」가 그 모습입니다.

MTU 를 키우는 점보 프레임

링크 규격이 정한 값이라고 해서 손댈 수 없는 것은 아닙니다. 장비와 설정이 받쳐 주면 인터페이스의 MTU 를 이더넷 규격이 정한 1500바이트보다 크게 잡을 수 있습니다. 이렇게 키운 프레임을 점보 프레임이라고 부릅니다.

키우면 같은 데이터를 보낼 때 덩어리 수가 줄고 덩어리마다 붙던 헤더도 그만큼 줄어듭니다. 데이터센터 안이나 저장 장치를 잇는 망처럼 구간을 한 팀이 다 쥐고 있는 곳에서 씁니다.

크기를 키우고 줄일 때 무엇이 오가는지를 잣대별로 보면 이렇습니다.

잣대 MTU 가 작을 때 MTU 가 클 때
데이터 대비 헤더의 몫 커진다 작아진다
한 덩어리가 깨졌을 때 다시 보내는 양 적다 많다
한 덩어리가 선을 붙잡고 있는 시간 짧다 길다
경로의 모든 구간이 받아 줘야 하나 아니다 그렇다

마지막 줄이 실무에서 제일 자주 발목을 잡습니다. 내 서버의 MTU 를 키워도 가는 길 어딘가가 그 크기를 못 받으면 그 구간에서 버려집니다.

관련 항목

MTU 가 크기를 재는 대상

패킷 · 프레임 · 데이터그램 · 세그먼트 · 페이로드 · 헤더 · 옥텟

MTU 를 넘긴 데이터가 거치는 처리 단계

단편화 · 재조립 · 경로 MTU 탐색 · MSS 클램핑 · MSS

MTU 값을 정하는 링크 규격과 설정

이더넷 · 와이파이 · 점보 프레임 · 터널링 · VPN · 링크 계층

MTU 위에 얹혀 이 크기에 맞추는 프로토콜

IP · IPv4 · IPv6 · TCP · UDP · ICMP · QUIC

MTU 가 어긋났을 때 나는 장애

PMTU 블랙홀 · 패킷 손실 · 헤드 오브 라인 블로킹 · 타임아웃

다른 이름: Maximum Transmission Unit · 최대 전송 단위