TIL(사전캠프)

리액티브. (2024-07-03)

note994 2024. 7. 3. 23:12

1. Blocking I/O

운영체제 측면에서의 I/O는 일반적으로 컴퓨터 시스템이 외부의 입출력 장치들과 데이터를 주고받는 것을 의미한다. I/O 작업의 대표적인 예로 디스크에 저장된 프로그램 실행파일을 읽어들여 메모리에 올리는 것을 들 수 있다.

 

웹 애플리케이션 측면에서 I/O는 파일에서 데이터를 읽어 들이거나 파일에 데이터를 기록하는 작업을 떠올릴 수 있다.

 

파일I/O 이외에 데이터베이스에서 데이터를 조회하거나 추가하는 작업 역시 I/O이며, 이를 DB I/O라고 한다.

 

그리고 웹 애플리케이션에서 다른 웹 애플리케이션으로 네트워크 통신을 한다면 네트워크I/O가 발생한다. 웹 애플리케이션의 I/O 유형 중에서 네트워크 I/O의 예를 통해 Blocking I/O를 이해해 보도록 한다.

그림3-1 Blocking I/O 예시

 

 

[그림3-1]은 Blocking I/O를 설명하기 위한 예시이다.

 

한 대의 클라이언트 PC와 도서 데이터를 제공하는 두 대의 API 서버가 있다고 가정한다.

 

클라이언트 PC에서 브라우저 등을 이용해 본사 API 서버에 도서 정보 조회를 위한 요청을 보내면 본사 API 서버는 클라이언트 PC의 요청에 맞는 도서 데이터를 제공한다.

 

본사 API 서버에서는 클라이언트 PC의 요청에 맞는 도서 정보를 제공하기 위해 지점 API 서버에 추가적인 요청을 보낸다

.

본사 API 서버에서 지점 API 서버로 요청을 보내는 그 시점에 본사 API 서버에서 실행된 스레드(요청 스레드)는 차단되어 지점 API 서버의 스레드(작업 스레드)가 처리를 끝내고 응답을 반환하기 전까지 대기하게 된다.

 

이렇게 하나의 스레드가 I/O에 의해서 차단되어 대기하는 것을 Blocking I/O라고 한다. 

 

Blocking I/O 방식의 문제점을 보완하기 위해 멀티스레딩 기법으로 추가 스레드를 할당하여 차단된 그 시간을 효율적으로 사용할 수는 있다. 하치만 이렇게 CPU 대비 많은 수의 스레드를 할당하는 멀티스레딩 기법은 몇 가지 문제점이 존재한다.

 

단점1. 컨텍스트 스위칭(Context Switching)으로 인한 스레드 전환 비용이 발생한다.

그림3-2 프로세스의 컨텍스트 스위칭

 

[그림3-2]는 프로세스의 컨텍스트 스위칭 과정을 그림으로 표현한 것이다.

 

프로세스는 쉽게 말해 워드나 노트패드, 뮤직 플레이어, 웹 브라우저 등과 같이 현재 실행 중인 프로그램을 의미한다.

 

예를 들어 우리가 컴퓨터를 이용해 뮤직플레이어로 음악을 들으면서 동시에 웹 브라우저를 실행하고 있다면 우리 눈에는 두 개의 프로그램이 동시에 실행되고 있는 것처럼 보이지만 실제로는 컴퓨터가 두 개의 프로그램을 번갈아 가면서 실행시켜 주는 것이다. 다만 너무 빠르기 때문에 동시에 실행되는 것처럼 보인다.

 

두 개의 프로그램이 번갈아 가며 실행되는 과정에서 기존에 실행되고 있는 프로세스의 정보를 PCB(Process Control Block)라는 공간에 저장하고, 다시 실행시켜야 할 프로세스 정보를 PCB로부터 불러오는 그 과정을 바로 컨텍스트 스위칭 이라고 한다.

 

그런데 왜 문제가 되는 것일까?

 

[그림 3-2]을 자세히 보면 P1의 실행이 끝나는 그 지점에 바로 P2가 실행되는 것이 아니고 어느 정도의 대기 시간이 존재하는 것을 볼 수 있다. 이런 대기 시간이 발생하는 이유는 프로세스의 정보를 PCB에 저장하고 PCB에서 프로세스 정보를 reload하는 데 일정 시간이 소요되기 때문이다.

 

이렇게 프로세스의 정보를 PCB에 저장, reload하는 시간 동안에는 CPU가 다른 작업을 하지 못하고 대기하게 된다.

 

당연히 컨텍스트 스위칭이 많으면 많을수록 CPU의 전체 대기 시간은 길어지기 때문에 성능이 저하되는 것이다.

 

단점2. 과다한 메모리 사용으로 오버헤드가 발생할 수 있다.

일반적으로 새로운 스레드가 실행되면 JVM에서는 해당 스레드를 위한 스택 영역의 일부를 할당하며, 새로운 스레드의 정보는 스택 영역에 개별 프레임의 행태로 저장된다.

 

JVM의 디폴트 스택 사이즈는 64비트의 경우 1024KB이다. 만약 64,000명이 동시 접속을 한다면, 총 64GB 정도의 메모리가 추가로 필요하게 된다.

 

일반적으로 서블릿 컨테이너 기반의 Java 웹 애플리케이션은 요청당 하나의 스레드를 할당한다. 만약 각각의 스레드 내부에서 또 다른 작업을 처리하기 위해 스레드를 추가로 할당하게 된다면, 시스템이 감당하기 힘들 정도로 메모리 사용량이 늘어날 가능성이 있다.

'TIL(사전캠프)' 카테고리의 다른 글

Java. 배운거 기록하기(2024-07-05)  (0) 2024.07.05
리액티브.(2024-07-04)  (0) 2024.07.04
리액티브. (2024-07-02)  (0) 2024.07.02
리액티브. (2024-06-28)  (0) 2024.06.28
리액티브. (2024-06-27)  (0) 2024.06.27