안녕하세요, 쏘카 데이터 비즈니스 본부의 캐롯, 카일입니다.

쏘카에서 차량을 예약하기 위해 쏘카 앱을 탐색하다 보면 하나의 쏘카존에서 아반떼, 레이, 코나 등 다양한 차량들이 눈에 들어옵니다. 하나의 존에 차량이 1대만 있을 수도 있고, 같은 차종의 차량이 여러 대가 있을 수 있습니다. 이때, 하나의 존에 같은 종류의 차량이 여러 개가 있다면, 어떤 차량이 어떤 과정을 거쳐 나에게 배정되는지 궁금하신 적 없으신가요?

이번 글에서는 그 과정에 있는 예약 테트리스 프로젝트를 다룹니다.

프로젝트를 시작하게 된 계기부터, 선형 최적화 모델을 실제 서비스에 적용하기 위해 구축한 인프라 구조까지 프로젝트의 전반적인 내용을 자세하게 다루었으니 이 글을 읽고 최적화가 모빌리티 산업에서 어떻게 적용되는지 이해할 수 있는 시간이 되길 바랍니다.

예상 독자는 다음과 같습니다

  • 쏘카의 예약 과정의 뒷부분이 궁금하신 분
  • 모빌리티 산업에서 최적화(Optimization) 프로젝트가 어떻게 동작하는지 궁금하신 분
  • 데이터 기반의 오퍼레이션을 만드는 과정이 궁금하신 분
  • 프로젝트 과정에서 어떻게 아키텍처를 설계했는지 궁금하신 분

목차



1. 예약 테트리스 프로젝트 소개

1.1 프로젝트 이름의 유래

프로젝트를 설명하기에 앞서, ‘예약 테트리스’ 이름의 유래를 공유드리겠습니다. 테트리스는 위에서 내려오는 블록을 빈 공간에 맞춰 차곡차곡 쌓아 꽉 찬 한 줄 한 줄을 만들어 포인트를 얻는 퍼즐 게임입니다.

이번 프로젝트는 하나의 쏘카존에 있는 여러 차량(같은 차종의 차량)이 있는 상황에서 예약과 차량을 배정(매칭)하는 프로젝트입니다. 들어오는 예약을 차량의 빈 공간에 차곡차곡 정리하는 과정이 마치 테트리스 게임과 비슷하다고 생각했기에 예약 테트리스라는 프로젝트 이름을 붙였습니다.

쏘카에선 예약에 차량을 어떻게 배정하는지가 매우 중요합니다. 예약에 차량을 어떻게 배정하냐에 따라 얼마나 많은 고객이 쏘카를 이용할 수 있는지가 결정되기 때문입니다. 차량이 사용되지 않는 시간이 적을수록(=고객의 차량의 점유 시간이 길수록) 운영 효율이 좋아지기 때문에 예약에 차량을 어떻게 배정하는지에 따라 비즈니스에 영향을 줍니다. 즉, 비즈니스 임팩트에 영향을 줄 수 있는 문제입니다.

한 쏘카존에 같은 종류의 차량이 두 대 있는 경우를 예시로 추가 설명드리겠습니다.

A와 B라는 서로 다른 두 고객이 각각 08시 ~ 12시와 20시 ~ 24시 총 두 건의 예약을 한 상태에서, 0시부터 24시까지 24시간 동안 이용하고 싶어 하는 C라는 고객이 같은 존에서 같은 차량을 대여하고 싶어 하는 상황을 생각해 봅시다.

이때 만약 A와 B에게 서로 다른 차량이 배정된 상태라면 C는 이용할 수 있는 차량이 없을 것입니다.

두 차량 모두 C의 예약을 받을 수 있을 만큼의 충분한 여유 공간이 없기 때문입니다.

하지만 만약 A와 B의 예약에 같은 차량을 배정했다면 두 사람의 예약에 배정되지 않은 하나의 차량이 남아 C는 수월하게 쏘카를 이용할 수 있게 됩니다.

이처럼 예약의 상황마다 더 적절한 차량을 배정해 주면 더 많은 차량을 준비하지 않아도 더 많은 고객들이 쏘카의 서비스를 이용할 수 있도록 할 수 있고 운영 효율이 좋아지게 됩니다.


1.2 예약 테트리스의 목적

예약 테트리스 프로젝트가 도입되기 이전에도 예약을 차량에 배정하는 효율화 작업은 이루어지고 있었습니다. 단, 지금과 다른 점이 있다면 이 모든 작업이 쏘카 직원분들의 손으로 진행되고 있었습니다.

앞서 설명한 문제 수준의 난이도라면 사람 손으로도 쉽게 처리할 수 있겠지만, 쏘카는 15,000대 이상의 차량과 4,000개의 쏘카존을 보유하고 있습니다. 이런 상황에서 발생하는 예약이 매우 많기 때문에 사람이 직접 진행하기 어렵고, 진행한다고 해도 매우 많은 시간이 소요됩니다.

만약 같은 종류의 차량이 두 대뿐이라고 해도 쏘카는 최대 90일 전부터 예약을 할 수 있다는 점을 생각하면 사람이 직접 최적의 차량 배정을 하기가 쉽지 않습니다. 즉, 어제 수정한 배정 결과가 내일이 되면 새로운 예약이 추가되어 더 이상 최적이 아닐 수 있습니다. 쏘카에서 차량이 가장 많은 제주공항 존의 경우는 예약 테트리스 서비스가 배포되기 전까진 하루에 최대 4시간 정도 시간을 사용하며 고생하고 있었습니다.

차량 배정 프로세스를 자동화하면 쏘카의 직원분들이 업무 시간을 더 효율적으로 사용할 수 있고, 사람의 머리로 도출하기 어려운 조합을 자동으로 산출해 최적화된 차량 배정으로 서비스를 운영할 수 있게 됩니다. 즉, 예약 테트리스 프로젝트는 업무 효율과 차량 운영 효율 두 마리 토끼를 모두 잡기 위한 프로젝트입니다.

해결하려는 목적을 정리하면 다음과 같습니다

  • 쏘카의 운영 효율 개선
  • 차량 배정 최적화 과정을 자동화해 내부 운영 리소스 효율화(업무 효율 개선)


2. 예약 테트리스 최적화 모델링

2.1 최적화 문제(Optimization Problem)의 접근법

최적화 문제(Optimization Problem)는 어떤 목적 함수(Objective Function)의 함숫값을 최대화 또는 최소화하는 변수의 해 값을 찾는 유형의 문제를 뜻합니다. 최적화 문제를 푸는 방법은 다양하게 있는데, 다음과 같이 정리할 수 있습니다.

최적화 문제를 푸는 방법 중 첫 번째는 알고리즘을 사용하는 것이고, 두 번째는 해 찾기 도구인 솔버(Solver)를 활용하는 것입니다.

알고리즘으로 최적화 문제를 접근하는 방법도 두 가지로 나눌 수 있는데 먼저 해당 문제에 특정된 알고리즘을 사용 또는 개발하는 방법이 있습니다. 특정 문제를 풀기 위한 알고리즘의 대표적 예시로는 최단거리 경로를 구하는 다익스트라 알고리즘 (Dijkstra’s Algorithm) 을 들 수 있습니다. 문제에 딱 맞는 알고리즘을 개발하면 알고리즘으로 도출된 해가 최적임을 보장할 수 있다는 큰 장점이 존재합니다. 하지만 그런 알고리즘을 개발하는 데까지 시간과 노력이 매우 많이 필요하기 때문에 단점 또한 명확합니다.

최적화 문제를 알고리즘으로 접근하는 방식의 두 번째 갈래로는 휴리스틱 알고리즘이 있습니다.

휴리스틱 알고리즘은 정확한 최적해를 효율적으로 찾을 수 있는 방법이 없을 때 해의 최적성을 희생해 더 빠르고 효율적으로 해를 찾는 알고리즘을 의미하고, 유전 알고리즘(Genetic Algorithm), 개미 집단 알고리즘(Ant Colony Optimization Algorithm) 등이 잘 알려진 예시입니다.

문제 유형과 관계없이 쉽고 빠르게 근사 최적해를 구할 수 있다는 이점이 있지만 휴리스틱적 접근은 계산보다는 탐색에 더 가깝기 때문에 찾은 해가 최적임을 보장할 수 없다는 단점이 있습니다.

알고리즘을 직접 구현하지 않고 Solver를 활용하여 모델링을 통해 최적화 문제를 푸는 방법도 존재합니다.

Solver는 수학적으로 표현된 최적화 문제의 해를 구하는 최적해 탐색 도구로 Gurobi, CPLEX 등이 상업적 Solver와 Pyomo, OR-Tools 등의 오픈 소스 Solver 등이 있습니다.

Solver로 최적화 문제를 풀기 위해서는 문제를 수식으로 모델링 해야 하는데 이 과정을 수학적 모델링(Mathematical Programming)이라고 부릅니다.

문제의 성격이 선형 또는 비선형인지에 따라 선형 계획법(Linear Programming)비선형 계획법(Nonlinear Programming)으로 나뉘고, 구하고자 하는 해가 정수로 한정되는 경우는 정수 계획법(Integer Programming)으로 정의할 수 있습니다.

수학적 모델링을 통해 수식화된 문제를 풀기 위해 Solver를 사용하면 매우 빠른 속도로 최적해 또는 최적해에 매우 근접한 해를 도출할 수 있다는 매우 큰 장점이 존재합니다. 하지만 문제가 복잡할수록 시간이나 컴퓨팅 파워 같은 연산을 위한 리소스가 많이 요구되어 비용적인 측면을 고려해야 한다는 단점이 있습니다.

예약 테트리스 프로젝트에서는 Solver를 사용하여 최적화 문제를 해결하고 있습니다. 직접 서비스에 사용하는 서비스인만큼 최대한 최적에 가까운 해를 도출하는 것이 필요했고, 알고리즘을 직접 개발하는 것 대비 훨씬 짧은 시간 안에 좋은 결과를 도출할 수 있었기 때문입니다. 연산에 필요한 컴퓨팅 파워는 후술할 GCP(Google Cloud Platform)의 힘을 빌려 단점으로 꼽히는 리소스 측면도 충분히 해결할 수 있었기 때문에 최적화 문제의 접근법 중 가장 적합한 방법론이라고 판단했습니다.

2.2 정수 계획법(Integer Programming)

예약 테트리스 프로젝트는 차량 배정 최적화 모델링을 위해 정수 계획법을 사용합니다.

구체적인 모델을 다루기 전 먼저 정수 계획법이 무엇인지 짚고 넘어가겠습니다.

정수 계획법(Integer Programming)은 주로 선형 제약조건으로 표현된 해 공간에서 조합 최적화(Combinatorial Optimization) 문제를 푸는 최적화 기법입니다.

생소한 단어들이 많아 처음 접하는 개념처럼 느낄 수도 있지만 다음과 유사한 일차 부등식 문제를 풀어본 경험이 있다면 낯설지 않다고 느낄 것입니다.

  • “0보다 큰 정수 x와 y가 아래와 같은 조건을 만족할 때, k 값을 최대화하는 x, y를 찾으면?”

이런 유형의 문제가 바로 정수 계획법을 사용할 수 있는 간단한 예라고 할 수 있습니다.

우리에게 익숙한 이 문제를 최적화 모델의 3요소라 할 수 있는 제약조건, 결정 변수, 목적 함수로 설명하겠습니다.

  • 제약조건(Constraints)
    • 특정 제약을 거는 조건입니다. 예를 들어 x는 0 보다 큰 값이다, -x와 y를 더하면 2보다 작다입니다.
    • x, y 축과 부등식으로 표현된 두 직선이 x와 y가 가질 수 있는 값을 한정하는 제약조건이 됩니다
  • 결정 변수(Decision Variable)
    • 우리가 알고자 하는 변수인 x, y는 k 값을 결정하는 결정 변수로 정의할 수 있습니다
    • 모든 제약조건을 만족하는 결정 변수 값의 집합을 해 공간(Solution Space)라고 합니다
    • 해 공간이 정수로만 이루어져 있기 때문에 정수 계획법을 사용하게 됩니다
  • 목적 함수(Objective Function)
    • 최대화하고자 하는 값 k는 이 문제의 목적이 되는 함수로 목적 함수라고 부릅니다
    • 목적 함수가 결정 변수에 대해 선형 관계를 가지면 선형 계획법, 제곱 등의 비선형 관계를 가지면 비선형 계획법이 됩니다
    • 이 문제는 k가 x와 y에 대해 일차식의 형식을 띄고 있기 때문에 정수 선형 계획법(Integer Linear Programming)의 예시로 볼 수 있습니다

위 문제에서 각 요소들을 표시하자면 다음처럼 표현할 수 있습니다.


2.3 최적화 지표 정의하기 : 어떤 상태가 더 ‘최적’일까?

예약 테트리스 모델링에서 가장 어려운 부분은 어떤 차량 배정 상태가 더 “최적”인지를 수치적으로 판단할 수 있는 지표를 정의하는 것이었습니다.

모델 성능과 최적화 정도 사이에서 고민한 끝에, 가상 예약이라는 개념을 도입해 지표를 만들었습니다.

  • 실제 예약: 실제로 고객이 이용 중이거나 이용 예정인 예약
  • 가상 예약: 실제 예약이 들어올 수 있는 여유 공간을 나타낸 가상의 예약

완벽한 최적해는 아니더라도 가상의 예약 건이 가장 많이 들어올 수 있도록 예약에 차량을 배정하는 모델을 작성하기로 했습니다.

즉, 가상 예약 건의 예약 가능성이 클수록 더 최적이라고 판단한 것입니다.

앞서 들었던 예시로 설명하자면, A와 B의 예약을 서로 다른 차량에 배정한다면 예약 가능한 하루 단위의 가상 예약건수는 0이 되지만, 두 예약을 같은 차량에 배정한다면 1이 되기 때문에 후자의 경우를 더 최적이라고 판단할 수 있습니다.

예약이 어떤 차량에 배정되었는지가 중요하고, 다른 예약과의 선후 관계는 변수 단위에서 고려하지 않아도 되기 때문에 모델의 최적해 도출 속도에서 강점을 가지는 접근법이었습니다.


2.4 최적화 모델 정의하기

예약 테트리스의 최적화 모델은 다음과 같이 정의됩니다.

  • 결정 변수: 실제 또는 가상의 예약에 차량의 배정 여부(0 또는 1)
  • 목적 함수: 예약 가능한 가상 예약건수의 최대화
  • 제약조건
    • 모든 예약은 단 하나의 차량에 배정되어야 한다
    • 차량이 고정되어야 하는 예약은 배정된 차량이 변경되면 안 된다
    • 임의의 서로 다른 두 개의 실제 예약은 같은 차량에 배정된 경우 서로 겹칠 수 없다
    • 임의의 실제 예약과 가상 예약은 같은 차량에 배정된 경우 서로 겹칠 수 없다

이를 수식으로 표현하면 다음과 같이 작성할 수 있습니다.

2.5 최적화 모델 구현하기 : Google OR-Tools

수식화한 모델을 코드로 구현하고 최적해를 찾기 위해서는 Solver가 필요합니다.

예약 테트리스의 최적화 모델은 구글의 오픈소스 Solver인 Google OR-Tools의 파이썬 패키지로 구현하였습니다.

Google OR-Tools가 지원하는 Solver 중 조합 최적화 문제를 위한 CP-SAT Solver는 무료로 사용할 수 있는 오픈소스임에도 뛰어난 성능을 가지고 있고, 사용자의 입맛에 맞는 커스텀 설정들을 지원하기 때문에 이번 프로젝트에 적합하다고 판단했습니다.

제약조건을 수식화하는 것도 직관적이기 때문에 개발 난이도도 높지 않은 편입니다. 최적화 문제를 푸는 분이 계시다면 Google Or-Tools Solver를 추천드립니다.

앞에서 예시로 가져온 문제를 CP-SAT Solver로 푸는 파이썬 코드를 보면 실제 수식과의 괴리감이 크게 없는 것을 확인할 수 있습니다.

3. 예약 테트리스 모델 배포

최적화 모델링을 통해 생성된 모델을 실제 서비스에 배포하기 위해선 여러 작업이 필요합니다. 우선 쏘카 서비스 서버에서 최적화 요청을 해야 하고, 최적화 결과를 서비스 서버에 전달해 데이터베이스에 반영해야 합니다.

이를 위해 쏘카의 서비스 엔지니어링 본부와 협업을 진행했습니다

이 프로젝트의 요구 조건은 다음과 같습니다

  • 1) Solver를 실행할 서버 환경이 필요하며, 빠르게 결과를 반환해야 합니다
  • 2) 쏘카 서비스 서버와 최적화 서버의 데이터 요청 프로토콜이 필요합니다

3.1 최적화 서버 & 병렬 처리

Solver는 실행할 서버 환경을 “최적화 서버”로 지칭하고, 쏘카 서비스의 서버는 “쏘카 서비스 서버”로 지칭하겠습니다.

Solver는 CPU 연산으로 진행되며, 저희 프로젝트에선 최대 90일 치의 데이터를 가지고 최적화를 수행해야 합니다. 이 과정에서 많은 데이터를 빠르게 처리해야 합니다. 배정 가능한 경우의 수를 따지면 존 x 차종 별 예약건수(최대 90일) x 차량 대수가 됩니다. 쏘카는 약 4,000개의 존을 가지고 있고 15,000대가 넘는 차량을 보유하고 있습니다. 위 최적화를 실행하기 위해 많은 컴퓨팅 파워가 필요합니다.

쏘카 서비스 서버에서 최적화 서버에 최적화 요청을 하고, 최적화 연산이 실행되는 동안 새로운 예약이 들어온다면 그 최적화는 다시 실행해야 합니다. 따라서 저희는 더 빠르게 최적화할 수 있는 방법을 고민했습니다.

Solver 자체의 성능 개선을 하는 방법과 최적화를 병렬로 실행하는 작업을 모두 할 수 있다고 판단했고, Solver 자체의 성능은 최적화에서 연산을 줄이기 위한 트릭을 사용해 줄였습니다. 그 후엔 Ray를 사용해 최적화 작업을 병렬로 실행했습니다.

Ray는 다음과 같이 데코레이터를 사용해 간단하게 병렬 처리를 실행할 수 있는 라이브러리입니다.

import ray
ray.init()

@ray.remote
def f(x):
    return x * x

futures = [f.remote(i) for i in range(4)]
print(ray.get(futures))

위에서 말씀드린 것처럼 연산을 실행하기 위해 많은 컴퓨팅 파워가 필요하기 때문에, CPU 성능이 좋은 인스턴스를 선택해 사용하고 있습니다. 더 자세히 말씀드리면 Google Cloud Platform의 vCPU n2d-highcpu-224 인스턴스를 사용하고 있습니다. CPU 224개를 사용한다고? 생각하실 수 있지만 선점형(Preemtible) 인스턴스를 사용할 경우 US 기준 1시간에 1.69 달러로 저렴합니다. GCP의 선점형 인스턴스는 AWS의 스팟 인스턴스와 유사한 서비스입니다.

img

단, 선점형 인스턴스는 사용하던 도중 구글 클라우드 측에서 회수할 수 있는 단점을 가지고 있습니다. 이런 경우를 대비해 만약 선점형 인스턴스가 종료된다면 새로운 최적화 서버를 띄우는 방식으로 구현했습니다. 이 과정에서 Shutdown Script를 사용했습니다.

최적화 요청을 모두 처리하면, 최적화 서버를 자동으로 종료하도록 설정해 낭비될 수 있는 비용을 미리 절감했습니다.

3.2 쏘카 서비스 서버와 최적화 서버의 데이터 프로토콜

데이터 프로토콜을 정의하기 전에 “예약이 하나 생성될 때마다 실시간으로 실행돼야 하는가?”에 대해 고민했습니다. 예약이 새로 생성될 때마다 최적화를 실행해서 결과를 반영하는 방식도 존재했고, 많은 예약을 배치로 정리하는 방식도 존재했습니다. 예약이 들어올 때마다 기존 예약을 바꾸는 것을 실험해 본 결과 일희일비하는 모습을 보이기도 했고, 쏘카 매니저분들이 운영하실 때 혼란을 가중할 수 있다 판단했습니다.

실제로 현업에 계신 분에게 여쭤보니, 예약이 들어올 때마다 할 필요는 없고 성수기 기준 1시간에 1번씩 실행하면 괜찮다고 이야기 들었습니다. 한번 최적화를 잘 해두면, 1시간 후엔 바꿀 부분이 많이 없기 때문에 매번 할 필요가 없다는 현업의 이야기를 들었습니다.

위 내용을 토대로 예약을 일정 간격으로 정리하는 방식(Batch)으로 결정했습니다. 단, 쏘카 서비스 서버에서 최적화 요청 빈도는 추후에 변경될 수 있기에 이런 변경 가능성도 고려했습니다.

그와 동시에 데이터를 어떻게 주고받을지에 대한 논의도 진행했습니다. 최적화를 하기 위해 데이터가 존재해야 하는데, 데이터가 저장되는 데이터 웨어하우스인 BigQuery는 실시간으로 데이터가 저장되지 않고, ETL 파이프라인을 통해 1시간에 1번씩 저장됩니다. 추후에 최적화 요청 빈도가 변할 수 있기에 데이터 웨어하우스의 데이터를 사용하지 않고 별도의 메시지(Message)로 데이터를 주고받기로 했습니다.

메시지 프로토콜은 서버와 데이터 조직이 나뉘는 쏘카에서 적합했으며, 서버에선 메시지를 Push 하고, 최적화 서버에선 메시지를 받아와(Pull) 연산을 진행한 후 다시 서버 쪽에게 최적화 결과를 반환하는 구조로 진행됩니다.

API 형태로 진행하는 방법도 고민했으나, 최적화 작업의 특성상 연산 시간이 오래 소요될 수 있기 때문에 메시지 형태로 작업하기로 협의했습니다.

메시지 시스템은 대표적으로 Apache Kafka, AWS SQS, GCP Pub/Sub 등을 활용할 수 있습니다.

이 프로젝트를 위해 Kafka를 띄우기엔 관리의 리소스가 더 크다고 판단했고 클라우드의 매니지드 시스템인 AWS SQS와 GCP Pub/Sub을 고려했습니다.

AWS SQS와 GCP Pub/Sub의 큰 차이는 메시지를 저장하는 기간(리텐션)의 차이와 메시지의 Payload 사이즈 등이 있습니다. AWS SQS는 최대 Payload Size가 256KB, GCP Pub/Sub은 최대 10MB입니다. 저희는 90일간의 예약 내역과 차종의 데이터를 담아 메시지를 보내기 때문에 256KB보단 10MB가 안정적이라 판단했고, 따라서 GCP Pub/Sub을 사용하기로 결정했습니다

혹시 메시지 시스템에서 생소하신 분들을 위해 간단하게 아시면 좋은 내용을 정리하면 다음과 같습니다

  • Pub/Sub 구조
    • 서비스 간의 비동기 통신을 위해 사용되는 통신 모델입니다. Pub/Sub 구조에서 사용되는 몇 가지 중요한 개념을 짚고 넘어가면 다음과 같습니다
    • Topic
      • Publisher가 발행하는 메시지를 Subscriber에게 전송하는 창구 같은 개념입니다
    • Publisher/Producer
      • 메시지를 생성해 Topic으로 발행하는 서비스입니다
    • Subscriber/Consumer
      • Topic을 구독해 메시지를 받는 주체입니다
    • Push와 Pull
      • Subscriber가 메시지를 전달받는 방식의 종류에는 Push와 Pull 두 가지가 있습니다.
      • Push: Pub/Sub 시스템이 Subscriber에서 메시지를 밀어 넣는(Push) 방법
      • Pull: Subscriber가 직접 서비스로부터 메시지를 당겨오는(Pull) 방법

메시지를 받은 후, Google Cloud Platform의 Dataflow로 데이터를 처리했습니다. 이 과정에서 Apache Spark를 사용할 수 있었지만, Pub/Sub과 Dataflow의 결합이 편리하므로 Dataflow를 사용했습니다.

최종 인프라는 다음과 같습니다.

img

  • 쏘카 서비스 서버에서 최적화 요청을 하기 전에, 최적화 서버를 띄우는 메시지를 보냅니다
  • 그 과정에서 최적화 서버가 띄워지고, 쏘카 서비스 서버는 Pub/Sub에 최적화가 필요한 예약과 차종 데이터를 보냅니다(Push)
  • 최적화 서버에선 메시지를 받고(Pull) Ray로 최적화를 병렬로 실행합니다
  • 최적화 결과를 쏘카 서비스 서버에게 보냅니다(Push)
  • 쏘카 서비스 서버에선 최적화 결과를 데이터베이스에 반영하고 성공 여부를 다시 최적화 결과 Pub/Sub에 보냅니다(Push)
  • 실행된 최적화 서버는 서버의 CPU, Memory 사용량이 특정 조건이 될 경우(예 : 일정 시간 이상 CPU Usage가 5% 이하인 경우) 최적화 서버를 종료합니다
  • 위 과정에서 선점형 인스턴스가 구글에게 회수된다면, Shutdown Script가 다시 최적화 서버를 실행시킵니다

4. 예약 테트리스 적용 성과

프로젝트 소개 단에서도 언급했다시피, 예약마다 어떤 차량을 배정해 주는지에 따라 같은 대수의 차량에서도 얼마나 많은 고객이 쏘카를 이용할 수 있는지가 달라집니다.

예약 테트리스 프로젝트로 실제 운영 효율이 얼마나 더 좋아졌는지는 사용한 차량 대비 차량이 얼마나 점유되었는지를 확인해 보면 됩니다.

  • 사용한 차량 = 전체 운영 중인 차량 중 예약에 사용된 차량의 비율 = 차량 사용 비율
  • 차량의 점유 정도 = 판매 가능한 모든 차량의 시간 중 예약으로 점유된 시간의 비율 = 가동률

위 개념은 카셰어링 비즈니스를 처음 접한다면 다소 생소한 개념으로 느껴질 수 있기 때문에 위에서 들었던 예시로 설명해 보겠습니다.

img

총 두 대의 차량이 있을 때, 앞선 두 개의 예약에 각각 다른 차량을 배정하여 세 번째 예약이 예약 실패되었다면 차량 사용 비율은 1.0, 가동률은 0.25가 됩니다.

반면 두 개의 예약에 같은 차량을 배정하여 세 번째 예약이 무사히 예약되었다면 차량 사용 비율은 동일하게 1.0이지만 가동률은 0.75로 더 많은 예약을 수용할 수 있었음을 뜻합니다.

img

동일한 예시에 차량을 한 대 추가하여 앞선 두 개의 예약에 각자 다른 차량을 배정해도 세 번째 예약을 받을 수 있었던 경우도 살펴보겠습니다.

세 개의 예약에 각각 다른 차량을 배정한 경우에는 운영 중인 모든 차량을 사용했기 때문에 차량 사용 비율은 1.0이 되고, 가동률은 0.5가 됩니다.

하지만 같은 차량을 배정할 수 있는 예약을 잘 정리한다면 3대의 차량 중 2대만을 사용해도 충분하기 때문에 가동률은 0.5로 동일하지만 차량 사용 비율은 0.67로 더 낮게 운영할 수 있습니다.

이렇게 차량 사용 비율과 가동률을 비교하면 예약 테트리스 프로젝트를 통해 같은 대수의 차량으로 더 많은 예약을 수용하게 되었는지, 또는 같은 예약량이 더 적은 차량 대수로도 수용할 수 있게 되었는지 판단할 수 있습니다.

이제 실제 일별 차량 사용 비율 대비 가동률을 적용 전후로 확인해 보면 다음과 같습니다.

img

그래프에서 볼 수 있듯이 적용 후의 추세선이 전과 비교해 더 높은 것을 확인할 수 있습니다.

이는 동일한 차량 사용 비율 관점에서 보면 같은 대수의 차량을 공급하여 더 많은 예약을 수용할 수 있다는 것을, 동일한 가동률 관점에서는 더 적은 비용으로 동일한 매출을 만들어낼 수 있음을 의미합니다.

결론적으로 예약 테트리스 프로젝트를 통해서 평균적인 차량 사용 비율 대비 약 4%가량의 가동률 증분을 만들어낼 수 있었습니다.

또한 차량 사용 비율이 더 낮을수록 두 추세 선의 차이가 더 두드러지는 것을 볼 수 있는데 이는 최적화를 할 수 있는 여지와 관련이 있습니다.

최적화를 하기 위해서는 최적화를 할 수 있는 여지가 충분히 있어야 합니다. 이미 모든 차량에 예약이 빽빽하게 차있는 경우라면 최적화를 할 수 있는 여유가 부족해 예약 테트리스의 효과가 두드러지기 어렵습니다.

하지만 반대로 예약이 많지 않은 경우라면 배정할 수 있는 차량의 경우의 수가 많은 만큼 최적화할 여유 공간이 남아있어 예약 테트리스를 적용했을 때 그 결과가 더 두드러지게 나타나게 됩니다.

img

예약 테트리스 프로젝트는 단순히 매출과 가동 관점에서만 성과가 있던 것은 아니었습니다.

매일 직접 예약을 정리하던 업무가 모두 자동화되었기 때문에 각 지역사업팀에서는 업무시간을 훨씬 더 효율적으로 쓸 수 있게 되었습니다.

특히 팬데믹 이후 여행 수요가 몰려 성수기 수준으로 예약이 밀려들어오는 상황인 제주사업팀에서 예약 테트리스가 큰 도움이 되고 있다는 소식을 들었을 때는 일을 하며 뿌듯함을 느꼈던 순간 중 하나입니다 :)

img

5. 마무리

실시간으로 서비스에 적용되는 최적화 프로젝트는 실제 케이스가 많지 않아, 시행착오도 있었지만 함께 작업하며 서포트해 주신 많은 분들 덕분에 성공적으로 프로젝트를 마무리할 수 있었다고 생각합니다. 쏘카 예약 테트리스는 2020년에 완성한 프로젝트로 현재까지 이상 없이 동작하고 있습니다.

예약 테트리스 프로젝트에서 서버 개발 쪽을 맡아주신 맷과 브루스, 프로젝트가 진행되는 동안 여러 부서를 오가며 디테일하게 챙겨주신 주디, 그리고 적극적으로 피드백 주신 제주사업팀과 기타 지역사업팀에게 감사드리고 싶습니다.