정보 공유 게시글은 Sluv 서비스의 핵심이 되는 기능입니다.
핵심이 되는 기능이다 보니 한 페이지에 많은 데이터가 보여지며, 이는 성능 저하로 이어졌습니다.
한 페이지에 많은 데이터가 몰리다 보니 정보 공유 게시글 상세 조회에는 총 11개의 Entity가 필요한 상황이 벌어집니다.
PostMan으로 성능을 측정해 보니 최초 호출 시 0.8초, JPA 캐시 호출 시 0.5초의 성능을 보여주었습니다.
이 정도면 준수(?)하지 않나라고 생각하고, JMeter로 부하 테스트를 진행하였습니다.
JMeter의 Thread Group 설정은 100명이 1초 안에 동시에 접속하는 것으로 가정하였습니다.
이럴 수가.. 테스트 결과를 보고 눈을 의심했습니다...
최소 시간은 PostMan에서 JPA 캐시 호출의 속도와 비슷했지만.. 최대 시간 18960/ms. 평균 9767/ms가 걸렸습니다.
100명이 동시에 호출하면, 누군가는 18.9초가 걸린다니.. 평균적으론 9.7초가 걸린다니.. 이건 있을 수 없는 일입니다.
바로 성능 개선할 방법을 고민하기 시작했습니다.
위 사진에서 파란색 박스는 작성자가 게시물을 통해 공유하고 싶은 손민수템의 정보들입니다. 즉, 핵심 정보입니다.
반면 빨간색 박스는 해당 손민수템과 관련된 다른 정보 공유 게시글들 입니다.
저는 파란색 박스는 가장 중요한 부분, 빨간색 박스는 덜 중요한 부분이라고 판단하였습니다.
해당 정보 공유 게시글을 조회하는 사용자는 게시글의 손민수템 정보를 보고 싶어서 들어오는 것이지, 관련된 다른 정보 공유 게시글들을 보러 들어오는 것이 아닐 것이라 생각하였습니다.
유튜브로 예를 들면, 동영상 상세 페이지엔 해당 동영상이 재생되고, 그 밑으로 관련 혹은 추천 동영상들이 알고리즘을 타고 나타납니다.
사용자가 유튜브의 동영상 상세 페이지를 선택하는 이유는 해당 동영상이 보고 싶어 선택하는 것이지, 관련 동영상들을 보고 싶어 확인하지 않습니다.
현재 구조는 정보 공유 게시글 상세조회 API를 호출하면 파란색 박스와 빨간색 박스의 내용이 모두 조회됩니다.
이는 가장 중요한 핵심 정보가 덜 중요한 정보라는 모래주머니를 차고 있는 구조입니다.
현재 구조가 핵심 정보가 모래주머니 때문에 힘들어하는 구조이기 때문에 핵심 정보로부터 모래주머니를 떼주었습니다.
정보 공유 게시글 상세조회 API를 4개의 API로 분리하였습니다.
- 정보 공유 게시글 상세조회 API.
- 같은 셀럽의 아이템 목록 조회 API.
- 같은 브랜드의 아이템 목록 조회 API.
- 다른 스러버들이 함께 보관한 아이템 목록 조회 API.
이후 프론트 개발자에게 부탁하였습니다.
빨간색 박스 부분의 호출이 느려 빨간색 박스 부분의 랜딩이 안되더라도 중요한 부분은 파란색 박스 부분이니까 정보 공유 게시글 상세조회 API를 가지고 우선 페이지를 채우는 구조로 변경해달라고 하였습니다.
위 사진과 같이 처음 정보 공유 게시글을 조회하면 정보 공유 게시글 상세조회 API에서 제공하는 정보로만 가득차기 때문입니다.
이렇게 API를 분리하니 최대 6064/ms, 평균 3780/ms가 걸리는 것을 확인할 수 있었습니다.
글의 초반부에 설명했듯이 정보 공유 게시글 상세조회에는 총 11개의 Entity가 사용됩니다. 때문에 많은 join이 발생하며, 조회의 성능이 떨어집니다.
이 부분을 캐싱으로 개선하려고 하였습니다.
두 가지 중에 Cache Aside 전략을 선택하였습니다.
캐시 읽기 전략을 선택할 때 단점에 주목하였습니다.
- Cache Aside : 데이터의 최신화가 어렵다.
- Read Through : 캐시가 다운되면 서비스에 장애가 생긴다.
서비스에 장애가 생길 수 있는 조건이 늘어나는 건 매우 위험한 방식이기 때문에 Cache Aside 전략을 선택하고 단점을 보완할 방법을 고민하였습니다.
Cache Aside 최신화가 어렵다는 단점을 보완하기 위해 잘 바뀌지 않는 데이터와 자주 바뀌는 데이터에 주목하였습니다.
파란색 박스는 자주 바뀌지 않는 데이터, 빨간색 박스는 자주 바뀌는 데이터입니다.
이렇게 분리하여 자주 바뀌지 않는 데이터인 것들만 Cache Aside로 Redis에 저장한다면, 조회 시 성능에 이점을 얻을 수 있을 것이라 생각했습니다.
또한 최신화를 위해 파란색 박스의 데이터가 수정되거나 삭제될 경우 해당 데이터를 캐시에서 삭제하는 방식을 도입하였습니다.
최종적으로 100명이 동시에 같은 정보 공유 게시글을 조회했을 경우, 최대 시간 5571/ms. 평균 3206/ms가 걸렸습니다.
- 최대 시간 : 18960/ms -> 5571/ms. 240% 성능 개선.
- 평균 시간 : 9767/ms -> 3206/ms. 203% 성능 개선.
중요 데이터와 함께 묶여있는 덜 중요한 데이터를 API에서 분리해 내고, 자주 바뀌지 않는 데이터를 캐싱하여 데이터의 최신화를 챙기며 최대 240%의 성능 개선을 이루어 냈습니다.
현재는 서버 컴퓨터의 스케일업까지 적용하여 평균 0.022초까지 개선할 수 있었습니다.
스럽 서버 멀티모듈 전환기 (0) | 2024.09.30 |
---|---|
비동기 처리를 통해 검색 성능을 개선해보자! (0) | 2023.10.07 |
사진을 빠르고 안전하게!! PreSigned URL (0) | 2023.07.29 |
AOP!! Exception을 잡아줘!! (0) | 2023.04.29 |
카카오, 구글, 애플. 우리는 Sluv으로 만난다! (0) | 2023.04.29 |
댓글 영역