홈피드 조회 성능 테스트 경험기_2
2021, Oct 15
💡 Intro
- 이전 포스트에서 진행한 프로젝트에서 홈피드 게시물 조회 성능 테스트에 대한 결과를 보고 개선대상을 파악하고 개선한다.
- 개선 후 테스트를 재진행하여 결과를 비교한다.
🌩 쿼리 진단
이전 포스트에서 진행한 성능 테스트를 통해 DB 쿼리 쪽 병목이 있다는 것을 알아냈다. 구체적으로 쿼리를 자세히 살펴보면서 어떤 문제가 있는지 확인해보자.
- 홈피드 게시물을 반환할 때 발생하는 slow query
- 현재는 포스트 조회하는 쿼리가 최대값으로는 3.62 초가 소요된다.
- 쿼리의 실행계획을 확인해서 문제점을 파악해보니 100만건의 데이터를 거의 다 훑으면서 filesort를 하고 있었다. 게시물을 최신순으로 정렬하여 상위 10개를 가지고 오는 Pagination을 적용하고 있기 때문이다.
🌩 개선하기
-
createt_At 칼럼에 인덱스를 추가하여 데이터가 정렬되도록 한다. 인덱스를 건 후 실행계획을 확인해보니 filesort가 제거되었고 훑는 row 수가 대폭 줄어들었다.
🌩 개선 후 성능 테스트
인덱스 추가 후 테스트
-
테스트 중 서버 모니터링
- 본래 DB에 실행 대기 중인 프로세스(맨 왼쪽 r 칼럼)가 많았다. 약 20 이라는 수치를 보였으며 DB 서버의 CPU의 idle 상태도 항상 0%였다.
- 인덱스를 걸어서 쿼리 수행이 훨씬 빨라지면서 DB 인스턴스에 CPU 부하가 훨씬 줄었다. 또한 여전히 Disk I/O는 발생하지 않는다.
- 대신 WAS 쪽 CPU에 부하가 발생했다. r 수치가 11-15 사이를 왔다갔다 했으며 CPU idle 비율이 2% ~ 15%를 왔다갔다 했다.
- 왜 갑자기 이런 수치가 보여졌을까?
- 성능 테스트를 할 때 실운영 환경과의 차이가 있기 때문이다.
- 성능 테스트를 할 때는 한 vuser의 요청에 대한 응답이 오기 전까지 다음 요청을 보내지 않는다. 따라서 요청에 대한 응답이 느리면 그 다음 요청을 못보내기 때문에 이전 테스트 결과와 다르게 더 많은 요청을 보냈고, WAS의 CPU 부하가 발생했다.
-
인덱스 추가 후 성능 테스트 결과
- 진행된 테스트 개수: 6694 → 944360
- 요청 응답 시간: 13.41s → 83.57ms
- TPS: 10.94/s → 1573.72/s
- 성능이 대폭 향상된 것을 확인할 수 있다.
🌩 요약
- 기존 홈피드를 조회할 때 13초 가량의 시간이 소요 되었다.
- 분석해보니 디스크 I/O 부하는 없고 DB쪽 CPU 부하가 있으므로 쿼리 효율성의 문제라고 판단하였다.
order by createdAt
쿼리의 부분이 풀스캔 + filesort를 하고 있음을 발견했다. (쿼리 실행 시간 3초 이상)createdAt
칼럼에 인덱스를 걸어서 풀스캔 → limit 개수 만큼만 스캔하도록 설정했다..- 결과적으로 응답 시간이 약 13초에서 85ms 정도로 단축되었다.
🌩 느낀점
- 테스트 코드를 통해서는 확인할 수 없는 허점을 발견할 수 있었던 것이 새로웠다.
- 성능 테스트를 하면서 가장 크게 느낀 것은 돌아가는 어플리케이션을 구현하는 것이 아니라 사용자에게 서비스될 수 있는 어플리케이션을 만들어야 한다는 것이다. 그렇게 하기 위해서는 경험하지 않으면 알 수 없는 많은 부분들을 고려해야한다.
- 기존에는 코드 퀄리티 자체와 원하는 결과를 내는 것에 집중했다면, 이제는 제한된 리소스 내에게 원하는 목표치까지 서비스할 수 있는 어플리케이션을 구현하는것이 중요하다는 시각이 트인 좋은 기회였다.
- 성능 테스트를 하면서 막힌 부분은 서버를 모니터링, 커넥션 개수 파악, 데이터베이스 쿼리 최적화, 네트워크 통신 부분이다. 많이 배웠던 CS 기초가 웹 어플리케이션을 구현하면서 많이 등장하지 않아서 왜 중요한지 체감하지 못하고 있있는데 이런 대용량 (대용량이라고 하기엔 훨씬 부족하지만..) 서비스를 만들면서 다시 마주하게 될 줄 몰랐다. 역시 기초가 튼튼한 것이 가장 중요한 것 같다.
- 성능 테스트를 하면서 부족한 CS 기초 (운영체제, 네트워크, 데이터베이스)를 병행해서 공부했다. 띄엄띄엄 알던 지식들이 하나로 연결되는 경험이었다.
백엔드 코다입니다 🙌