극단적인 경우로 CPU 바운드 벤치마크에서 < 1Gbit/s에서 4 Gbit/s로 향상됨. CPU flamegraph상 대부분의 시간은 I/O 시스템 콜과 암호화 코드에서 소모됨
네트워크 처리량이 400% 증가했다는 점은 UDP 네트워크 트래픽에서 CPU 사용량이 크게 줄어듦을 의미함
이는 특히 모바일 및 노트북 등 휴대용 클라이언트에서 전력 효율 향상 측면에서도 인상적인 부분임
이런 전환이 항상 좋은 것으로 받아들여지는 분위기가 있지만, 이 글은 실제 데이터를 통해 입증해서 신선하게 느껴짐
언젠가 유저와 시스템 프로그램 간의 컨텍스트를 넘나드는 메시지 패싱이 하드웨어 가속으로 돌아가는 날이 올지 궁금함
여기서 나온 개선은 실제 초고속(100Gb/s 이상)을 위해 필수이긴 하지만, 4Gb/s는 사실 별로 빠르지 않은 속도임
500MB/s라 이건 뭔가 심각하게 느린 병목 지점이 있다는 의미임
커널 컨텍스트 스위치가 1us대라는데 사실 시스템 콜 치고는 높은 편임
하지만 패킷당 평균 약 500바이트만 되도 500MB/s, 즉 4Gb/s 달성 가능함
예전 1Gb/s는 패킷 크기가 더 작았을 때였고, UDP 패킷을 단순히 NIC 버퍼에 밀어넣는 건 메모리 복사 속도로도 충분히 가능한 수준임
암호화가 느리다 해도 실제론 그렇지 않음
예를 들어 Intel i5-6500이 1729MB/s AES-128 GCM 속도를 낸 바 있음
지금 CPU는 코어당 3-5GB/s, 즉 25-40Gb/s도 가능한데 여기서 말한 4Gb/s는 너무 낮은 수치임
(AES-128 GCM 성능 참고 링크)
시스템 콜 대기 시간이 높다 했는데, 그 원인은 spectre & meltdown 대응 조치 때문일 수 있음
TCP는 경로 바인딩이 있지만 UDP에는 없어 경로 설정에 차이가 큼
암호화가 느리다는 건, 작은 PDU(프로토콜 데이터 단위)에서는 맞는 말임
대부분이 대용량 TCP 프레임 기준으로 최적화 및 벤치마킹되어 실제로는 작은 패킷에서 상태 설정 비용이 두드러짐
tight loop에서 마이크로벤치마크 돌리면 수치가 잘 나오지만, 실제 랜덤성 있는 환경에서는 캐시 활용 효율도 낮아지고, 1KB 이하 패킷은 효율이 뚝 떨어짐
여기에 추가적인 프레이밍 오버헤드, 바깥 밴드 데이터 유효성 검사 등 꽤 비싸게 작동함
UDP 버퍼 메모리도 기본 값이 부족해 실사용엔 문제가 많음
TCP 운영하며 버퍼 크기 계속 키웠지만 UDP는 90~00년대 보수적인 값에 머물러 있음
진짜 필요한 API는, fd 포크해서 connect(2) 및 라우트 바인딩 완전 지원, 이후 submission queue 기반(uring, rio 등) 이어야 함
암호화 측면에서, KDF 접근 방식이 상태 비용을 많이 줄일 수 있음
PSP 방식은 일부 벤더가 인정하지만 IETF 등에서 많이 거부당해서 널리 퍼지지 않음
벤더들의 대규모 동시성 테스트에선 기존 TLS류보다 월등히 높은 스케일링 수치 나옴
벤치마크한 CPU가 어떤 등급인지는 전혀 언급 안 됨
그리고 암호화 오버헤드는 QUIC 프로토콜 자체 처리 비용임
QUIC은 암호화 오프로드(하드웨어 처리)가 TCP 대비 미흡한데, TCP는 kTLS 오프로드로 어느 정도 NIC 처리 가능함
이런 기술 콘텐츠 정말 만족스러웠음
Mozilla의 모든 기술 자료가 이렇게 실무 엔지니어가 제대로 작성한 깊이 있는 내용이었으면 좋겠음
낙관론(alegria) 따위 없이, 읽을 가치가 높음
왜 Android 5를 아직도 지원하는지 모르겠음
출시된 지 10년이 넘었고, 그 기기를 쓰는 유저는 더 오래된 레거시임
요즘 웹은 너무 무거워서 이런 구형 기기로는 제대로 브라우징하기조차 힘들 텐데 굳이 지원하는 이유가 궁금함
아마 옛날 OnePlus 같은 기기를 보수해서 충전기 꼽아두고 LineageOS 같은 국민 롬도 안 올리고 대체 앱스토어에서 파이어폭스 써보는 해커들 정도임
현실적으로는 전체 개발 속도를 늦추는 비용임
이슈 리포터(마찬가지로 Mozilla 직원)와 수많은 시간을 왔다 갔다 하다가, 결국 문제 재현을 위해 노트북까지 똑같은 모델, 색상으로 사서 테스트했다는 부분
네트워크 재현의 미친 현실을 XKCD 2259 에서처럼 보여줘서 재밌었음
(xkcd 만화 링크)
"The map download struggle"라는 Factorio 개발 블로그에도 이와 관련된 흥미로운 에피소드가 있으니 추천함
(관련 블로그 글)
실제로 네트워크 문제 다뤄 본 사람이라면 미스터리한 패킷 런트(mystery packet runts) 때문에 더 공감할 내용임
대부분의 네트워크 장비들이 이런 패킷 처리 잘 못함
UDP나 QUIC 기반 트래픽은 일정한 수준 이상의 대형 클라우드 환경이 아니면 쉽게 공격에 휘둘림
이 때문에 소규모 혹은 자체 운영하는 호스팅 업체는 점점 운영이 어려워지고, 대형 트래픽 처리 역량이 있는 곳만 남게 됨
그래서 대부분의 LAN 환경에선 UDP 트래픽 대부분을 드롭하고 필요한 부분만 레이트 리밋해서 처리 중임
모질라 버그 트래커
macOS와 Fedora에서 Cloudflare가 호스팅하는 사이트를 Firefox로 접속 시 여전히 같은 현상을 겪고 있음
Windows와 MacOS에도 GSO/GRO(대용량 네트워크 패킷 처리) 유사 기능이 있다는 사실을 이번에 알게 됐음
다만 실제론 버그가 많다니 아쉬움
Microsoft와 Apple이 왜 자기네 네트워크 스택 품질에 좀 더 신경을 안 쓰는지 의문임
GSO/GRO만 버그가 있는 게 아닐 거라는 생각도 듦
UDP GSO/GRO가 구조적으로 어떻게 동작하는지 설명 가능한 사람 있냐는 질문임
UDP는 순서가 없는 패킷인데, QUIC 한 패킷이 여러 UDP 패킷으로 쪼개질 때 헤더에 시퀀스 정보도 없는데 수신 측에서 어떻게 순서 맞춰 합치는지 궁금함
내가 파악한 바로는, 애플리케이션 레벨에서는 GRO가 활성화돼 있어도 사실상 합쳐진 UDP 데이터그램을 받는 일이 없음
커널이 여러 데이터그램을 하나의 구조체에 담아서, 각 계층끼리 경계(예, sk_buff 내 data fragments)를 유지한 채로 넘기는 개념임
정확한 전문가는 아니지만 이 방식이 어떻게 동작하는지 찾아보다가 이 글을 참고하게 됨
"우리는 Quinn 프로젝트의 UDP I/O 라이브러리인 quinn-udp 위에서 개발을 시작했으며 이 덕에 개발 속도가 훨씬 빨라졌다"고 언급했는데
그럼 혹시 Quinn 프로젝트에 후원을 진행했는지 궁금함
(Quinn 후원 링크)
재정 지원 관련해서 직접 물어봤더니, Mozilla의 Senior Principal Software Engineer가 "Mozilla는 돈이 없어요"라고 답변해줬음
다만 코드는 엄청나게 많이 기여해줘서 정말 감사하게 생각하고 있음
(나는 Quinn 메인테이너임)
"후원했나요?"라는 질문에, 굳이 오픈소스 후원 안 해도 CEO 연봉에 수백만 달러 더 쓰는 게 Mozilla의 방식이라는 의견 제시함
플래그십 제품(Firefox)까지도 무너져가는데 말임
코드 등 다른 방식으로 기여한 점이 있다면 궁금함
sendmmsg/recvmmsg가 “최신”이라 불린다는 게 놀라움
사실 꽤 오랜 시간 존재한 시스템 콜임
Linux 관련 내용에서 io_uring도 언급될 줄 알았는데 없어서 아쉬움
io_uring은 여러 UDP 다이어그램을 한 번에 처리하는 진짜 의미의 배치 기능이 없음
최선을 다해도 sendmsg, recvmsg 여러 개를 한 번에 요청하는 것 정도임
GSO/GRO가 정답임
sendmmsg/recvmmsg는 이미 매우 오래된 기술이며, 커널 개발자들 중엔 이제 없애고 싶다는 사람도 있음
(관련 GitHub 토론)
Hacker News 의견
글의 핵심은 중간에 숨어 있음
여기서 나온 개선은 실제 초고속(100Gb/s 이상)을 위해 필수이긴 하지만, 4Gb/s는 사실 별로 빠르지 않은 속도임
500MB/s라 이건 뭔가 심각하게 느린 병목 지점이 있다는 의미임
커널 컨텍스트 스위치가 1us대라는데 사실 시스템 콜 치고는 높은 편임
하지만 패킷당 평균 약 500바이트만 되도 500MB/s, 즉 4Gb/s 달성 가능함
예전 1Gb/s는 패킷 크기가 더 작았을 때였고, UDP 패킷을 단순히 NIC 버퍼에 밀어넣는 건 메모리 복사 속도로도 충분히 가능한 수준임
암호화가 느리다 해도 실제론 그렇지 않음
예를 들어 Intel i5-6500이 1729MB/s AES-128 GCM 속도를 낸 바 있음
지금 CPU는 코어당 3-5GB/s, 즉 25-40Gb/s도 가능한데 여기서 말한 4Gb/s는 너무 낮은 수치임
(AES-128 GCM 성능 참고 링크)
시스템 콜 대기 시간이 높다 했는데, 그 원인은 spectre & meltdown 대응 조치 때문일 수 있음
TCP는 경로 바인딩이 있지만 UDP에는 없어 경로 설정에 차이가 큼
암호화가 느리다는 건, 작은 PDU(프로토콜 데이터 단위)에서는 맞는 말임
대부분이 대용량 TCP 프레임 기준으로 최적화 및 벤치마킹되어 실제로는 작은 패킷에서 상태 설정 비용이 두드러짐
tight loop에서 마이크로벤치마크 돌리면 수치가 잘 나오지만, 실제 랜덤성 있는 환경에서는 캐시 활용 효율도 낮아지고, 1KB 이하 패킷은 효율이 뚝 떨어짐
여기에 추가적인 프레이밍 오버헤드, 바깥 밴드 데이터 유효성 검사 등 꽤 비싸게 작동함
UDP 버퍼 메모리도 기본 값이 부족해 실사용엔 문제가 많음
TCP 운영하며 버퍼 크기 계속 키웠지만 UDP는 90~00년대 보수적인 값에 머물러 있음
진짜 필요한 API는, fd 포크해서 connect(2) 및 라우트 바인딩 완전 지원, 이후 submission queue 기반(uring, rio 등) 이어야 함
암호화 측면에서, KDF 접근 방식이 상태 비용을 많이 줄일 수 있음
PSP 방식은 일부 벤더가 인정하지만 IETF 등에서 많이 거부당해서 널리 퍼지지 않음
벤더들의 대규모 동시성 테스트에선 기존 TLS류보다 월등히 높은 스케일링 수치 나옴
벤치마크한 CPU가 어떤 등급인지는 전혀 언급 안 됨
그리고 암호화 오버헤드는 QUIC 프로토콜 자체 처리 비용임
QUIC은 암호화 오프로드(하드웨어 처리)가 TCP 대비 미흡한데, TCP는 kTLS 오프로드로 어느 정도 NIC 처리 가능함
이런 기술 콘텐츠 정말 만족스러웠음
Mozilla의 모든 기술 자료가 이렇게 실무 엔지니어가 제대로 작성한 깊이 있는 내용이었으면 좋겠음
낙관론(alegria) 따위 없이, 읽을 가치가 높음
왜 Android 5를 아직도 지원하는지 모르겠음
출시된 지 10년이 넘었고, 그 기기를 쓰는 유저는 더 오래된 레거시임
요즘 웹은 너무 무거워서 이런 구형 기기로는 제대로 브라우징하기조차 힘들 텐데 굳이 지원하는 이유가 궁금함
아마 옛날 OnePlus 같은 기기를 보수해서 충전기 꼽아두고 LineageOS 같은 국민 롬도 안 올리고 대체 앱스토어에서 파이어폭스 써보는 해커들 정도임
현실적으로는 전체 개발 속도를 늦추는 비용임
"The map download struggle"라는 Factorio 개발 블로그에도 이와 관련된 흥미로운 에피소드가 있으니 추천함
(관련 블로그 글)
실제로 네트워크 문제 다뤄 본 사람이라면 미스터리한 패킷 런트(mystery packet runts) 때문에 더 공감할 내용임
대부분의 네트워크 장비들이 이런 패킷 처리 잘 못함
UDP나 QUIC 기반 트래픽은 일정한 수준 이상의 대형 클라우드 환경이 아니면 쉽게 공격에 휘둘림
이 때문에 소규모 혹은 자체 운영하는 호스팅 업체는 점점 운영이 어려워지고, 대형 트래픽 처리 역량이 있는 곳만 남게 됨
그래서 대부분의 LAN 환경에선 UDP 트래픽 대부분을 드롭하고 필요한 부분만 레이트 리밋해서 처리 중임
모질라 버그 트래커
macOS와 Fedora에서 Cloudflare가 호스팅하는 사이트를 Firefox로 접속 시 여전히 같은 현상을 겪고 있음
Windows와 MacOS에도 GSO/GRO(대용량 네트워크 패킷 처리) 유사 기능이 있다는 사실을 이번에 알게 됐음
다만 실제론 버그가 많다니 아쉬움
GSO/GRO만 버그가 있는 게 아닐 거라는 생각도 듦
UDP GSO/GRO가 구조적으로 어떻게 동작하는지 설명 가능한 사람 있냐는 질문임
UDP는 순서가 없는 패킷인데, QUIC 한 패킷이 여러 UDP 패킷으로 쪼개질 때 헤더에 시퀀스 정보도 없는데 수신 측에서 어떻게 순서 맞춰 합치는지 궁금함
커널이 여러 데이터그램을 하나의 구조체에 담아서, 각 계층끼리 경계(예, sk_buff 내 data fragments)를 유지한 채로 넘기는 개념임
정확한 전문가는 아니지만 이 방식이 어떻게 동작하는지 찾아보다가 이 글을 참고하게 됨
"우리는 Quinn 프로젝트의 UDP I/O 라이브러리인 quinn-udp 위에서 개발을 시작했으며 이 덕에 개발 속도가 훨씬 빨라졌다"고 언급했는데
그럼 혹시 Quinn 프로젝트에 후원을 진행했는지 궁금함
(Quinn 후원 링크)
재정 지원 관련해서 직접 물어봤더니, Mozilla의 Senior Principal Software Engineer가 "Mozilla는 돈이 없어요"라고 답변해줬음
다만 코드는 엄청나게 많이 기여해줘서 정말 감사하게 생각하고 있음
(나는 Quinn 메인테이너임)
"후원했나요?"라는 질문에, 굳이 오픈소스 후원 안 해도 CEO 연봉에 수백만 달러 더 쓰는 게 Mozilla의 방식이라는 의견 제시함
플래그십 제품(Firefox)까지도 무너져가는데 말임
코드 등 다른 방식으로 기여한 점이 있다면 궁금함
sendmmsg/recvmmsg가 “최신”이라 불린다는 게 놀라움
사실 꽤 오랜 시간 존재한 시스템 콜임
Linux 관련 내용에서 io_uring도 언급될 줄 알았는데 없어서 아쉬움
최선을 다해도 sendmsg, recvmsg 여러 개를 한 번에 요청하는 것 정도임
GSO/GRO가 정답임
sendmmsg/recvmmsg는 이미 매우 오래된 기술이며, 커널 개발자들 중엔 이제 없애고 싶다는 사람도 있음
(관련 GitHub 토론)