Posts [MSA] Kafka 도메인 이벤트 순서 보장하기
Post
Cancel

[MSA] Kafka 도메인 이벤트 순서 보장하기

MSA환경에서 Kafka를 활용한 데이터 동기화 포스팅에서 MSA환경에서 카프카를 활용하여 두 마이크로서비스간의 데이터를 동기화하기 위한 방법들에 대해 알아보았고 아래 이미지처럼 4가지 경우의 수애 대해서 알아보았다.

스크린샷 2023-04-08 오후 4 56 48

도메인 이벤트별 토픽 나누는 방식의 단점(3, 4)

도메인 이벤트 별 토픽 나누는 방식(order-create-topic, order-cancel-topic, order-change-topic)의 단점은 컨슈머의 처리 순서에 대해 보장할 수 없다는 점이다.

스크린샷 2023-04-08 오후 5 15 45

예를 들어, 주문 생성되어야 했을 때 처리되어야 하는 로직이 30초가 걸리고, 주문이 취소 됐을 떄 처리되는 로직이 5초가 걸린다고 해보자.(극단적으로 이해를 돕기 위한 예시이다)

만약 주문이 생성되자마자 바로 취소 이벤트가 발생한다고 해보자. 그렇게 됐을 떄 주문이 생성되는 와중에 취소 처리를 하기 때문에 데이터 정합성이 안맞거나 로직에서 문제가 발생하게 될 것이다. 생성된 주문이 없음에도 주문 취소 처리를 하게 되기 때문이다.

하지만 모든 것을 완벽하게 방어 코딩을 작성해서 모든 것을 해결할 수도야 있겠지만 코드가 너무 복잡해지고 가독성도 떨어지게 될것이다.

또한 컨슈머 애플리케이션에 장애가 발생하여 shutdown되었을때도 문제가 된다.

스크린샷 2023-04-08 오후 5 20 34

소프트웨어 개발에서 중요한 점 중 하나는 장애 복구이다. 장애가 발생했을때 이를 쉽고 완벽하고 빠르게 복구를 할 수 있어야 한다.

주문 마이크로서비스에 장애가 발생하고 다시 재기동을 했을 때 컨슈머는 consume 하지 못한 offset의 메시지부터 읽을 것이다.

그런데 어느 토픽의 메시지부터 읽는다는 것을 보장할 수가 없게 된다.(주문 생성 토픽부터 다 처리하고, 주문 취소 이벤트 다처리하고, 주문 변경이벤트 다처리해라 라는 식으로 할수가 없다.)

위와 같은 문제들로 인해 도메인 이벤트별 토픽을 나누는 방식은 장애에 취약하다 볼 수 있다.

그렇다면 고민해야될 포인트는 도메인 이벤트별 토픽으로 나눴을때의 Zero-Payload 방식과 Full-Payload 방식이다.

두 방식에 대해 깊은 고찰을 했을 떄 두 방식 큰 문제가 없어보인다.

하지만 우형 기술블로그에서는 아래와 같은 설명을 하고 있다.

스크린샷 2023-04-08 오후 5 28 13출처: 우아한형제들 기술블로그

이벤트 순서 보장 문제를 해소한는 방식으로 사용된다고 하는데 이 부분은 사실 어떠한 순서 문제가 발생하는지에 대해 생각이 나질 않는다. 페이로드에 외부시스템에 대한 의존을 제거하여 느슨한 결합을 만들 수 있는 장점은 공감이 되는 것 같다.

카프카 파티션을 활용한 이벤트들의 순서 보장

위의 내용까진 단일 파티션으로 구성된 토픽을 기준으로 설명을 했다.

근데 서비스가 점점 확장되어 커져가게 되면 하나의 파티션으로 이를 다처리하는데는 너무 큰 지연시간이 발생할 것이다.

이 문제에 대해선 아래 출처에 기재된 포스팅들에서 잘 설명을 하고 있다.

바로 원본 Data의 PK를 카프카 Message Key로 사용해 Kafka의 Topic에 Partitioning 하는 것이다.

주문 데이터의 파티션을 3개로 늘리고 주문 순번값을 기준으로 파티션을 하면 하나의 주문 데이터에 대해선 동일한 파티션에 메시지가 발행될 것이다. 왜냐하면 순번값에 대해 해쉬함수를 적용해 나온 값을 기준으로 어느 파티션에 메시지를 보내게 될 지 정하기 때문이다.</b>

스크린샷 2023-04-08 오후 5 42 53

예를 들어, 1번 주문 데이터와 관련된 도메인 이벤트 메시지는 0번 파티션으로만 쌓이게 될 것이고, 2번 주문 데이터와 관련된 도메인 이벤트 메시지는 1번 파티션으로만 쌓이게 될 것이다.

따라서 도메인 이벤트들에 대한 순서 보장이 사라지게 된다.

위 포스팅에 대해 잘못된 내용 또는 추가되면 좋을 것 같은 내용이 있다면 아래 코멘트로 언제든 피드백 부탁드립니다😀

출처

This post is licensed under CC BY 4.0 by the author.