반응형

Distributed System 8

12편. 운영 가능한 Event-driven System 체크리스트

Event-driven은 설계보다 운영에서 실패한다Event-driven Architecture는 설계 단계에서는 그럴듯해 보인다.문제는 운영 단계다.이벤트가 늦게 처리된다중복 이벤트가 쌓인다어디서 막혔는지 알 수 없다운영 가능한 Event-driven System은 “잘 돌아간다”가 아니라문제가 생겼을 때, 우리가 통제할 수 있다는 기준으로 평가되어야 한다.1. Event 정의 체크리스트이 이벤트는 요청이 아니라 사실인가아무도 소비하지 않아도 시스템이 괜찮은가이벤트 이름이 과거형으로 표현되는가의도가 아니라 상태 변화를 표현하는가이 질문에 답하지 못하면, 그것은 Event가 아니다.2. Producer 체크리스트Producer가 Consumer의 존재를 모르는가Consumer 처리 성공 여부를 고려하지 ..

11편. Event-driven Architecture의 안티패턴

Event-driven이 항상 좋은 선택은 아니다Event-driven Architecture는 문제를 해결하는 구조이지, 만능 해법이 아니다.EDA가 실패하는 경우를 보면 기술이 아니라 사용 방식이 문제인 경우가 대부분이다.이 글에서는 Event-driven 시스템을 망가뜨리는 대표적인 안티패턴을 정리한다.안티패턴 1. 이벤트로 RPC 흉내내기가장 흔한 안티패턴은 Event를 비동기 RPC처럼 사용하는 것이다.이 이벤트는 반드시 처리되어야 한다처리 결과를 알고 싶다실패하면 바로 문제다이 기대가 생기는 순간, Event-driven의 핵심 전제가 깨진다.Event에는 응답이 없다응답이 필요하다면, 그것은 Event가 아니라 Command다.안티패턴 2. 이벤트 남용모든 상태 변경을 무작정 이벤트로 만들면..

8편. 이벤트 스키마는 왜 계약(Contract)인가

이벤트는 코드가 아니라 약속이다이벤트를 처음 설계할 때는 대부분 이렇게 생각한다.필요한 필드만 담으면 된다나중에 바꾸면 된다하지만 Event-driven 시스템에서 이벤트는 단순한 데이터 구조가 아니다.이벤트는 Producer와 Consumer 사이의 계약이다이 계약을 가볍게 다루는 순간, 시스템은 조용히 망가지기 시작한다.왜 이벤트 스키마 변경은 위험한가동기 API에서는 스키마 변경이 비교적 명확하다.컴파일 오류런타임 예외하지만 이벤트 스키마 변경은 다르다.Producer는 정상 동작한다Consumer는 조용히 실패한다이 실패는 즉시 드러나지 않고, 시간이 지나서야 발견된다.그래서 이벤트 스키마 변경은 가장 위험한 변경 중 하나다.이벤트는 누가 소유하는가이벤트를 소유하는 주체를 명확히 하지 않으면 혼란..

7편. 이벤트는 어디에서 발생해야 하는가

이벤트는 아무 데서나 만들어지면 안 된다Event-driven Architecture를 도입하면 가장 먼저 마주치는 질문이 있다.이 이벤트는 어디에서 발생시켜야 하는가이 질문에 대한 답이 흐려지면, 시스템은 빠르게 혼란에 빠진다.같은 의미의 이벤트가 여러 곳에서 발생한다DB 변경이 그대로 이벤트가 된다Consumer가 Producer의 내부 구현에 의존한다이벤트 발생 지점은 설계의 핵심이다.이벤트는 상태 변화의 결과다Event는 무엇을 하겠다는 의도가 아니다.Event는 항상 다음을 의미해야 한다.상태 변화가 이미 발생했다즉, 이벤트는트랜잭션이 성공한 이후되돌릴 수 없는 시점에발생해야 한다.이 원칙이 깨지면, 이벤트는 신뢰할 수 없게 된다.Domain Event란 무엇인가Domain Event는 도메인 ..

6편. 이벤트 순서는 왜 보장되지 않는가

순서는 직관적이지만 위험한 가정이다사람은 자연스럽게 순서를 기대한다.먼저 일어난 일나중에 일어난 일그래서 이벤트를 설계할 때 무의식적으로 이런 가정을 깔게 된다.이 이벤트는 저 이벤트 뒤에 온다하지만 Event-driven 시스템에서 이 가정은 가장 쉽게 깨진다.분산 환경에는 하나의 순서가 없다이벤트 순서가 보장되려면 다음 조건이 필요하다.단일 생성 지점단일 전달 경로단일 소비자Event-driven Architecture는 이 조건을 의도적으로 포기한다.그 결과, 전역적인 순서는 존재하지 않는다.이벤트는 언제든 다른 순서로 도착할 수 있다이벤트 순서가 깨지는 이유는 명확하다.네트워크 지연재시도에 의한 재전송Consumer 처리 속도 차이이 중 어느 하나만 있어도, 이벤트는 발생 순서와 다른 순서로 처리..

5편. Exactly-once를 포기해야 하는 이유

Exactly-once는 왜 매력적으로 보이는가Event-driven 시스템을 설계하다 보면 자연스럽게 이런 요구가 등장한다.이 이벤트는 정확히 한 번만 처리되면 좋겠다이 요구는 합리적으로 보인다.중복 처리 걱정이 없다상태 불일치가 사라진다로직이 단순해진다문제는 이 요구가 Event-driven 시스템의 전제와 정면으로 충돌한다는 점이다.Exactly-once가 의미하는 것Exactly-once는 흔히 오해된다.이벤트가 한 번만 전달된다Consumer가 한 번만 실행된다하지만 실제로 의미하는 바는 이것이다.결과가 한 번만 반영된다문제는 이 결과가여러 시스템에 걸쳐 있고여러 저장소에 나뉘어 있으며여러 시점에 반영된다라는 점이다.왜 Exactly-once는 구조적으로 불가능한가Exactly-once가 어려운..

4편. Event-driven Architecture의 실패 모델

Event-driven 시스템에서 실패는 예외가 아니다Event-driven Architecture를 도입하면 많은 팀이 이렇게 기대한다.이벤트는 빠르게 전달된다처리는 자연스럽게 병렬화된다장애에 강해진다하지만 운영 단계에서 가장 먼저 마주치는 현실은 이것이다.이벤트는 자주 늦고, 가끔 중복되며, 때로는 순서가 깨진다이 현상은 설계 실패가 아니라 Event-driven 시스템의 기본 특성이다.실패 모델을 이해하지 못하면 생기는 일실패 모델을 이해하지 못한 시스템은 다음과 같은 반응을 보인다.중복을 버그로 간주한다순서 깨짐을 예외 처리한다지연을 장애로 오인한다이 순간부터 EDA는 불안정한 시스템이 된다.실패를 제거하려 할수록, 시스템은 더 복잡해진다.실패 모델 1. 이벤트 유실이벤트 유실은 가장 두려워하는 ..

1편. Event-driven Architecture는 왜 등장했는가

시스템은 언제부터 복잡해지는가시스템은 처음부터 복잡하지 않다.하나의 서비스, 하나의 데이터베이스, 하나의 요청 흐름.문제는 요구 사항이 늘어날 때 시작된다.기능이 늘어난다팀이 나뉜다시스템이 분리된다이 시점에서 대부분의 시스템은 동기 호출 구조를 그대로 유지한다.동기 호출은 왜 처음엔 좋아 보이는가동기 호출은 직관적이다.요청하면 응답이 온다흐름이 눈에 보인다에러 처리도 단순하다그래서 시스템 초반에는 동기 호출이 거의 항상 선택된다.문제는 이 구조가 확장될수록 비용이 기하급수적으로 증가한다는 점이다.결합은 호출에서 시작된다동기 호출은 단순한 통신 방식이 아니다.다음 가정들을 함께 가져온다.상대 시스템은 항상 살아 있다응답은 빠르게 온다지금 이 타이밍에 호출해도 괜찮다이 가정이 깨지는 순간, 호출자는 영향을 ..

반응형