티스토리 뷰

안녕하세요. Seller & SD Engineering 팀 박명훈입니다.

 

지난번의 전략편에 이어 이번에는 실제 서비스 전략에 대해서 이야기하려고 합니다. 실제 서비스를 배포하며 사용했던 전략, 그리고 그 과정에 대해서 이번 글에 서술합니다.

 

 

배포 전략과 설계

지난 전략편에서 이야기했듯이 서비스에 이슈가 없이 배포하기 위해서 여러 스텝으로 작업을 분리했습니다. 이를 도식화시키면 다음과 같습니다.

배포 전략 및 순서

1차 배포

1차적으로는 도식에서의 1 ~ 3번까지의 작업입니다.

배포 서버

  • 판매자 페이지
  • 관리자 페이지

배포 사항

  • Couchbase의 데이터를 MongoDB, MSSQL로 마이그레이션 합니다.
  • 기존에 Couchbase 에서만 저장하는 로직에서 Couchbase, MongoDB, MSSQL 모두룰 저장하는 로직으로 변경되게 됩니다. 
    • (기존) Couchbase에 단건으로 저장하고 수정하였습니다.
    • (신규) Couchbase, MongoDB, MSSQL 에 동시에 쓰도록 합니다.
  • 기존에 Couchbase 에서 조회하는 구조에서 MongoDB, MSSQL를 조회하는 구조로 바뀌게 됩니다. 
    • (기존) Couchbase에서 단건, 복수건, 복잡한 조건 검색 등을 진행합니다.
    • (신규) 무거운 작업인 경우, mssql에서 쿼리를 통한 조회를 하고, 간단한 단건 조회의 경우 mongodb를 조회합니다.

배포 영향

  • API 호출하는 사용자 입장에서는 전혀 영향이 없습니다. (즉, 인증 Gateway는 이슈가 없습니다.)
  • 일부 데이터의 싱크가 안 맞는 경우가 발생할 수 있습니다.
    • 이를 위해 주기적으로 마이그레이션 배치를 돌려줍니다.

배포 이후

  • 관리자 페이지에서 사용자 조회 시, 빠른 속도로 사용자가 조회될 것으로 예상됩니다.

 

2차 배포

2차 배포는 도식에서의 4 ~ 5번까지의 작업입니다. (6번은 그 후의 작업으로 보면 편합니다.)

배포 서버

  • Gateway 서비스

배포 사항

  • Couchbase 에서 보던 사용자 데이터를 MongoDB 로 조회하게 됩니다.

배포 영향

  • Gateway 서비스 장애 포인트가 발생할 수 있습니다.
    • 그러나 이런 이슈가 없도록 개발에서 테스트 이후, 이슈 없이 진행합니다.

배포 이후.

  • Gateway에서 Couchbase 를 조회하지 않고 MongoDB 로 전환하여 서비스의 안정성이 늘어납니다.

 

계획과 현실은 다릅니다. 그러나

앞에서 이러한 계획을 세우고 진행을 해도, 여러 가지 문제가 발생하게 됩니다. 그러나 최대한 그런 계획과 틀어지지 않게 하는 것이 좋은 설계의 역할이라고 생각합니다.

 

작업의 다른 키워드는 작업을 진행하면서도 가성비(적은 리소스와 높은 성과) 있게 진행하는 것입니다. 그러한 가성비 전략은 다음과 같습니다.

 

전략 1. migration을 위한 배치 대신, 공통된 api를 사용합니다.

배치 서비스를 만들면 서비스 적으로 안정감이 더 있을 수 있겠지만 단순히 초반에 데이터를 맞춰줄 때만 사용할 예정이기에 가성비가 안 좋은 상황이었습니다. 그래서 코드 퀄리티나, 제대로 된 배치 서비스를 만들기보다는 어떻게든 정상적인 기능을 구현하는 것으로 우선순위를 잡았습니다.

 

Spring Batch 등을 사용하는 것이 아니라, API를 사용하기에 데이터 양이 많기 때문에 페이징 처리를 안 하면 이슈가 발생했습니다. 그러나 조금 더 손이 가더라도 이 부분만 처리하고 최대한 관리자 페이지나 판매자 페이지에서 사용하는 API를 사용하는 방식으로 구성했습니다. 즉, 몇 번 삽질한다고 생각하고, 수동 API를 만들었습니다.

 

| document 가 10만 건에 육박하기 때문에 timeout 이슈는 달고 살았습니다. (history 테이블은 더욱이 많았습니다.)

 

전략 2. 최대한 CRUD API를 사용하고, 특별한 경우에만 API를 만든다.

각 테이블마다 4개 API(단건 조회/리스트 조회/입력 및 수정/삭제)로 모든 동작을 처리하려고 하였고, 이를 최대한 사용했습니다. 그리고, 특정 조건인 경우에만 서비스에서 사용하는 조회 API를 만들어 처리하는 방식으로 진행했습니다.

 

전략 3. 각 도메인에서 동일한 정책을 위해 반드시 API 서비스를 거쳐가게 한다.

개인의 욕심 중 하나였고, 각 도메인에서 DB를 접근하는 것보다 그전에 반드시 API 서비스를 통해서 접근하도록 하는 방식으로 구조를 잡았습니다. 여러 팀이 모여있는 서비스 일 수록 조금 더 동일한 기능의 비즈니스를 제공해야 한다고 생각합니다. 또한 추후 확장성을 고려했을 때를 위해 데이터 직접 접근보다는 한번 거쳐 가는 구조를 잡았습니다.

 

 

생각보다 작업량이...

생각보다 작업을 진행하면서 많은 손이 들어갔습니다. 어떤날은 1주일에 80개 정도의 API를 찍어냈고, 위의 로그보다 api는 그 이상으로 작업을 했고, 코드 리뷰가 힘들 정도로 코드를 작성했습니다. 전체 코드 변경 줄을 보면 5,000줄 이상을 바꿨고, 기존의 형태를 유지하도록 많은 투자를 했습니다.

놀랍게도 api 가 아닌 프로젝트 작업 로그, api는 작업이 더 많았습니다.

 

크게 작업은 개인적으로 1달 ~ 2달 정도 진행한 것 같은데, 다른 작업으로도 바빠서 순수하게 집중한 시간은 채 한 달 정도 걸린 것 같습니다. 다행히도 현재는 배포 이후 서비스 이슈가 없는 상태입니다.

 

결과적으로는

아래와 같은 이점을 얻었습니다.

 

감격스러운 속도 증가

간단한 테스트로 전체 페이징 개수를 조회하는 쿼리의 경우, 1800배 정도의 차이가 만들어졌습니다.

 

Couchbase N1QL 성능

 

Couchbase N1QL로 검색 시 대략 30.70 초가 걸렸습니다. 그러나.

 

MSSQL Query 성능

 

이처럼 MSSQL로 쿼리 검색을 했을 때는 17ms (0.017초) 정도로 성능이 향상되었습니다. 이는 페이징 처리를 예시로 든 것이고 특정 기준을 바탕으로 데이터를 조회하면 더 큰 성능 차이가 납니다.

 

기획 팀장님이 테스트 해보면서 주신 감사

 

 

데이터 경량화 작업과 레거시 제거

과거 히스토리를 Couchbase의 Document에서 MSSQL의 테이블로 전환하고 불필요한 document 용량을 줄이고 히스토리적으로도 용량 개선을 했습니다.

또한 과거 잘못된 데이터들을 정상화하는 작업을 진행할 수 있었습니다. 과거에 이상하게 적재되어 성능을 악화시키는 불필요한 데이터들을 마이그레이션을 진행하면서, 이를 수정하고 서비스의 안정성 또한 높일 수 있었습니다.

 

추후 확장성 증가

기존 레거시를 제거하기 어려운 이유 중 하나는 해당 서비스가 어떤 서비스에서 사용하는지 모르는 부분이 있다고 생각합니다. 그리고 특히, 특정 DB의 데이터를 변경하는 부분에 대한 리스크는 여러 서비스가 설켜있을수록 자주 발생하는 문제입니다. 이번 작업을 통해서 서비스에서 직접 접근하는 DB 대신, 저희 도메인의 내부 API를 통해서 접근하도록 처리하였습니다. 이를 통해 이후, 앞으로의 개선을 준비할 수 있게 되었습니다.

 

마무리.

개발자의 글쓰기는 다르다. 에서 이야기한 것처럼, 개발자는 기획을 할 수 있어야 한다고 생각합니다. 그리고 개발자는 다른 사람들이 불편해하는 서비스를 더 나은 서비스를 만들 수 있도록 지원을 해주는 것도 하나의 역할이라고 생각합니다.

 

해당 문제는 PM분이 서비스를 사용하며, "명훈님, 이 Admin 기능이 너무 느려요"라고 던진 이야기에서 시작된 프로젝트였습니다. 많은 개발자들이 이해하듯 문제가 직관적으로 보이는 것이 해결책이 쉬운 것은 아닙니다. 특히 성능에 대한 부분은 쉬울 수도, 어려울 수도 있습니다. 그러나 개발자는 자기의 서비스의 오너십을 가져야 한다고 생각하며, 자신의 서비스를 책임지고 진행하는 것이 역할이라고 생각합니다. 바쁜 일정 속에서 이 프로젝트를 진행하고 또 성과를 만들 수 있어서 기쁩니다.

 

마무리로, 이 작업을 진행하면서 예정에 없던 QA를 하게 된 우리 PM분들에게 감사 인사를 하고 싶습니다.

 

시리즈로 된 긴 글을 읽어주셔서 감사합니다.

댓글