2011-04-07 2 views
18

현재 CQRS 및 Event Sourcing 아키텍처를 평가 중입니다. 나는 이런 종류의 디자인을 사용함에 따른 유지 보수의 의미를 이해하려고 노력하고있다. 답변을 찾기 위해 애쓰는 두 가지 질문은 다음과 같습니다.CQRS + Event Sourcing Architecture에서 ViewModel 변경을 관리하는 방법

1) 잠시 애플리케이션을 실행 한 후 실행하면, ViewModel에 추가 필드를 추가해야하는 상황이 발생합니다. ReadModel 데이터베이스? 예를 들어 이전에 CustomerList ViewModel에 Customer Zip Code가 필요하다고 가정 해보십시오. 따라서 추가 열을 ViewModel 데이터베이스에 쉽게 추가 할 수는 있지만 어떻게 채워지나요? 내가 알 수있는 한, 유일한 방법은 읽기 데이터베이스를 지우고 모든 이벤트를 처음부터 재생하여 ReadModel Datbase를 백업하는 것입니다. 그러나 응용 프로그램이 몇 달 또는 몇 년 동안 실행되고 실행 중이면 (원하는대로) 어떻게됩니까? 이는 zipcode 열의 데이터를 추가하기 위해 재생할 수있는 수백만 건의 이벤트 일 수 있습니다.

기술적 이유가 무엇이든간에 ReadModel 데이터베이스가 동기화되지 않았거나 새 ReadModel 데이터베이스를 추가하려는 경우 동일한 우려가 있습니다. 응용 프로그램이 오래되면서 사용 된 것처럼 보입니다. 사용이 많을수록 최신 readmodel을 다시 가져 오는 것이 더 어렵고 비용이 많이 듭니다. 또는 어딘가에서 트릭을 놓치고 있습니까? ReadModel 스냅 샷과 같은 것이 있습니까?

2) 수백만 개의 이벤트가 재생되어 읽기 데이터베이스를 빌드 한 후 일부 데이터가 예상과 일치하지 않으면 (즉, 잘못 보입니다) 어떻게 될까요? 이벤트를 저장하거나 비정규 화하는 루틴의 어딘가에있는 버그가 원인 일 수 있다고 생각됩니다 (그리고 코딩에 의존 할 수있는 것이 있다면 버그입니다). 이것을 디버깅하는 방법! 그것은 불가능한 일처럼 보입니다. 아니면 다시 한 번 트릭을 놓치고 있습니다.

잠시 동안 이와 같은 시스템을 운영 해본 사람이라면 어떻게 유지 보수 및 업그레이드 경로가 효과가 있었는지 들어 주시면 감사하겠습니다.

언제든지 입력 해 주셔서 감사합니다.

답변

16

CQRS를 사용하여 이벤트 소싱을 사용함에있어서의 장점은 읽은 모델을 파기하고 처음부터 다시 작성하는 것입니다. 어떤 이유로 사람들은 당신이 임의의 수의 이벤트를 초과하면 오랜 시간이 걸릴 것이라는 생각을 가지고 있습니다. 읽기 모델에 대해 관계형 데이터베이스를 사용하고 있으며 트랜잭션을 열어서 핸들러를 통해 모든 이벤트를 읽고 트랜잭션을 커밋하는 것이 쉽습니다. 트랜잭션이 실제로 디스크에 닿는 경우에만 해당됩니다. 그 밖의 모든 것은 메모리에서 수행되므로 번개가 빠르다. 사실, 몇 분 안에 몇 백만 건의 이벤트를 통해 시스템이 작동하는 것을 보아도 놀라지 않을 것입니다.

처음부터 읽은 모델을 재구성하는 것은 매일 읽은 모델에 이벤트를 비정규 화하는 일상적인 방법과 똑같은 방식으로 표시해야합니다. 그렇지 않은 경우, 읽은 모델의 비정규 화 코드에 버그가 있습니다. 여기서 중요한 점은 메시지 처리기 관점에서 정규/프로덕션 시나리오 및 읽기 모델 재 작성 시나리오에서 수신되는 이벤트와 비정규 화 된 이벤트가 차이가 없다는 것입니다.

버그가 발생하면 프로덕션 이벤트를 로컬 워크 스테이션에 스트리밍/복사하고 처리기에 중단 점을 설정 한 다음 읽기 모델 처리 코드를 통해 해당 이벤트를 실행하여 쉽게 디버그 할 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 이벤트 재생 시간에 대한 귀하의 의견은 (심지어 수백만 건의 사건이 있더라도) 안심할 수 있습니다. 나는 당신의 블로그를 BTW, 공유 주셔서 감사합니다! – James

+1

잘못 입력하면 뷰 모델 모집단 *이 느려질 수 있으므로 테스트를하고 싶을 것입니다. 빨리하기 위해 약간의 노력이 필요합니다. –

+0

우리는 프로덕션에 이르기까지 매번 읽기 모델을 연습하거나 다시 작성했습니다. 우리는 먼저 데이터를 무대 읽기 모델로 푸시하고 재구성이 성공하면 재 작성을 수행하여 프로덕션 읽기 모델로 푸시합니다. 우리에게는 읽기 모델이 각 릴리스의 이벤트 핸들러에 대한 모든 수정 사항을 반영하도록합니다. –

1

나는 CQRS에 다소 익숙하기 때문에 이것이 가장 적합한 경로는 아니지만 (iirc는 CQRS/DDDD 메일 링리스트 중 하나에서 선택했습니다).

한 번 실행해야하는 목적에 맞는 명령과 해당 처리기를 만든 다음 사용되지 않습니다.

핸들러에서 우리는 편리한 메커니즘을 사용하므로 우편 번호 필드를 추가하는 경우 다른 시점에서 우편 번호를 가져 와서 새로운 열을 채우는 일회성 쿼리를 실행할 수 있습니다 . 우리는 이러한 시나리오에서 아키텍처 순도에 대해 크게 걱정하지 않습니다. 이는 일회성 작업으로 예상되기 때문에 (Rob Conery's Massive은 이러한 상황에서 성공과 함께 사용되었습니다).

1

아직 이벤트 준비와 함께 cqrs를 사용하는 프로덕션 준비가 된 앱이 없으므로 여기에 빌드를 시도하는 것은 내 경험입니다.

1) Read Model rebuild. 네, 기본적으로 Read Model DB가 변경되면 전체 Read Model DB를 다시 빌드해야합니다. 그리고 많은 사건이 있다면, 이것은 오랜 시간이 걸릴 수 있습니다. 따라서 Read Model 재구성은 고도로 최적화되어야합니다 (이벤트 일괄 처리 사용 등). 높은 소위 읽기 - 쓰기 비율이있는 경우 이벤트 소싱이 가장 적합하다고 생각합니다. 따라서 매우 휘발성 인 데이터의 경우 도메인 이벤트로 저장하지 않는 것이 좋습니다. 그러나 스토리지 용량에 대한 질문도 그다지 멀지 않습니다. 어쨌든 시스템에 가장 적합한 부분 (예 : 이벤트의 일부로 그래픽 이미지를 저장하지 않음)에 cqrs를 적용 할 수 있습니다.

2) Debugging. 이벤트 저장에 오류가있을 가능성은 거의 없으며 (프레임 워크의 관심사 여야 함) 저장소에있는 이벤트를 항상 쉽게 확인할 수 있습니다. 예상되는 이벤트를 생성하는 명령에 대해서는 여기서 테스트해야하며이 테스트는 시스템에서 가장 중요한 테스트 일 것입니다. 비정규 화기에 대해서도 테스트를 할 수는 있지만, 그들의 핵심성을 육안으로 볼 수 있다면 사소한 비정규 화기에 대한 테스트를 작성하는 것을 신경 쓰지 않을 것입니다. 즉, 더 복잡한 비정규 화기에서 문제를 찾기 위해 디버거를 몇 번 사용했습니다. 어떤 사건으로 일이 잘못 될지 결정하는 것은 그다지 재미 있지 않았습니다.

0

모델에 netting 이벤트를 추가 할 수도 있습니다. X 수의 이벤트가 수신 된 후 임의의 작업으로 실행할 수 있습니다 (예 : 500)

다시 작성하려면 netting 이벤트가 발생할 때까지 이벤트를 스택으로 밀어 넣습니다. 여기에서 기준선으로 사용됩니다. 스택에서 이벤트를 팝하여 기본 이벤트로 값을 집계합니다.

관련 문제