사전 패킷 손실
문제

패킷 손실

gabury1고친 사람 github-actions[bot]

패킷 손실은 보낸 데이터 덩이가 목적지에 닿지 못하고 도중에 사라지는 일입니다. 네트워크는 무엇이 언제 사라졌는지 알려 주지 않습니다. 보낸 쪽은 답장이 안 오는 것을 보고 사라졌다고 짐작합니다.

쉽고 빠른 이해

패킷 손실은 보낸 데이터 덩이 가운데 일부가 목적지에 닿지 않는 일입니다. 파일을 내려받다 속도가 뚝 떨어지거나 화상 회의에서 상대 목소리가 한 토막 끊기는 것이 이 일이 벌어졌을 때 보이는 모습입니다.

네트워크는 감당 못 할 만큼 데이터가 몰리면 줄을 더 세우지 않고 버립니다. 버려도 되게 만들어 둔 덕분에 중간 장비가 단순해지고 한 구간이 막혀도 네트워크 전체가 멈추지 않습니다. 잃은 것을 되찾는 일은 양 끝의 프로그램이 맡습니다.

어떻게 도나:

  1. 한 구간이 흘려보낼 수 있는 양보다 많은 데이터가 그 구간으로 몰립니다
  2. 중간 장비의 대기열이 꽉 차고, 그 뒤에 도착한 덩이는 버려집니다
  3. 답장이 안 오므로 보내는 쪽이 시간을 재다가 다시 보냅니다

대가는 기다림입니다. 다시 보내는 데 왕복이 한 번 더 들고, 보내는 쪽은 손실을 네트워크가 막혔다는 신호로 읽어 보내는 속도까지 낮춥니다.

상세

택배 상자 열 개를 부쳤는데 여덟 개만 도착했다고 해 봅시다. 어느 상자가 빠졌는지는 아무도 알려 주지 않습니다. 부친 쪽은 한참 기다려 보고 안 오면 같은 것을 다시 부칩니다.

패킷은 네트워크가 데이터를 나를 때 잘라 쓰는 덩이 하나입니다. 패킷 손실은 이 덩이가 출발지와 목적지 사이 어딘가에서 없어지는 일입니다.

없어진 덩이는 어디에도 남지 않습니다. 버린 장비는 버렸다는 기록을 보낸 쪽에 보내 주지 않고, 받는 쪽은 그 덩이가 있었다는 것조차 모릅니다.

이것이 최선형 전달이라고 부르는 약속입니다. 네트워크는 닿게 하려고 애는 쓰되 닿는다고 약속하지는 않습니다. 약속을 안 한 덕분에 중간 장비는 누가 누구와 통신 중인지 기억하지 않아도 되고, 그래서 네트워크를 크게 넓힐 수 있습니다.

대기열이 넘치면 버린다

가장 흔한 까닭은 혼잡입니다. 혼잡은 한 구간으로 들어오는 데이터가 그 구간이 내보낼 수 있는 양보다 많아진 상태를 뜻합니다.

라우터는 들어온 패킷을 보고 다음 장비로 넘겨주는 장비입니다. 넘기는 속도보다 들어오는 속도가 빠르면 못 넘긴 패킷이 대기열에 쌓입니다. 대기열은 라우터가 미처 못 넘긴 패킷을 잠시 쌓아 두는 공간입니다.

이 공간에는 끝이 있습니다. 꽉 찬 뒤에 도착한 패킷은 들어갈 곳이 없습니다. 라우터는 그 패킷을 버립니다.

flowchart TD
    A["패킷이 라우터에 도착한다"] --> B{"대기열에 빈 곳이 있나"}
    B -->|있다| C["줄을 세운다 · 차례가 오면 내보낸다"]
    B -->|없다| D["버린다 · 아무에게도 안 알린다"]

그림의 오른쪽 갈래가 패킷 손실입니다. 버리는 쪽에는 되돌릴 절차가 없습니다. 한 번 버려진 패킷은 그 장비 안에서 끝입니다.

재현 조건도 이 갈래에서 나옵니다. 어떤 구간이 내보낼 수 있는 양보다 많은 데이터를 그 구간으로 계속 밀어 넣으면 됩니다. 기계 둘을 한 선로로 잇고 한쪽이 그 선로가 감당하는 양을 넘겨 보내면, 넘긴 만큼이 중간에서 버려집니다.

버려지는 다른 까닭

혼잡 말고도 패킷이 없어지는 길이 몇 가지 더 있습니다. 증상은 같은데 손을 대야 할 곳이 서로 다릅니다.

까닭 어디서 어떻게 버려지나
전송 중 비트가 틀어짐 데이터가 온전한지 보려고 함께 실려 온 짧은 값이 체크섬입니다. 받는 장비가 이 값을 맞춰 보고 안 맞으면 버립니다
거쳐 갈 장비 수를 다 씀 패킷에는 몇 장비까지 거쳐도 되는지가 적혀 있습니다. 이 수가 0이 되면 그 장비가 버립니다
정책에 걸림 무엇을 지나보낼지 미리 정해 두고 거르는 장치가 방화벽입니다. 여기에 걸린 패킷은 목적지까지 가지 않습니다
크기 초과 구간마다 한 번에 실을 수 있는 크기 상한인 MTU(Maximum Transmission Unit, 최대 전송 단위)가 있습니다. 넘는 패킷은 쪼개지거나 버려집니다
받는 기계에서 넘침 도착은 했는데 받는 프로그램이 제때 안 읽어 가면, 프로그램이 데이터를 주고받는 출입구인 소켓의 받는 공간이 차서 버려집니다

마지막 줄은 따로 짚어 둘 값이 있습니다. 손실이 늘 네트워크 한가운데서 나는 것은 아닙니다. 받는 기계 안에서도 납니다. 서버가 바빠 읽어 가지 못하면 운영체제가 쌓아 두다가 버리므로, 네트워크를 아무리 뒤져도 원인이 안 나옵니다.

아무도 알려 주지 않는다

버린 장비는 버렸다는 것을 알리지 않습니다. 그래서 손실은 눈으로 보는 것이 아니라 짐작으로 알아냅니다.

프로토콜은 둘이 데이터를 주고받는 순서와 꼴을 미리 정해 둔 약속입니다. TCP(Transmission Control Protocol, 전송 제어 프로토콜)처럼 빠짐없는 전달을 챙기는 프로토콜은 손실을 짐작하는 방법을 둘 가지고 있습니다. 아래 그림에 둘이 같이 나옵니다.

sequenceDiagram
    participant 보내는 쪽
    participant 라우터
    participant 받는 쪽
    보내는 쪽->>라우터: 패킷 1
    라우터->>받는 쪽: 패킷 1
    받는 쪽-->>보내는 쪽: 1번까지 받았다
    보내는 쪽->>라우터: 패킷 2
    Note over 라우터: 대기열이 꽉 차 2번을 버린다
    보내는 쪽->>라우터: 패킷 3
    라우터->>받는 쪽: 패킷 3
    받는 쪽-->>보내는 쪽: 1번까지 받았다
    보내는 쪽->>라우터: 패킷 2 다시

첫째 짐작은 시간입니다. 확인 응답은 받는 쪽이 「여기까지 받았다」고 알려 주는 짧은 답장입니다. 보내는 쪽은 패킷을 내보낸 뒤 답장이 올 때까지 시간을 잽니다. 정해 둔 시간이 지나도 답장이 없으면 사라졌다고 보고 다시 보냅니다. 이 기다림이 타임아웃입니다.

둘째 짐작이 그림의 마지막 답장입니다. 3번이 도착했는데도 받는 쪽은 여전히 「1번까지 받았다」고 답합니다. 2번이 빠져 중간에 구멍이 났기 때문입니다. 같은 답장이 되풀이되는 것을 중복 확인 응답이라고 부릅니다. 보내는 쪽은 이 되풀이를 타임아웃보다 이른 손실 신호로 읽습니다.

네트워크를 밖에서 재는 쪽에서는 ping을 씁니다. ping 은 짧은 패킷을 여러 번 보내고 몇 개가 돌아왔는지 세어, 보낸 것 가운데 얼마가 안 돌아왔는지를 함께 적어 줍니다.

되찾는 길은 셋이다

잃은 것을 어떻게 할지는 네트워크가 아니라 양 끝의 프로그램이 정합니다. 고르는 길은 대체로 셋입니다.

길 어떻게 하나 대가
다시 보낸다 빠진 것을 되보내고 받는 쪽에서 원래 순서로 맞춥니다. TCP 가 이렇게 합니다 왕복이 한 번 더 들어 그만큼 지연이 늘어납니다
미리 여벌을 보낸다 원래 데이터에 복구용 조각을 얹어 보내, 일부가 빠져도 받는 쪽이 되살립니다 잃지 않아도 늘 여벌만큼 더 보내야 합니다
그냥 넘어간다 빠진 토막을 건너뛰고 다음 것을 씁니다. 음성 통화가 이렇게 합니다 그 토막의 내용은 영영 못 받습니다

둘째 길처럼 복구용 조각을 미리 얹어 두는 방식을 전방 오류 정정이라고 부릅니다. 다시 보내 달라고 요청할 틈이 없는 실시간 전달에서 씁니다.

손실 하나가 속도를 깎는다

손실의 대가는 잃은 데이터 자체보다 클 때가 많습니다. 보내는 쪽이 손실을 네트워크가 막혔다는 신호로 읽기 때문입니다.

혼잡 제어는 보내는 쪽이 네트워크 사정을 살펴 보내는 속도를 스스로 줄이는 일입니다. 오래 쓰인 방식은 손실을 혼잡의 증거로 삼습니다. 패킷 하나가 사라지면 보내는 쪽은 한 번에 내보내는 양을 크게 줄이고 그 뒤로 조금씩 다시 올립니다.

그래서 무선 구간처럼 혼잡이 아닌 까닭으로 손실이 잦은 네트워크에서는 보내는 쪽이 헛되이 속도를 줄입니다. 네트워크는 한가한데 잡음 때문에 버려진 것을 막혔다는 증거로 읽는 것입니다.

대가가 하나 더 있습니다. 순서를 맞춰 주는 프로토콜에서는 앞 패킷이 빠지면 뒤에 도착한 것들이 이미 와 있어도 프로그램에 안 넘어갑니다. 빠진 것이 다시 올 때까지 뒤가 전부 기다리는 이 현상을 헤드 오브 라인 블로킹이라고 부릅니다.

손실이 나도 되는 일과 안 되는 일

손실을 견디는 정도는 하는 일마다 다릅니다. 이 판단이 곧 어느 프로토콜을 쓸지의 판단이 됩니다.

하는 일 손실을 어떻게 다루나
파일 전송 · 결제 요청 한 덩이도 빠지면 안 됩니다. 다시 보내 전부 채웁니다
음성 통화 · 화상 회의 한참 늦게 온 토막은 쓸모가 없습니다. 건너뛰고 다음으로 갑니다
게임의 위치 갱신 곧 새 위치가 옵니다. 지난 위치는 다시 안 받습니다
이름 질의 답이 안 오면 다시 묻습니다. 질문이 짧아 다시 묻는 값이 쌉니다

UDP(User Datagram Protocol, 사용자 데이터그램 프로토콜)는 손실을 가리지 않고 프로그램에 넘깁니다. 빠진 덩이는 그냥 안 옵니다. 대신 프로그램이 무엇을 되찾고 무엇을 버릴지 직접 고를 수 있습니다.

TCP 는 반대로 손실을 프로그램에서 가려 줍니다. 프로그램은 빠짐없는 데이터를 순서대로 받습니다. 가려 준 대가가 앞에서 본 기다림과 속도 낮춤입니다.

손실을 0으로 만드는 것은 목표가 아닙니다. 버려도 되게 둔 것이 이 네트워크의 설계이고, 정할 것은 얼마를 견딜지와 잃은 것을 누가 챙길지입니다.

관련 항목

패킷이 버려지는 까닭

혼잡 · 혼잡 붕괴 · 버퍼 블로트 · 비트 오류 · TTL · 블랙홀 라우터 · PMTU 블랙홀 · MTU

손실과 나란히 나타나는 전달 오류

지연 · 지터 · 순서 뒤바뀜 · 중복 수신 · 헤드 오브 라인 블로킹

손실을 알아채는 신호와 도구

확인 응답 · 중복 확인 응답 · 타임아웃 · ping · 패킷 캡처 · ICMP · ECN

손실에 대응하는 프로토콜의 장치

재전송 · 선택적 확인 응답 · 전방 오류 정정 · 혼잡 제어 · 흐름 제어 · 혼잡 윈도

손실을 겪는 전달 단위와 설계 원칙

패킷 · 데이터그램 · 프레임 · 세그먼트 · 최선형 전달 · 종단 간 원칙

손실을 서로 다르게 다루는 프로토콜

TCP · UDP · QUIC · RTP · HTTP-3 · SCTP

손실이 일어나는 네트워크 장비와 그 안의 공간

라우터 · 스위치 · 대기열 · 방화벽 · 소켓 · 능동 대기열 관리

손실을 재는 지표

패킷 손실률 · 처리량 · 왕복 시간 · 대역폭

다른 이름: packet loss · 패킷 유실 · 패킷 드롭