제로 카피(Zero-Copy)는 데이터를 CPU를 통한 복사 없이 직접 전송하는 기법이다. 전통적인 read-write 방식은 커널 버퍼와 사용자 버퍼 간 불필요한 복사가 발생하는데, 제로 카피로 이를 제거해 성능을 향상시킨다.
전통적 방식 vs 제로 카피
[전통 방식] 파일 → 네트워크 전송:
1. read(): 디스크 → 커널 버퍼 (DMA)
2. read(): 커널 버퍼 → 사용자 버퍼 (CPU 복사)
3. send(): 사용자 버퍼 → 소켓 버퍼 (CPU 복사)
4. send(): 소켓 버퍼 → NIC (DMA)
총 2번의 CPU 복사 + 4번의 컨텍스트 스위치
[sendfile() 제로 카피]:
1. 디스크 → 커널 버퍼 (DMA)
2. 커널 버퍼 → NIC (DMA, CPU 복사 없음)
총 0번의 CPU 복사 + 2번의 컨텍스트 스위치
Linux 제로 카피 API
c
// sendfile: 파일을 소켓으로 직접 전송
# include <sys/sendfile.h>
ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
// splice: 두 파일 디스크립터 간 파이프를 통한 전송
# include <fcntl.h>
ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out,
size_t len, unsigned int flags);
// mmap: 파일을 가상 주소에 직접 매핑
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
활용
- •Nginx 정적 파일 서빙 (sendfile on)
- •Kafka 메시지 전송
- •고성능 네트워크 서버
관련 개념