제로 카피란?
2018년 10월 14일
일반적으로 클라가 서버에게 정적 파일을 요청할 때 서버에서는 다음과 같은 프로세스를 탄다.
- 디스크에서 정적 파일 요청 (App -> Kernel)
컨텍스트 스위칭: 1회
데이터 복사: 0회 - 원본 데이터를 복사함. (Kernel)
원본 파일을 커널의 ReadBuffer에 복사
컨텍스트 스위칭: 1회
데이터 복사: 1회 - 복사한 파일 데이터 반환 (Kernel -> App)
ReadBuffer에 있는 데이터를 Application의 ReadBuffer에 복사
컨텍스트 스위칭: 2회
데이터 복사: 2회 - 반환된 데이터를 소켓에 담게 끔 요청 (App -> Kernel)
Application의 ReadBuffer에 있는 데이터를 커널의 SocketBuffer에 복사
컨텍스트 스위칭: 3회
데이터 복사: 3회 - 소켓에 데이터를 담아서 클라에게 응답 (Kernel)
커널의 SocketBuffer에 있는 데이터를 커널의 NIC Buffer(Network Interface Card)에 복사
컨텍스트 스위칭: 3회
데이터 복사: 4회 - 다시 제어권을 Application으로 전환
컨텍스트 스위칭: 4회
데이터 복사: 4회
아래 두 권한은 일반적인 어플리케이션의 권한이 아닌 운영체제(커널 단)의 권한 같다.
- 디스크에서 파일을 읽어오는 권한
- 소켓에 데이터를 담아서 전송하는 권한
컨텍스트 스위칭 및 데이터 복사로 인해 오버헤드가 많다.
제로카피를 쓰면 아래와 같이 줄일 수 있다.
- 디스크에서 정적 파일 요청 (App -> Kernel)
컨텍스트 스위칭: 1회
데이터 복사: 0회 - 원본 데이터를 복사함. (Kernel)
원본 파일을 커널의 ReadBuffer에 복사
컨텍스트 스위칭: 1회
데이터 복사: 1회 - 복사한 파일 데이터를 소켓에 담음. (Kernel)
ReadBuffer에 있는 데이터를 SocketBuffer에 복사
컨텍스트 스위칭: 1회
데이터 복사: 2회 - 소켓에 데이터를 담아서 클라에게 응답 (Kernel)
커널의 SocketBuffer에 있는 데이터를 커널의 NIC Buffer(Network Interface Card)에 복사
컨텍스트 스위칭: 1회
데이터 복사: 3회 - 다시 제어권을 Application으로 전환
컨텍스트 스위칭: 2회
데이터 복사: 3회
컨텍스트 스위칭을 1회 줄이고, 데이터 복사도 1회 줄였다.
물론 커널이 업데이트 되면서(리눅스 커널 2.4 이후 커널 파일 디스크립터가 수정되어 네트워크 카드가 gather operation을 지원하면 커널이 중복으로 데이터를 처리하는 것을 줄일 수 있다
고 한다.) 아래와 같이 더 개선되었다고 한다.
- 디스크에서 정적 파일 요청 (App -> Kernel)
컨텍스트 스위칭: 1회
데이터 복사: 0회 - 원본 데이터 복사. (Kernel)
원본 파일을 커널의 ReadBuffer에 복사
컨텍스트 스위칭: 1회
데이터 복사: 1회 - 소켓에 데이터를 담아서 클라에게 응답 (Kernel)
커널의 ReadBuffer에 있는 데이터를 커널의 NIC Buffer(Network Interface Card)에 복사
컨텍스트 스위칭: 1회
데이터 복사: 2회 - 다시 제어권을 Application으로 전환
컨텍스트 스위칭: 2회
데이터 복사: 2회
뭐 완전 제로 카피는 아니지만… 언젠가는 제로 카피…처럼 동작하는 날이 오길 바라며 이름을 그렇게 지은 게 아닐까…
카프카에서 이런 제로 카피 기술을 사용해서 성능을 높였다고 한다!