[Java & Network] 논블럭(Non Block I/O)개요와 자바 NIO 패키지

NIO(Nonblock Input/Output) 개요


일반적으로 네트워크의 속도는 컴퓨터의 CPU, 메모리, 심지어 디스크의 속도와 비교해도 매우 느리다. 이러한 상황에서 나오는 현상중 상대적으로 느린 네트워크를 엄청나게 빠른 CPU가 기다리는 것이다. 

CPU가 느린 네트워크를 기다리지 않고 네트워크보다 앞서 달리게 하기 위한 전통적인 자바의 해결 방안은 버퍼링과 멀티스레드를 결합하는 것이다. 다수의 스레드가 동시에 다수의 서로 다른 연결을 통해 보낼 데이터를 생성한다. 그리고 네트워크가 데이터를 보낼 준비가 될 때까지 해당 데이터들을 버퍼에 저장해 둔다. 

그러나 멀티 스레드를 생성할 때 드는 오버헤드와 스레드 전환 시 발생하는 오버헤드를 무시할 수 없다. 그리고 각각의 스레드는 약 1메가 바이트의 메모리리를 여분으로 필요로 한다. 초당 수천 개의 요청을 처리하는 대규모 서버 환경에서는 스레드가 사용하는 여분의 메모리와 다양한 오버헤드로 인해 연결마다 스레드를 할당하는 것이 쉽지 않다. 그래서 하나의 스레드가 다수의 연결을 담당하고, 데이터를 수신할 준비가 된 연결을 골라내서 처리하고, 그리고 다시 준비된 다음 연결을 골라내는 방법을 반복한다면 훨씬 더 빠를 것이다. 이러한 기능을 java.nio 패키지 에서 제공한다.


java.nio(New Input/Output) 패키지







IO와 NIO의 차이점


IO는 입력 스트림과 출력 스트림이 구분 되어 입/출력 별도의 생성이 필요하다.  또 동기(synchronous) 방식이기 때문에 입력과 출력이 다 될때까지 스레드는 멈춰 있어야 한다. 이것을 블로킹이라고 하는데 interrupt로 블로킹(Blocking)을 빠져 나올 수 없다. 블로킹을 빠져 나오는 유일한 방법은 스트림을 닫는 것이다. 반면 NIO는 양방향 입출력이 가능하므로 하나만 생성하면 된다. 또 NIO는 블로킹(Blocking)과 넌블로킹(Non-Blocking)을 지원하는데 넌블로킹 방식으로 입출력 작업시 스레드가 블로킹 되지 않는다. 또 NIO 블로킹은 스레드 interrupt로 인해 빠져 나오는 것이 가능하다.








NIO 패키지 핵심개념


1. 채널(Channel)

- 채널은 파일, 소켓, 데이터그램 등과 같은 다양한 I/O 소스로부터 데이터 블록을 버퍼로 쓰거나 읽어 온다. 

- 비동기 읽기/쓰기를 지원하는 스트림과 같은 기술이다.


2. 버퍼(Buffer)

- nio(new input/output) 에서는 모든 I/O가 버퍼링된다. 게다가 버퍼는 새로운 I/O API의 기초를 이루고 있다.

- 데이터를 입출력 스트림으로 쓰거나 읽지 않고 대신 버퍼에 일시적으로 저장하여 쓰고 읽는다. 

- 채널과 함께 동작한다.


3. 셀렉터(Selector)

- 싱글 스레드에서 다중채널을 처리 하기 위한 기술이다. 즉 준비된 채널을 선택함으로써 읽고 쓸 때 블록하지 않아도 된다.

- 애플리케이션에서 싱글 스레드로 low-traffic 연결을 처리하는 경우 유용하다.




앨리엇 러스트 해럴드, Java Network Programming, 제이펍

최수경 교수님, 네트워크 프로그래밍, 삼육대학교 강의(2018) 

댓글

Designed by JB FACTORY