Why?

퇴사자가 남기고간 API의 성능을 개선하는 업무를 맡게되면서 겪었던 내용과 생각들을 정리해보려고 글을 썼다.

현재 상황은?

기존 API는 PHP로 작성되어 있었고, 한번 조회 시 개발서버에서는 2-3분, 운영서버에서는 네트워크 상황에 따라 조금씩 달랐긴 했지만 약 11분이 넘어가는 API였다.

API 조회 속도를 끌어올리기위해 여러가지 고민해본 내용들이 있다.

성능 개선 방안

여러가지 생각해 본 내용이 있으나 크게는 아래 4가지 정도가 될 듯하다.

  1. 파일에 결과를 저장하는 방법
  2. Redis에 결과를 저장하는 방법 (하지만 현재 PHP버전에서는 Redis와 연결 불가능)
  3. RDB에 결과를 저장하는 방법
  4. 페이징 / 카테고리별로 나눠서 제공하는 방법

Redis에 결과를 저장하는 방법

위 방법중에 작업하려는 API속성과 가장 잘 맞는건 2번, Redis에 저장을 하는 것이다. 이유를 나열하자면,

  • 응답이 고정된 API이다.
  • 영구적으로 저장할 필요가 없는 데이터이다.
  • 다른 방법들에 비해 가장 빠른 응답속도를 기대할 수 있다.
  • 필요에 따라 영구적으로 사용할 수 있다.

하지만, 문제가 하나 있었는데 현재 사용중인 PHP버전에서는 Redis와 직접 연동할 수 있는 방법이 없었다. 그래서 생각한 내용은 JAVA시스템을 이용하는 방법이였다.

생각한 내용은 기존 PHP로 작성된 API를 배치로 만들고 그 안에서 생성된 결과물을 JAVA시스템을 이용하여 Redis에 저장하는 구조로 작업을 진행하였다.

API 성능개선

그러나 여전히 PHP 배치 시간이 10분이나 걸리는 건 문제가 있다고 판단하여 약간의 성능 개선을 위한 작업을 진행하였다.

가장먼저 눈에 들어온 것은 3중 for문 안에서 한건씩 쿼리를 조회하다보니 약 240만번!! 을 조회하고 있는 내용이였고, 이 쿼리를 실행하는 횟수를 줄이고자 다건 조회를 만들었고, 쿼리하는 내용을 보다보니 반복되는 데이터를 찾는 부분도 많았기에 이를 다시 조회하지 않도록 로직을 추가하였다. 개발서버 기준으로 약 80%의 성능이 올라갔다. (약 2분 -> 약 25초)

다음으로는 서브쿼리로 던지고 있는 내용을 조인으로 변경하여 성능을 개선하였고, while문으로 하나씩 조회해서 가져오는 로직을 쿼리로 바꿔 한번에 가져올 수 있도록 변경했다. (약 25초 -> 약 3초)

성능이 눈에 띄게 많이 줄어든 모습이 보였다.

(그러나 아쉽게도 이건 실제 운영에 반영되지 못했다…)

얼마나 개선 되었나요?

일단 위에 얘기한것처럼 프로세스 성능 개선은 무마되었기 때문에 실행에 10분이나 걸린다는 사실은 변치 않았지만 최초 한번 실행 이후 모두 레디스에서 조회를 해왔기 때문에 굉장히 빠른 타이밍에(0.4초) 응답을 내려줄 수 있게 되었다.

그외 추가적으로 고민했던 부분들은 아래와 같다.

  • 공용으로 사용중인 해당 Redis에 저장한 데이터는 얼마나 보관을 해야할지? (디폴트 만기 일, 설정이 필요한 만기일)
  • 배치 시간동안에는 어떠한 응답코드를 내려주는게 좋을까? (우리 서비스 만의 응답 코드 등)