다시 시작 Restart/개선 Improvements

PostgreSQL과 PGRouting을 활용 전역 경로 계획 속도 개선

Tap to restart 2024. 10. 9. 18:00

# Situation 상황

- 자율주행 이동 로봇은 전역 경로 계획Global Path Planning(우리가 지도앱으로 출발지와 도착지를 입력했을 때 나오는 경로를 생각하면 된다)을 바탕으로 자율 주행을 한다.

- 기존 전역 경로 계획은 타팀에서 만든 패키지를 활용해 OSM(Open Street Map) 파일을 바탕으로 경로 계획을 했다.

- 대규모 지역에서 서비스를 하게 되면서 OSM 파일이 기존 다른 서비스 지역과 비교해 10배 이상으로 커졌다. 전역 경로 계획 시 OSM 파일을 읽어서 그래프 형태로 메모리에 올리는 전처리 과정이 오래 걸리게 되어서 첫 경로 계획은 3초 이상 소요되었다. 

- 더 큰 지도 파일을 사용할 경우 당연히 전처리 과정이 더 오래 걸려서 첫 경로 계획은 더 오랜 시간이 필요했다.

- 협력 업체가 OpenAPI로 전역 경로 계획이 필요한 API를 요청한 경우 타임아웃(Timeout)이 발생했다.

 

# Task 과제

- 첫 경로 계획이든 두 번째든 관계 없이 일정한 시간이 소요되어야 했다.

- 평균적으로 큰 편차 없이 최소한 0.5초 이내로 전역 경로 계획을 할 수 있어야 했다.

 

# Action 행동

- 서버가 구동되자마자 첫 경로 계획을 생성해서 전처리 데이터가 메모리에 올라오도록 개선했다. 백엔드 서버가 장고Django + 구니콘gunicorn을 사용하고 있었기 때문에 gunicorn on_starting을 활용했다.  

- 하지만 OSM 파일이 변경되었을 때 기존 구니콘 워커worker는 메모리에 전처리 데이터가 없으므로 타임아웃이 발생했다. OSM 파일을 이용한 전역 경로 계획은 각 구니콘마다 메모리에 전처리 데이터를 올려야만하는 근본적인 문제를 해결할 수 없었다. OSM 파일을 변경할 때마다 새로 배포를 해야만 했다.

- 데이터베이스를 활용해 전역 경로 계획을 새로 구현했다.

- PostgreSQL 기반 오픈소스 경로 찾기 확장 프로그램(extension)인 PGRouting을 활용했다. 다익스트라, A* 등 여러 경로 찾기 알고리즘을 지원해줬고, 적용도 어렵지 않았고, 속도도 빨랐다.

- 기존에 OSM 파일을 데이터베이스에 Way, Node 등으로 나눠서 저장했다. PGRouting 적용을 위해서 Way를 조각Segment 내서 테이블에 저장하는 작업을 진행했다.

- 여러 PGRouting의 최단 경로 찾기 알고리즘 테스트를 진행해 가장 최적의 알고리즘을 선택했다.

- 기존 전역 경로 계획과 똑같은 형태로 응답이 나오도록 구현했다.

- 소요 시간 분석 시 출발점과 도착점에서 가장 가까운 Way 조각을 찾는데 긴 시간이 소요되어서 자주 사용되는 출발점과 도착점은 미리 Redis로 캐싱했다.

 

# Result 결과

- 첫 경로 계획이든 두 번째든 관계 없이 일정한 시간이 소요되었다. 데이터베이스 기반으로 변경했기 때문에 전처리 데이터를 메모리로 올리는 과정이 필요 없게 되었기 때문이다. 지도 파일이 더 커져도 비슷한 시간이 소요되었다.

   첫 경로 계획 기존 3초 → 0.1~0.2초. 15배 이상 빨라졌다.

- 지도 파일을 언제든 바꿀 수 있게 되었다.

- 데이터베이스 기반이므로 비용cost을 쉽게 변경할 수 있으며, 변경 시 동적으로 다른 경로를 생성할 수 있게 되었다.

- 배달 서비스 시 로봇 대기 장소 -> 매장, 매장 -> 고객 집 앞, 고객 집 앞 -> 대기 장소 총 3가지 전역 경로 계획을 한 번에 생성해야 하는데 0.5초 이내에 할 수 있게 되었다.

- 더 이상 타임아웃이 발생하지 않게 되었다.