Netty는 Java 언어로 작성된 고성능 네트워크 통신 프레임워크입니다. Zero Copy는 이 프레임워크의 기능 중 하나입니다.
컴퓨터에서 데이터 전송을 완료하려면 일반적으로 두 단계가 필요합니다. 첫 번째 단계에서는 운영 체제가 로컬 하드 디스크나 네트워크 카드의 데이터를 커널 공간의 메모리로 복사하고, 두 번째 단계에서는 응용 프로그램이 시스템 커널 공간의 메모리에서 데이터를 커널 공간의 메모리로 복사합니다. 사용자 공간, 다음 단계는 데이터 처리 작업입니다.
먼저 몇 가지 명사를 살펴보겠습니다.
DMA(직접 메모리 액세스) 직접 메모리 액세스, 한 주소 공간에서 다른 주소 공간으로 데이터를 복사합니다. CPU가 전송 작업을 초기화하면 전송 작업 자체가 DMA 컨트롤러(DMAC)에 의해 완료됩니다. 이는 데이터 전송 중에 시스템이 다른 작업을 병렬로 수행할 수 있음을 의미합니다. CPU 복사는 CPU에서 직접 처리하는 데이터 전송입니다. 데이터 복사 중에 CPU 리소스가 항상 점유됩니다.
위 그림에서 볼 수 있듯이 기존 IO 읽기 및 쓰기 프로세스에는 사용자 모드 및 커널 모드 스위치 4개, 컨텍스트 스위치 4개, 데이터 복사본 4개, CPU 복사본 2개, 보조 DMA 복사본 2개가 포함됩니다.
1. 제로카피란 무엇인가요?
복사란 한 저장 영역에서 다른 저장 영역으로 데이터를 복사하는 것을 의미합니다. 0은 횟수가 0이고 복사 횟수가 0임을 의미합니다. 즉, 한 저장 영역에서 다른 저장 영역으로 데이터를 복사할 필요가 없다는 의미입니다.
2. 제로카피가 필요한 이유는 무엇인가요?
제로 복사는 시스템 커널 공간의 메모리에서 사용자 공간의 메모리로 복사하는 전통적인 데이터를 사용할 필요가 없음을 의미합니다. 대신 시스템 커널 공간의 메모리와 사용자 공간의 메모리가 매핑(mmap 메모리 매핑 메커니즘)과 연관되므로 데이터 전송 중에 복사할 필요가 없습니다.
mmap(메모리 맵) 메모리 매핑 메커니즘은 단순히 파일/장치를 메모리에 매핑합니다. 프로세스는 메모리를 읽고 쓰는 방식으로 mmap 파일에서 작동할 수 있습니다. 제로 복사는 복사가 전혀 없다는 의미는 아니지만 데이터 복사본 수를 줄입니다.
3. Netty에서 제로 카피의 세 가지 구현.
1. 직접 메모리(Direct Memory)라고도 하는 오프힙 메모리를 사용합니다. Netty는 수신 및 생성을 위해 시스템 하단의 mmap 메커니즘에 해당하는 Direct 버퍼를 사용합니다. 이는 바이트 버퍼의 보조 복사본이 필요 없이 소켓 읽기 및 쓰기를 위해 오프힙 메모리를 직접 사용합니다.
2. 여러 ByteBuffer 개체를 집계할 수 있는 결합된 버퍼 개체(CompositeByteBuf)를 제공합니다. 사용자는 메모리 복사를 통해 여러 버퍼를 병합하는 기존 방법을 피하면서 결합된 ByteBuffer를 하나의 ByteBuffer로 작동하기만 하면 됩니다. 큰 버퍼이므로 메모리 복사가 필요하지 않습니다.
3. 파일 전송에서는 파일 버퍼의 데이터를 대상 채널로 직접 보낼 수 있는 TransferTo 메서드를 사용하여 기존 순환 쓰기 방법으로 인해 발생하는 메모리 복사 문제를 방지합니다.
최종 요약
정리를 통해 netty의 zero copy는 전혀 복사를 하지 않는다는 의미가 아니라 CPU copy를 줄인다는 것을 알 수 있다. 시스템 커널 공간의 메모리를 사용자 공간으로 복사합니다. DMA 복사는 여전히 존재합니다. 결국 이는 운영 체제에 의해 수행되는 작업이므로 애플리케이션의 작업 범위에 속하지 않습니다. Netty에는 현재 제로 카피를 구현하는 세 가지 방법이 있습니다. 첫 번째는 오프힙 메모리를 사용합니다. 둘째, CompositeByteBuf는 버퍼 개체를 결합합니다.
셋째, 파일 전송은 TransferTo 메서드를 사용합니다.
참고 문서: /s/HvdiDbkMMMcGhee5Dhq_Jw