29CM 의 이굿위크 장애대응 기록

Greg Lee
29CM TEAM
Published in
14 min readJan 8, 2024

이굿위크란?

이굿위크는 이커머스의 블랙프라이데이 행사를 29CM 에 맞게 재해석한 것을 말합니다. 23년 11월에 진행한 이굿위크는 많은 고객분들의 사랑에 힘입어 기대 이상의 성공을 거두었습니다. (다시 한번 29CM 을 사랑해주시는 많은 분들에게 감사의 말씀 드립니다)

이번 이굿위크에서는 29CM 만의 차별화된 브랜드 셀렉션을 고객들에게 다수 선보임과 동시에 플랫폼 관점에서도 이굿위크를 이용하는 고객을 위해 다양한 맞춤형 기능을 제공했습니다. 이굿위크 티져, 마이셀렉션, 럭키쿠폰과 하루특가, 이굿입점회와 이굿라이브, 브랜드 팝업과 이굿상품과 같은 다양한 기능을 통해 이굿위크에 대한 고객의 기대치를 충족시켰고, 거기에 더하여 고객분들이 선호하는 감도 높은 브랜드 상품을 좋은 가격에 다수 제공했던 것이 이굿위크의 성공 비결이라고 생각하고 있습니다. 그리고 실제로 23년의 이굿위크는 전년 대비 286% 증가한 판매액을 기록하게 되었습니다.
(이굿위크를 준비했던 제품팀의 제품 전략과 실행 과정은 이굿위크 : 작년보다 2배 더 잘하기 위한 전략과 실행을 통해 자세하게 확인 가능합니다)

하지만 29CM 의 시스템을 개발하고 운영하는 엔지니어의 관점으로 23년의 이굿위크를 돌아본다면, 이굿위크 시작과 동시에 발생했었던 장애 상황에 대한 아쉬움이 크게 남는 것은 어쩔 수 없을 듯 합니다.

이 글에서는 오픈하자마자 평시 대비 7배 이상의 트래픽이 순간적으로 인입되면서 장애가 발생하고, 그러면서도 하루 거래액 121억을 돌파했었던 23년 11월 13일의 29CM 서비스 운영 과정을 공유하고자 합니다.

Phase 1. 장애 발생 직후

이커머스에서 블랙 프라이데이라는 행사는 1년 중 가장 큰 트래픽과 매출이 발생하는 프로모션입니다. 그 때문에 블랙 프라이데이를 준비하는 각 플랫폼 서비스들은 순간적으로 높게 튀는 트래픽 상황에서도 안정적인 서비스를 제공할 수 있도록 만반의 준비를 하게 됩니다. 예상하는 트래픽에 맞게 장비를 증설하고 병목이 발생할 수 있는 구간마다 이슈가 발생하지 않도록 사전에 개선 작업을 진행합니다.

29CM 에서도 이굿위크를 준비하는 과정에서 예상하는 트래픽에 맞게 인프라를 증설하고, 병목 발생 가능성이 높은 구간마다 별도의 개선 작업을 진행하면서 고객분들을 맞이할 만반의 준비를 진행했습니다. 그럼에도 저희는 이굿위크 오픈과 동시에 약 26분 동안의 서비스 전면 장애를 경험하게 됩니다.

이굿위크 시작과 동시에 장애 공지

이굿위크 오픈 직후의 장애 원인은 크게 2가지입니다.

장애의 첫 번째 원인은 예상보다 더 높은 수준의 트래픽이 순간적으로 인입된 상황 때문이었습니다. 오픈 직후 순간 트래픽이 높게 형성될 것을 예상하고 인프라 증설 등을 사전에 진행했지만, 전년 이굿위크의 패턴을 기반으로 예측했던 예상 트래픽을 상회하는 수준의 트래픽이 오픈 직후에 인입되었습니다. 이러한 Traffic Spike 는 서비스의 장애를 유발할 수 있습니다.

[Traffic Spike] 동 시간대 대비 약 7배 이상의 트래픽이 시스템에 순간적으로 인입됨

또 다른 원인으로는 이굿위크를 위한 별도의 상품 탭에서 검색 엔진(ElasticSearch) 에 과도한 부하를 일으키는 기능이 있었습니다. 이굿위크 전용 셀렉션을 고객에게 보여줄 때 ‘여성의류’, ‘남성의류’ 와 같은 대카테고리 키워드로 검색 엔진을 호출하는 부분이 있었는데, 대카테고리는 많은 상품을 포함하는 포괄적인 검색어라서 그만큼 검색 엔진에 과도한 부하를 줄 수 있습니다. 이러한 기능이 오픈 직후에 유저가 몰리면서 과도한 수준으로 호출되었고, 이 때 검색 엔진에 과도한 부하가 발생하면서 검색 엔진이 오동작하게 되었습니다.

이굿위크 오픈 시점이었기 때문에 29CM 개발팀의 주요한 맴버들은 모두 시스템을 모니터링하고 있었고, 서비스 장애를 확인한 직후 장애 대응을 시작하였습니다. 대응 과정에서 대량의 트래픽으로 인한 검색 엔진 과부하가 주요한 원인임을 확인하였고, 00시 12분에 검색 기능을 멈추게 하여 검색 엔진의 부하를 낮추는 시도를 했습니다. 이렇게 하면 유저가 검색의 주요한 기능은 이용할 수 없게 되지만 전체 서비스는 살릴 수 있다고 판단했고, 유저가 원하는 주요한 상품은 모두 이굿위크 탭에 잘 정리되어 있었기 때문에 그 당시 상황에서는 검색이 유저에게 주요한 핵심 기능은 아니라고 봤습니다.
이후 00시 26분에는 검색 기능과 이굿위크 상품 탭을 제외한 모든 기능을 정상화 시켰습니다.
(감사하게도 장애 시간대에서도 분당 주문완료 건수는 평시 대비 4~5배 이상으로 확인되었고, 이 후 여러 가지 준비 작업을 거친 후에 13일 오후 5시 즈음에는 검색 기능도 다시 정상화 시켰습니다)

Phase 2. 예정된 Traffic Spike 를 대비한 준비 작업

장애 상황을 해결한 이후, 새벽 5시에 서비스 인프라 추가 증설 작업을 진행하였습니다. 해당 시간에는 메인 데이터베이스의 max_connection 을 기존 대비 2배로 늘렸고, 캐시 목적으로 사용하는 인프라의 스펙도 늘렸습니다. 그리고 이굿위크를 위한 주요한 애플리케이션의 서버 대수도 크게 늘렸습니다.

AWS 와 같은 클라우드 환경에서의 애플리케이션 증설은 쉽고 빠르게 진행할 수 있지만, 애플리케이션 증설의 최대 한계는 결국 데이터베이스가 버텨주는 수준으로 결정됩니다. 그 당시 장애 상황을 대응하면서 애플리케이션을 기존 대비 40% 수준까지 늘렸었는데, 그러면서 메인 데이터베이스가 제공할 수 있는 connection 갯수가 부족해지는 상황이 발생했습니다.
전체 서비스에서 특정 애플리케이션의 수를 늘리게 되면, 애플리케이션 내의 DB Connection Pool 도 당연히 늘어나게 되고, 이 때문에 전체 애플리케이션과 데이터베이스 간의 connection 갯수도 크게 증가하게 됩니다.
실제로 장애 상황을 대응하면서 크게 늘려놨던 애플리케이션 때문에 메인 데이터베이스가 제공할 수 있는 connection 의 수(max_connection parameter) 가 부족해질 수도 있는 상황이 발생했고, 이 때문에 max_connection 수를 늘려야 했습니다. 다만 max_connection 수의 증가만큼 데이터베이스의 부하가 크게 늘어나는 것은 아니었기 때문에 데이터베이스의 scale-up 은 진행하지 않았고, 단순히 max_connection 파라미터만 변경하는 수준으로 대응했습니다.

데이터베이스의 max_connection 을 늘린 이후, 캐시 인프라도 추가로 증설하게 됩니다. 29CM 에서 캐시가 적용된 구좌 중에는 상품 상세 페이지(PDP) 도 포함되어 있었는데, 장애를 경험하면서 PDP 로의 트래픽 인입이 상당히 높다는 것을 확인하였습니다. 그 때문에 사전에 증설해놨던 캐시 인프라를 추가로 증설하게 됩니다. 다만 이 때에는 단순히 캐시 인프라를 추가하는 수준 이상으로 트래픽 별로 캐시 인프라를 나누어 관리할 수 있도록 세분화 하였습니다. “PDP 를 처리하는 트래픽”과 “그 외의 트래픽”을 앞 단의 로드밸런서(ALB) 가 각각의 담당 캐시로 전달되게끔 트래픽을 분배하도록 설정하였고, 이를 통해 특정 캐시가 down 되더라도 다른 영역의 트래픽 처리는 정상적으로 이루어질 수 있도록 인프라를 격리 시켰습니다.

상품 PDP 와 그 외의 트래픽을 분리하여 캐시 인프라 운영

그리고 이굿위크를 위한 주요한 애플리케이션의 서버 대수도 크게 늘렸습니다. 평소의 29CM 는 서비스의 안정성과 소비하는 비용 간의 균형을 적정 수준으로 맞춰가면서 인프라를 운영해왔지만, 이굿위크 오픈 직후의 장애를 경험한 상황에서 다시 장애가 발생한다면 고객 분들의 실망과 함께 29CM 서비스의 신뢰도가 크게 떨어질 수 있기 때문에 그 때만큼은 평소와 다르게 인프라에 많은 버퍼를 두어 증설을 진행했습니다.

29CM 개발팀은 이런 식으로 다음에 있을 전투 상황을 준비하였습니다.

Phase 3. 비상! Database CPU 65%

인프라 증설 이후 오후 2시 전까지는 큰 이슈 없이 이굿위크를 진행하고 있었습니다. 그런데 오후 2시 20분 즈음의 모니터링 과정에서 메인 데이터베이스의 CPU 가 65% 까지 올라왔다는 크리티컬한 이슈가 발견됩니다.

오후 그 시간대에도 이굿위크의 시작과 함께 주요한 브랜드와 이벤트를 홍보하는 대량의 푸시가 발송되고 있었고, 그 때마다 예상보다 높은 수준의 트래픽이 지속적으로 인입되고 있었습니다. 그럼에도 그 때의 트래픽 수준은 오후 7시에 예상하는 인입 트래픽만큼의 수준은 아니었는데, 이미 DB CPU 가 65% 에 도달했다는 것은 분명 문제 상황이었습니다. (누락된 인덱스, 오랜 시간 실행되고 있는 롱쿼리, 데드락 발생과 같은 이슈는 발견되지 않았고, 순수하게 정상 로직 처리 과정에서 발생하는 DB 부하였습니다)

이를 위해 다소 무모하면서도 위험해보일 수 있는 의사 결정을 하게 됩니다.
29CM 개발팀은 새벽도 아닌 업무 시간에 메인 데이터베이스를 scale-up 하기로 결정합니다. (scale-up 은 데이터베이스의 restart 를 필요로 합니다)
그렇게 하지 않으면 메인 이벤트가 예정된 오후 7시에는 분명 장애가 발생할 것이라는 판단이 있었기 때문입니다.

다행히 29CM 에서는 몇 번의 데이터베이스 인프라 작업과 함께 다양한 기술 검증을 진행했던 경험이 있었기 때문에, 15분 정도의 짧은 회의를 통해서 이슈를 최소화하면서도 메인 데이터베이스를 scale-up 할 수 있는 작업 계획을 정의할 수 있었습니다.

하지만 아무리 작업 계획이 잘 잡혀있고 몇 번의 경험을 통한 확신이 있다 할지라도 많은 사람들이 서비스를 이용하는 대낮에 데이터베이스를 restart 하는 것은 위험부담이 큰 작업이었기 때문에, 이러한 사항을 29CM 의 대표님에게 빠르게 공유하고 승인을 받는 과정이 필요했습니다.
감사하게도 대표님은 맥락과 상황을 파악하신 후에 흔쾌히 해당 작업에 대한 승인을 해주셨지만, 지금 생각해도 대표님 입장에선 다소 당황스러운 이야기였을 것이라 짐작합니다. (감사했습니다)
“준모님, 해당 작업 과정에서 최소 10분 정도는 서비스가 동작하지 않을 예정입니다. 승인을 부탁 드립니다.”

그리고 이러한 사항을 전사에 공지하고 작업을 진행합니다.
(장애 발생 직후의 공지는 많이 해봤지만, 잠시 뒤에 장애가 발생할 것을 예고하는 공지는 저도 처음 경험해봅니다)

10분 뒤에 서비스에 장애가 발생합니다~

이후 데이터베이스 scale-up 과정에서 “write connection 으로 생성된 connection 이 데이터베이스의 failover 과정에서 read DB 로 변경될 때의 readonly commit 에러가 발생하는 이슈” 와 “Spring 애플케이션이 사용하는 hikari CP 의 maxLifetime 를 default 값으로 설정했을 때, 기존 커넥션이 오랜 시간 유지되는 이슈” 가 있었지만, 이는 모두 사전에 예상했던 사항이기 때문에 큰 어려움없이 목표했던 작업을 완료할 수 있었습니다.

다행히 오래 걸리진 않았다는…

(나중에 기회가 된다면 29CM 에서 경험했던 데이터베이스 인프라 작업에서 얻었던 지식과 경험을 별도의 기술블로그로 작성할 예정입니다)

Phase 4. 오후 7시 이후

오후 7시가 되기 전에는 다시 한번 각 시스템과 모니터링 영역을 체크합니다.

그리고 오후 7시에는 예상대로 평시 트래픽 대비 n배 이상의 순간 트래픽이 인입되었습니다. 하지만 00시와는 다르게 큰 이슈 없이 성공적으로 이굿위크의 준비된 프로모션을 진행할 수 있었습니다. 그리고 13일 19시 이후부터 이굿위크가 끝나는 시점까지 특별한 장애 없이 이굿위크를 안정적으로 운영하게 되었습니다.

Lessons Learned

저희는 이번 이굿위크 오픈 직후의 장애 상황을 경험한 후에 두 가지 Lessons Learned 를 얻었습니다.

1. 대형 이벤트 전에는 다소 과한 수준의 인프라를 증설해놓기

사실 이굿위크 오픈 전에도 대량의 트래픽 인입을 대비한 인프라 증설이 있었습니다. 그럼에도 오픈 직후에 모두의 예상을 뛰어넘는 수준의 트래픽이 순간적으로 인입되었고 29CM 은 약 26분 정도의 전면 장애를 겪게 되었습니다.

앞으로는 이굿위크와 같은 대형 이벤트가 예정되어 있을 때에는 서비스 인프라를 다소 과하게 증설하여, 순간 높은 트래픽이 인입되더라도 장애가 발생하지 않도록 대비할 예정입니다.

인프라 증설은 그만큼의 비용을 지불해야 하기 때문에 서비스 안정성과 비용 간의 적정한 균형이 필요합니다. 하지만 이굿위크와 같이 전사적으로 큰 행사가 진행되는 상황에서 장애가 발생한다면, 이로 인해 고객 경험과 비즈니스에 악영향을 끼치기 때문에 인프라 비용을 고려하더라도 다소 과한 수준으로 인프라를 미리 늘려놓는 것이 필요합니다.

2. 대형 프로젝트 내에서는 기술 리딩 담당자를 명시적으로 지정하기

이굿위크 오픈 직후의 장애 원인 중 하나는 이굿위크를 위한 특정한 로직에서 검색 엔진에 과도한 부하를 일으키는 API 를 대량으로 호출했기 때문입니다. 그런데 원인이 되는 문제 상황은 사전에 발견만 되었다면 비교적 쉽게 대응할 수 있는 수준의 이슈였습니다. API 의 호출량과 시스템 부하를 파악한 후에 API 의 호출량을 줄이거나 부하를 낮출 수 있는 방안을 적용했으면 되는 사항이었고, 실제로 문제를 발견한 이후 비교적 쉽고 빠르게 장애의 원인을 제거하기도 했습니다.

그런데 이러한 잠재적인 위험 요소를 장애 상황이 발생한 후에야 발견할 수 있었던 것은 “이굿위크 제품 개발 과정에서 서비스 전체를 조망하고 확인하는 기술 리딩 담당자가 없었기 때문” 입니다. 이굿상품 페이지를 개발하는 개발자와 검색 엔진을 관리하는 개발자는 있었지만, 둘 간의 연결을 확인하고 이러한 연결이 전체 시스템에 어떠한 영향을 줄 것인지를 확인하는 개발자는 없었습니다. 시스템은 특정 영역이 정상적으로 동작하는 것도 중요하지만 그 이상으로 전체 영역이 유기적으로 동작하는 것이 훨씬 더 중요합니다.

앞으로는 이굿위크와 같은 대형 프로젝트를 진행할 때에는 PM 과 함께 프로젝트의 테크리드를 선임하고, 테크리드를 통해 프로젝트 전체의 기능과 성능을 체크하고, 서비스 아키텍처의 정합성을 확인하면서 안정적인 서비스를 구현하도록 할 예정입니다.

마무리

장애는 언제든지 발생할 수 있지만, 동일한 사유로 반복되지 않게 하는 것이 중요합니다.

매사에 최선을 다하더라도 시스템의 장애는 언제든지 발생할 수 있습니다. 특히 29CM 와 같이 빠르게 성장하는 서비스는 다른 어떤 서비스보다 장애 발생 가능성이 더 높을 수 밖에 없다고 봅니다. 이 때 장애 발생에 대한 책임 소재를 찾아가면서 따지는 접근보다는 우선 벌어진 문제를 빠르게 해결하고, 이후의 회고를 통해서 우리가 얻을 수 있는 배움을 발견하는 것이 중요하다고 봅니다. 그리고 이러한 배움을 기반으로 이후의 실행에서는 좀 더 나은 방안을 찾는 것이 팀의 지속적인 성장에 도움이 된다고 생각합니다.

특정한 장애 상황과 대응 과정을 상세히 정리하여 공유하는 것은 다소 부끄러울 수도 있지만, 저희는 이굿위크의 장애를 통해서 안정적인 서비스 구현과 운영을 위한 두가지 배움을 얻었다고 생각합니다. 그리고 이를 통해 내년의 이굿위크에서는 장애 없이 고객 분들에게 양질의 제품 경험을 제공하고자 합니다.

이러한 공유가 함께 성장하는 다른 팀과 개발 동료분들에게도 도움이 되었으면 하는 바람입니다. 감사합니다.

29CM CAREER

함께할 동료를 찾습니다.🚀
29CM는 ‘고객의 더 나은 선택을 돕는다’라는 미션으로 출발했습니다. 우리는 우리만의 방식으로 콘텐츠를 제공하며, 브랜드와 고객 모두에게 대체 불가능한 커머스 플랫폼을 만들어가고 있습니다. 이 미션을 이루기 위해 우리는 흥미로우면서도 복잡한 문제들을 해결하고 있습니다. 만약 우리와 함께 이 문제들을 해결해 보고 싶다면, 주저하지 말고 29CM에 합류하세요!

29CM 채용 페이지 : https://www.29cmcareers.co.kr
채용이 완료되면 공고가 닫힐 수 있으니 빠르게 지원해 주세요!

--

--

Greg Lee
29CM TEAM

Musinsa Head of Engineering / Software Architect