기본 콘텐츠로 건너뛰기

라벨이 transferTo인 게시물 표시

자바에서 Zero Copy를 이용한 데이터 전송

리눅스나 유닉스에서 I/O 성능을 높이기 위해 sendfile () 시스템 호출을 이용해 "Zero Copy"기술을 사용한다. 자바에서는 어떻게 I/O 성능을 높이는가에 관한 글요약. 2008년에 쓰인 글이며 지금은 대중화 된 방법이다. 원문링크 웹 서버가 정적인 파일을 디스크에서 읽어서 소켓에 쓸때 커널 영역과 어플리케이션 영역간에 데이터 복사와 컨텍스트 전환으로 발생되는 비효율은 Zero Copy로 효율적인 처리를 할 수 있다. Zero Copy는 디스크에서 소켓으로 데이터를 복사할 때 커널레벨에서 데이터를 복사하는 방식으로 CPU 사용율과 메모리 대역폭 사용도 줄이고 커널 모드와 사용자 모드간 컨텍스트 전환 비용도 줄일 수 있기 때문에 성능이 좋아진다. 자바는 java.nio.channels.FileChannel.transferTo() 메소드를 통해 Zero Copy를 제공 한다. 데이터를 전송하는 일반적인 방법 파일에서 데이터를 읽고 소켓에 쓰기까지는 사용자 모드와 커널 모드간 4번의 컨텍스트 전환이 일어난다. 그리고 데이터 복사도 4번 일어난다. read() 호출은 사용자 모드에서 커널 모드로 컨텍스환트를 전환 하고, DMA( Direct Memorry Access) 엔진이 디스크에서 파일을 읽어 커널 영역 버퍼에 데이터를 저장한다. 이때  첫번째 복사가 생긴다. 요청된 양만큼 읽기 버퍼에서 사용자 버퍼로 데이터가 복사되고, read() 호출은 읽은 데이터를 반환한다. 이때 또 한번 컨텍스트 전환이 생기며 데이터는 사용자 영역 버퍼에 저장된다. 두번째 복사. 다시 send() 소켓 호출은 사용자 모드에서 커널 모드로 컨텍스트를 전환시키고, 커널 영역 버퍼로 데이터를 복사하는 세번째 복사가 생긴다. 완료된 send() 시스템 호출은 값을 반환하고 네번째 컨텍스트 전환이 생긴다. 그리고 DMA 엔진이 커널 영역 버퍼에서 프로토콜 엔진으로 데이터를 복사한다. 네번째 복사. 사용자 버퍼에 바로 ...