getAllStore 알고리즘 issue

jj·2022년 5월 12일
0

Server

목록 보기
2/8

-> getAllStore 알고리즘 issue[2]


문제 상황


FirstKitchen 프로젝트 작업을 하다가 발생한 issue에 대해 정리하고자 한다. getAllStore 라는 API를 만들다가 발생한 issue 이다. client가 getAllStore API를 호출하고 server는 DB에서 모든 store 정보를 불러온 다음 각 store와 client의 거리를 계산하고 일정 반경안에 있는 store 정보를 return 하는 API 이다.


배달의 민족 기준 약 14만개의 store가 등록되어 있다. getAllStore 요청이 들어올 때 마다 14만 개의 store 정보를 db에서 불러오면 서버에 과부하가 생길 것이라 생각해서 해결법을 찾고자 했다.

나중에 알게 되었지만 10만개 정도의 data로는 과부하가 생기지 않는다.



해결 방안


행정구역별로 나누기


먼저 '배달의 민족' 기술 블로그를 찾아보았다.

배민 기술블로그 보러가기

배달의 민족에서는 이전에는 행정구역별로 store를 관리했지만 행정구역 명칭이 바뀌는 문제가 생겼고 현재는 구글의 S2방식을 채택해서 사용하고 있다고 한다.



S2방식을 간단히 설명하면 지구를 작은 마름모로 무수히 쪼개는 것이다. 마름모의 크기는 depth level로 설정이 가능하다.

하지만 이 방식은 우리 수준에서 하기에는 무리가 있다고 생각했다.



그래서 처음으로 생각한 방식이 행정구역 별로 table을 나누는 것이었다. 현재는 store table 하나에 모든 store 정보가 들어가지만 store table을 동별로 쪼개서 방학동_store, 방배동_store 처럼 관리하면 DB에서 data를 탐색하는 시간을 줄일 수 있다고 생각했다. 하지만 이 방식은 DB를 관리하기가 사실상 불가능했다. 그래서 다른 방법을 찾고자 대학교 과 익명 톡방에 질문을 올렸다.



Redis


덕분에 쿠팡이츠에서 일하시는 프론트 개발자분과 연이 닿아서 그 분을 통해 쿠팡이츠에서 이런 issue를 어떻게 해결했나 알아 보았다. 그 분도 신입개발자라 자세히 설명은 못해주셨지만 redis라는인 메모리 DB를 사용하여 시간을 줄였다고 한다.


redis를 사용하면 시간을 줄일 수 있겠다 생각하여 redis에 대해 공부했다. 인 메모리 DB는 말 그대로 RDBMS 처럼 disk에 data를 저장하는게 아니라 메모리에 data를 저장한다. 따라서 data를 불러오는 I/O에 걸리는 시간이 매우 짧지만 휘발성이라는 단점이 있다. 따라서 현업에서는 확장된 Server를 동기화하는 용도로 redis를 사용한다고 한다.



원래 용도와는 다른것 같지만 server를 킬 때 RDBMS의 store table을 통째로 redis에 올려서 getAllStore에서 store 정보를 조회할 때 redis와 통신하게 한다면 시간을 줄일 수 있지 않을까 생각했다.



하지만 용도와 맞지 않다는 느낌을 지울 수 없어서 의구심이 들었고 '안산학생'이라는 개발자 취준 단톡방에 질문을 올렸다. 그 결과 10만개 정도의 data로는 과부하가 생기지 않는다는 사실과redis를 쓰면 빨라지기야 하겠지만 10만개의 data는 indexing이 잘된 RDBMS에서 불러와도 충분하다는 것이었다.



결론


추가로 알게된 사실로

select * from store

로 모든 store data를 server에 불러온 뒤 거리를 계산하여 특정 store들만 추출하는 것과 DB에서 애초에 걸러진 data를 server로 가져오는 것은 큰 시간차이를 보인다는 것이었다. 하지만 위도,경도로 저장되어 있는 위치 정보를 MySQL쿼리를 통해 정확히 거르는 것은 무리가 있었다.



그래서 생각해낸 방법이

`select * from Store where longitude between ${x-0.035} and ${x+0.035} and latitude between ${y-0.03} and ${y+0.03}`;

다음과 같은 쿼리였다. client의 위도,경도에서 각각 약 0.03정도 반경안에 있는 data들을 가져오는 것이다. 이렇게 하면 목표인 3km안에 있는 data에다가 약간의 data가 추가되어 server로 보내진다. 그럼 server에서 그 data들만 추출해내면 되는 것이다. 이렇게 하면 DB에서 불러오는 data양을 줄여 시간을 줄일 수 있겠다 생각했다.


-> getAllStore 알고리즘 issue[2]

profile
끊임없이 공부하는 개발자

0개의 댓글