[JAVA] NIO vs IO의 차이점
회사에서 사용하는 기술 스택 중 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가 불가능하다.
- 유일하게 나오는 방법은 스트림을 닫는 것이다.
- read() write() 함수 모두 데이터가 올 때까지 / 모든 쓰기 활동이 완료 될 때까지 대기한다.
- NIO
- 블로킹이라도, interrupt를 통해 쓰레드가 대기에서 나오는 게 가능하다.
- 논블로킹 시에는, 입출력 작업에서 쓰레드가 블록되지 않는다.
그럼 뭘 쓰는게 좋을까?
내용만 보면 NIO가 무조건 좋아 보인다.
하지만, 무조건이라는 건 당연히 없다..
IO의 경우,
- 연결되는 client 수가 적고,
- 대용량이며
- 순차 처리가 필수적인 경우
에 좋다.
왜냐하면, 순차 처리 및 대용량을 데이터 전송할 경우, 버퍼의 크기가 점점 커져야 하는데,
버퍼의 크기를 무한정 키우는 게 불가능하기 때문이다.
NIO는 언제 쓰는 게 좋을까?
- 연결 client 수가 많고
- 전송 데이터가 적으며
- 입출력 작업처리가 빨리 끝나는 경우
에 효율적이다.
왜냐하면, NIO는 thread pool을 반드시 사용해야 하는데,
thread pool에서는 하나의 thread가 작업을 오래하면 다른 작업이 불가능하기 때문이다.
댓글남기기