[JAVA] NIO vs IO의 차이점

1 분 소요

회사에서 사용하는 기술 스택 중 Webflux가 존재하는데..

기본적으로, Webflux에 대해서 공부하고 물어물어 업무적인 개발은 하고 있었지만,,

그 정도로는 내 개인적인 궁금함이 풀리지 않는게 많았다.

좀 깊게 Webflux를 공부하려 하니..

Netty에 대해서 먼저 알아야 할 것 같았고 Netty를 찾아보는데..

Netty는 또, NIO로 구성되어있어 NIO부터 공부를 하게 되었다.

그래서 정리해보는 NIO와 IO의 차이를 쉽게 정리해보자!

물론, 기준은 내가 봤을 때 영상에서 배웠던 내용이 싹 다시 떠올리게 하는 게 목적이다.

참고한 영상의 링크

NIO와 IO의 차이

  • IO
    • 스트림: 데이터 전송이 단방향 이동이다. (그래서 통신 시 읽기 / 쓰기 두 개의 스트림이 필요하다)
    • 기본적으로는 버퍼를 사용하지 않는다. (성능 향상을 위해 보조스트림을 사용. 버퍼를 사용하기는 한다.)
    • 동기적인 작업만 지원한다.
    • 블로킹이다.
  • NIO (New Input / Output의 약자)
    • 채널: 데이터의 이동이 양방향이다.
    • 버퍼 사용이 기본이다. 즉, 버퍼에다가 쓰거나 읽는 방식으로 통신한다.
    • 동기와 비동기 방식 모두 지원한다.
    • 블로킹 과 논블로킹 모두 지원하는데.. 블로킹의 경우, IO 방식이 조금 다르다.

동작 구조

  • IO
    • 위에서 말했듯 2개의 스트림을 생성해야 읽고 쓸 수 있다.
    • 1byte씩 읽고 출력하기에 느리다.
    • 성능 향상을 위해 BufferedInputStream / BufferedOutputStream / BufferReader / BufferWriter 등 보조 스트림을 사용한다. (즉, 버퍼 이용한다.)
    • 입력 스트림으로 넣은 데이터는 버려지기 때문에 재사용이 불가능하다. 재사용하고 싶으면 어디에 저장해놔야한다.
  • NIO
    • 버퍼에 넣고 읽는다.
    • 버퍼에 한번에 넣어서 처리하니까 성능이 좋다.
    • 읽은 데이터는 버퍼에 저장되어 있으니, 필요한 부분만 읽을 수도 있고, 재사용도 가능하다.

블로킹

  • IO
    • read() write() 함수 모두 데이터가 올 때까지 / 모든 쓰기 활동이 완료 될 때까지 대기한다.
      • 즉, 쓰레드가 블로킹되고, interrupt가 불가능하다.
    • 유일하게 나오는 방법은 스트림을 닫는 것이다.
  • NIO
    • 블로킹이라도, interrupt를 통해 쓰레드가 대기에서 나오는 게 가능하다.
    • 논블로킹 시에는, 입출력 작업에서 쓰레드가 블록되지 않는다.

그럼 뭘 쓰는게 좋을까?

내용만 보면 NIO가 무조건 좋아 보인다.

하지만, 무조건이라는 건 당연히 없다..

IO의 경우,

  1. 연결되는 client 수가 적고,
  2. 대용량이며
  3. 순차 처리가 필수적인 경우

에 좋다.

왜냐하면, 순차 처리 및 대용량을 데이터 전송할 경우, 버퍼의 크기가 점점 커져야 하는데,

버퍼의 크기를 무한정 키우는 게 불가능하기 때문이다.

NIO는 언제 쓰는 게 좋을까?

  1. 연결 client 수가 많고
  2. 전송 데이터가 적으며
  3. 입출력 작업처리가 빨리 끝나는 경우

에 효율적이다.

왜냐하면, NIO는 thread pool을 반드시 사용해야 하는데,

thread pool에서는 하나의 thread가 작업을 오래하면 다른 작업이 불가능하기 때문이다.

댓글남기기