서론

이번에 2년동안 서비스한 서비스에 서버 이중화를 적용하였다.

그 이유는 갈수록 사용자 수와 트래픽이 많아졌고, 서비스 특성상 트래픽이 일정하게 발생하는 구조가 아니었기 때문이다.

현재 서버는 가입자수 0에서 시작한 서버기 때문에 개발 속도 효율과 과금 효율에 집중된 구조였다. 초기 인프라와 개발을 내가 하지 않았지만, 확장성을 위한 개발은 선호하지 않기 때문에 이전 구조에 대해 납득하고 있다.

(빅워크 BM 내용임. 관심 없으시면 다음 주제로 넘어가도 됩니다)

빅워크의 초기 BM은 B2B로 시작했다. 기업에게 비용을 받고 빅워크 플랫폼에 캠페인을 등록하면, 사용자들이 해당 캠페인에 기부를 하는 것이다. 이때 사용자는 일반 사용자와 기업 사용자로 분류되는데, 트래픽이 일정하지 않은 이유가 이 때문이다. 대기업과 거래가 많은 서비스다보니, 그 기업의 임직원 수가 5천에서 많으면 몇 만명이다. 캠페인이 오픈 되면 몇 만명의 기업 사용자들의 트래픽이 발생하다보니 기업의 규모에 따라, 캠페인 개수에 따라 트래픽이 불규칙적으로 발생한다. 규모는 예상이 가능하기에 적절하게 EC2의 사양을 Up/Downgrade 시키며 운영하였지만, 그러기 위해서는 서비스를 일시적으로 중단해야 한다.

예전 서버 구조와 목표하고 있는 모습

빅워크의 서버는 Spring boot를, DB는 MySQL을 사용하며, AWS의 EC2에서 서버와 DB가 동작한다. DB가 별도의 RDS가 아닌, EC2에서 동작하는 것은 조금 특이한 부분이다. 추가로 내장 DB인 Redis 또한 EC2 local에서 사용하고 있다.

이중화의 목표 모습은, AWS EC2에서 LBS(Load balancing) + Auto scailing (자동 증설) 이다. 기본적으로는 2대의 Active-Active 구조로 운용하며, 한 대의 서버의 CPU가 많아질 경우 부하 분산을 하도록 한다. 그리고 기본 2대의 트래픽 허용량을 초과할 경우 자동으로 Scale out하여 새 EC2 insatnce가 생성되도록 하도록 목표하였다.

이중화를 적용하기 위해 선행되어야 할 것

현재 구조에서 서버를 이중화 한다면, 치명적인 문제가 발생한다. 그것은 데이터 불일치다. MySQL과 Redis가 서버 로컬에서 작동하고 있기 때문에, 서버가 늘어나면 MySQL, Redis도 중복으로 늘어나고, 이는 데이터 공유가 되지 않을 것이다. 사용자 인증쪽은 다행히 저장소가 필요 없는 JWT를 사용하고 있기 때문에 고려하지 않아도 되었다.

한 묶음으로 있는 것들을 모두 분리하는 작업이 필요했다.

이 글에서는 2년동안 서비스하고 있는, 20만명이 사용중인 DB의 마이그레이션과 서버 이중화 작업에 대해 고군분투한 얘기들을 적어보려고 한다.