[GCP 원데이] I/O 바운드 애플리케이션 (1)

2021. 5. 1. 13:47GCP/원데이

1. I/O 바운드 애플리케이션

1) I/O 바운드 애플리케이션성능 향상

서버 스케일 아웃으로 인해 하드디스크도 서버와 함께 늘어날 것이고, 자기 하드디스크에 있는 데이터로만 처리하면 충분히 성능을 향상 시킬 수 있다. 하지만, 각자의 하드디스크의 데이터를 실시간으로 공유하기 어렵다는 문제를 가지고 있다.

 

따라서 서로 공유할 수 있는 저장소(DB)를 사용한다. 하지만 문제는 서버를 아무리 늘려도 DB의 성능이 낮다면 전체 서비스의 성능은 DB와 동일해진다(병목현상). 이를 해결하기 위해서는 DB의 성능에 의존적인 부분을 줄이고 전체 서비스의 성능을 향상시켜 더 많은 트래픽을 처리할 수 있도록 만들어야한다.

 

파일 I/O 바운드일 경우 서버를 늘려 성능을 올릴 수 있지만 DB I/O 바운드 애플리케이션은 서버를 늘린다고해도 성능이 올라가지는 않는다.

2) 한 줄 게시판

댓글 같이 짧은 글을 작성할 수 있는 한줄 게시판(id, content)을 간단히 생성해준다. 여기에는 다음과 같은 기능들이 필요하다.

- 글 작성

글 작성의 동작 과정으로는 사용자로 부터 DB에 INSERT 쿼리가 전달되고, 이에 해당하는 응답을 사용자에게 전달해준다. 이 과정속에서 사용자는 응답을 받을 때 까지 대기하고 있다.

 

- 글 목록 (Paging) / 글 번호로 조회 (내용 확인) / 글 내용으로 검색

이 기능들의 경우 SELECT 쿼리로 글에 대한 정보를 사용자에게 반환해준다. 사용자는 마찬가지로 응답이 올 때까지 대기해야하는데, 이 때 사용자가 새로고침을 할 경우 새로운 SELECT 쿼리가 전달이 된다. 즉, 서비스에서 응답이 없을 경우 사용자는 새로고침을 하여 SELECT 쿼리문이 발생되는 악순환이 이루어진다.

 

결국, 모든 행위에는 공통적으로 DB가 존재하며, DB 속도가 느려지면 병목현상이 일어날 수 밖에 없다. 여기서 기억해야하는 것은 사용자가 새로고침의 행위를 할 때마다 데이터베이스에 조회를 하고 있다는 점이다. 따라서 사용자의 요청을 바로 DB에 반영하지 않고 처리하는 방법으로 진행해준다.

 

Spring Boot 프로젝트를 생성하고 Postgre 도커 이미지를 실행시켜준다.

docker run --name pgsql -d -p 5432:5432 -e POSTGRES_USER=postgresql -e POSTGRES_PASSWORD=postgrespassword postgres

3) 인스턴스 생성 및 설정

  • 타이완
  • e2-medium
  • CentOS 7

 

sudo yum install -y docker
sudo systemctl start docker
sudo chmod 666 /var/run/docker.sock
docker run --name pgsql -d -p 5432:5432 -e POSTGRES_USER=postgresql -e POSTGRES_PASSWORD=postgrespassword postgres

※ 생략되어있지만, 실무에서 Postgresql 이미지를 이용하여 실행을 할 때에는 컨테이너 내에서 사용하고 있는 저장 공간을 호스트 OS와 공유할 수 있도록 volume 옵션을 추가해준다. (로그, DB 데이터 저장)

 

application.yml 파일의 경우 생성한 postgresql DB가 설치된 인스턴스를 사용하기 때문에 datasource url을 해당 인스턴스에 맞게 수정해주어야 한다.

spring:
  datasource:
    url: jdbc:postgresql://[Postgresql 인스턴스 내부 IP]:5432/postgresql
    username: postgresql
    password: postgrespassword
  jpa:
    show-sql: true
    hibernate:
      dialect: org.hibernate.dialect.PostgreSQLDialect
      ddl-auto: update

4) 인스턴스 설정

기존에 생성되어있던 CPU 바운드 애플리케이션용 인스턴스 3개를 재활용한다.

별도로 Webhook를 설정해두지 않았으므로, 자동으로 배포가 되지 않는다. 따라서 Jenkins로 수동으로 배포하도록 한다. 단, 브랜치의 이름에 따라 수정해야한다.

빌드 후 확인해보기 위해 Postman을 이용하여 임의의 데이터 30개를 넣고 NginX 외부 IP에 '/posts'로 접속해본다. (약 Post 하나에 357ms 정도의 지연시간이 걸림)


자신이 만든 애플리케이션이 어떤 리소스를 많이 사용하는지 대략적으로 알고 있다면, 그것을 바탕으로 추측하면서 하나씩 테스트해보아야한다. 통상적인 웹 애플리케이션이라면, DB 저장소 > API 호출 > File > CPU 순으로 리소스를 많이 사용한다.

 

CPU를 많이 사용하는 경우는 드믈며, CPU Load가 높을 경우 애플리케이션 문제가 아닌 서버용 보안 프로그램이 문제인 경우가 많다. 데이터가 적을 때에는 어디서 병목이 일어나는지 파악하기 어렵기 때문에 애플리케이션이 저장소에 접근하거나 API 호출을 할 때 시작과 끝날 때 타이머로 시간을 측정하여 로그를 남기는 것을 권장한다.


[참고] github.com/ozofweird/io-bound-application

728x90