Circuit Breaker 적용기 1편
Convoy Effect
현재 내가 속한 개발 파트는 회사 사이트가 아닌 외부 제휴사에 셀러로 입점하여 상품을 제휴사 DB에 동기화하고, 제휴사 DB에 있는 주문/반품/교환 데이터를 회사 DB로 동기화하는 역할을 수행한다. 입사 당시에 회사의 시스템은 카프카를 사용한 이벤트 기반 아키텍처로 구성되어 있었다. 프로듀서에서는 특정 토픽으로 상품을 등록시키는 이벤트, 상품을 수정시키는 이벤트 등을 발행하고 있고, 컨슈머에서는 토픽으로 들어온 레코드를 읽어서 제휴사 API를 통해 제휴사 상품 데이터와 회사의 상품 데이터를 동기화하는 작업을 수행한다. 정리하면 아래 그림과 같이 동작한다.
병렬처리를 위해 파티션별 컨슈머가 1:1 할당되었기 때문에 평상 시에는 컨슈머 랙이 아주 작다. 발행되는 순간 거의 바로 처리가 된다. 아래 사진과 같이 평상 시에는 컨슘 속도가 발행 속도와 동일하거나 빠르다.
하지만, 특정 상황에 컨슈머 랙이 아주 커진다. 두가지 케이스로 인해서 컨슈머 랙이 커질 수 있다. 첫번째 케이스는 신규 제휴사에 입점하였을 때, 판매중인 전체 상품(대략 70만)을 제휴사에 등록하기 위해서, 프로듀서에서 상품 등록 이벤트를 대량 발행할 때이다. 두번째 케이스는 특정 제휴사에서 API 타임아웃을 발생시킬 때이다. 내가 겪은 컨슈머 랙이 커지는 상황은 신규 제휴사에 입점하였는데, 신규 제휴사에서 API 타임아웃을 발생시킨 상황과 기존 제휴사에서 타임아웃을 발생시키는 상황이 있었다.
첫번째 케이스의 경우, 프로듀서에서 이벤트(상품 등록) 발행하는 건수를 조절하면 컨슈머 랙을 조절할 수 있다. 하지만, 두번째 케이스의 경우는 우리 회사에서 통제 할 수 없는 케이스이다. 파티션 별로 컨슈머가 할당되더라도, 특정 제휴사에서 API 타임아웃을 발생시킨다면, 파티션에는 커밋되지 않은 레코드가 계속 쌓이게 된다. 이러한 케이스를 나는 Convoy Effect와 동일하다고 보았다.
현재 회사의 시스템은 제휴사마다 토픽을 생성하여 운영/관리하기 어려운 상황이라, 각 제휴사에 발행되는 이벤트가 동일한 토픽에 적재되고 있다.
특정 제휴사에서 타임 아웃을 발생시킨다면, 다른 제휴사에서 빠르게 응답을 준다고 하더라도, 앞서 오래 걸리는 제휴사의 이벤트가 처리되기를 이벤트 큐에서 계속 기다리는 현상이 발생한다.
그렇게 되면, 판매되지 않아야할 상품이 제휴사에서 판매될 수도 있고, 잘못된 가격 데이터로 판매가 될 수도 있다.
우리 파트의 목표는 최대한 빠르게 외부 제휴사 DB와 회사 상품 DB의 정합성을 보장해야 한다. 그렇지 않으면 고객은 상품을 받지 못할 수도 있고, 회사의 경우 매출에 손실이 발생할 수도 있다.
우리는 제휴사마다 토픽을 만들지 않는한, OS의 Convoy Effect처럼 이러한 현상들을 앞으로 신규 제휴사를 입점할 때마다 고려를 해야한다.
해결 방안
가장 간단하게 각각의 제휴사마다 영향을 주지 않게 이벤트를 처리하는 방법은 신규 제휴사를 입점시킬때마다, 제휴사 전용 토픽을 할당하는 것이다. 제휴사마다 전용 토픽을 할당하면, 특정 제휴사의 통신 장애, 카프카 토픽 장애, 컨슈머 장애 등을 다른 제휴사로 전파하지 않게 만들 수 있다. 가장 간단하지만, 단점도 존재한다. 우선, 제휴사를 입점할때마다 토픽을 늘려야하기 때문에 토픽 운영 포인트가 늘어나게 된다. 현재 카프카의 경우 카프카 관리자가 따로 존재하고, 실제 운영자가 담당하지 않기 때문에 카프카 관리자에게 운영건을 부여하는 상황이 된다. 뿐만 아니라, 새로 생긴 토픽의 파티션마다 컨슈머를 붙혀야하고, 이는 새로운 프로젝트 혹은 새로운 컨슈머 로직을 만들어야한다.
그래서 카프카 운영 이슈 때문에 새로운 제휴사가 생기더라도, 공통 토픽을 사용하기로 결정하였다. 대신 컨슈머 개수를 충분히 늘려 이벤트 처리 속도를 분산 처리하도록 구성하였고 로직 또한 재사용성을 늘리도록 구현하였다. 특정 제휴사의 장애가 이벤트 파이프라인에 영향이 가지 않도록 API 로직에 써킷 브레이커를 도입하기로 결정하였다. 제휴사 마다 모두 공용 토픽을 사용하기로 결정하였기 때문에, 이벤트 실패건을 어떻게 처리할 것인가가 상당히 중요하다고 판단하였다. 관련하여 서킷 브레이커 사용과 이벤트 재처리 로직에 대해서 추후에 기술하려고 한다.
Reference
- https://www.youtube.com/watch?v=ThLfHtoEe1I
- https://www.youtube.com/watch?v=PBiZLvlx_zk
- https://techblog.woowahan.com/15694
- https://engineering.linecorp.com/ko/blog/try-armeria-circuit-breaker
- https://blog.hwahae.co.kr/all/tech/14541
- https://mangkyu.tistory.com/261
- https://bcho.tistory.com/1247
- https://resilience4j.readme.io/