제로카피(Zero-copy) 기술로 본 Go의 sendfile·splice·io.Copy 성능 비교

Go 언어에서 파일 전송 시 sendfile(2) 시스템 콜을 활용하면 사용자 공간 복사 없이 커널 내에서 직접 데이터를 전송해 성능이 크게 향상된다. io.Copy는 os.File을 감지하면 자동으로 sendfile 경로를 사용하지만, io.Reader로 래핑하면 이 최적화가 비활성화되어 CPU 사용량이 증가하고 처리량이 감소한다. 512MiB 파일 테스트에서 raw os.File 사용 시 가장 높은 성능을 보였다.

AI 요약

Go 언어에서 파일을 TCP 소켓으로 전송할 때 io.Copy*os.File을 직접 전달하면 내부적으로 sendfile(2) 시스템 콜을 사용해 제로카피 전송이 가능하다. 그러나 파일을 io.Reader로 감싸는 사소한 변경만으로도 이 최적화 경로가 비활성화되어 CPU 사용량이 2배 증가하고 처리량이 절반으로 감소할 수 있다. Go 런타임은 *net.TCPConnReadFrom 메서드에서 소스가 *os.File인지 타입 단언으로 확인한 후 sendfile 루프를 실행한다. *io.LimitedReader는 유일하게 런타임이 감지하는 래퍼로, 이를 통한 제한된 파일 전송도 제로카피가 가능하다.

핵심 포인트

  • sendfile(2)는 디스크→페이지 캐시→소켓 버퍼로의 2회 복사를 1회 커널 내 전송으로 줄임
  • Go의 io.Copy(conn, f)*os.File을 감지해 자동으로 sendfile 사용
  • io.Reader로 래핑하면 제로카피 경로가 비활성화되어 CPU 2배, 처리량 절반으로 저하
  • *io.LimitedReader는 유일하게 런타임이 감지하는 래퍼로 제로카피 유지 가능

향후 전망

  • Go 표준 라이브러리의 제로카피 감지 로직이 더 다양한 래퍼 패턴을 지원하도록 확장될 가능성
  • 고성능 네트워크 서비스 개발 시 io.Copy 사용 패턴에 대한 주의 필요성 증가
Share

이것도 읽어보세요

댓글

이 소식에 대한 의견을 자유롭게 남겨주세요.

댓글 (0)

불러오는 중...