여러 곳에 데이터를 저장해야 하는 필요성
동일한 데이터를 여러 장소에 저장하고 잠재적으로 다른 형식을 저장해야 하는 경우가 있다. 이를 구체화된 뷰(Materialized view) 라고 한다.
다음 이러한 사계의 몇가지 에이다
- 영구 데이터 저장소에 있는 데이터도 별도의 인 메모리 저장소에 캐시해야 읽기 작업이 짧은 대기 시간으로 캐시에서 처리될 수 있다.
- 쓰기 작업은 영구 데이터 저장소와 메모리 내 저장소를 모두 업데이트해야 합니다.
- 분산된 키-값 저장소에 저장된 데이터는 ElasticSearch 또는 Solr 과 같은 효율적인 전체 텍스트 검색을 제공하는 별도의 데이터 저장소에도 저장되어야 한다.
- 읽기 작업의 형태에 따라 최적의 성능을 위해 적절한 데이터 저장소를 사용할 수 있습니다.
- 관계형 데이터베이스에 저장된 데이터도 그래프 데이터베이스에 저장해야 그래프 쿼리를 보다 효율적으로 수행할 수 있다.
이중 쓰기를 통한 데이터 동기화
한 가지 접근 방식은 업데이트 작업을 수신하는 단일 애플리케이션에서 연결된 모든 데이터 저장소에 쓰기를 수행하는 것이다. 이 접근 방식을 이중 쓰기 라고도 한다. 일반적으로 연결된 데이터 저장소에 대한 쓰기는 업데이트 작업이 성공했다는 확인으로 클라이언트에 응답하기 전에 모든 위치의 데이터를 업데이트하기 위해 동기식으로 수행된다.
이중 쓰기의 단점과 해결책
이중 쓰기에 대한 한가지 단점은 시스템이 부분오류가 발생하여 원자성을 잃어버릴수 있다는 것이다.
애플리케이션이 첫 번째 데이터 저장소를 성공적으로 업데이트했지만 두 번째 데이터 저장소 업데이트 요청이 실패하면 원자성이 위반된다. 이로 인해 전체 시스템이 일관성을 잃게 된다. 또한 이 경우 데이터가 업데이트되었기 때문에 일부 클라이언트에 대한 응답이 무엇인지 명확하지 않을 수 있다.
이러한 문제를 해결하기 위한 확실한 방법은 2단계 커밋 및 2단계 잠금의 조합과 같이 필요한 원자성 및 격리를 제공하는 분산 트랜잭션 프로토콜을 도입하는 것이다. 이를 수행하려면 기본 데이터 저장소가 이에 대한 지원을 제공해야 한다.
Event Sourcing
이벤트 소싱은 데이터 동기화를 위한 또 다른 접근 방식이다.
모든 업데이트 작업을 추가 전용 이벤트 로그에 기록한다. 관심 있는 애플리케이션은 이 로그의 이벤트를 소비하고 관련 데이터를 기본 데이터 저장소에 저장한다.
또힌 애플리케이션은 일반적으로 오류가 발생할 경우 전체 로그를 다시 사용할 필요가 없도록 상태의 주기적 스냅샷을 저장한다. 이 경우 오류를 복구하는 애플리케이션은 최신 스냅샷 이후의 로그 이벤트만 재생하면 된다.
이중 쓰기 문제 완화
이벤트 소싱 접근 방식은 원자성을 위반하지 않는다. 이는 원자성 커밋 프로토콜이 불필요 하다는 것을 뜻한다. 그 이유는 모든 애플리케이션이 로그를 독립적으로 소비하고 결국 모든 이벤트를 성공적으로 처리하고 일시적인 오류가 발생할 경우 마지막으로 소비된 이벤트에서 다시 시작되기 때문이다.
애플리케이션이 모든 이벤트를 동일한 순서로 소비하므로 이중 쓰기 접근 방식의 격리 문제도 해결 된다.
이벤트 소싱 접근 방식의 주의 사항
애플리케이션은 로그의 이벤트를 다양한 속도로 사용할 수 있다. 이는 이벤트가 모든 애플리케이션에 즉시 반영되지 않음을 의미한다. 이 현상은 애플리케이션 수준에서 처리할 수 있다. 예를 들어 캐시에서 항목을 사용할 수 없는 경우 애플리케이션은 다른 데이터 저장소를 쿼리할 수 있다.
이 문제의 또 다른 문제는 신뢰할 수 있는 데이터 저장소에 아직 저장되지는 않았지만 성공적으로 인덱싱된 항목으로 인해 댕글링 포인터가 발생할 수 있다. 끊어진 링크를 표시하는 대신 이러한 항목을 식별하고 삭제하면 애플리케이션 수준에서 이 문제를 해결할 수 있다. 애플리케이션 수준에서 그러한 기술을 적용할 수 없는 경우 동시성 제어 프로토콜을 사용할 수 있다.
Change Data Capture (CDC)
변경 데이터 캡처(CDC)는 데이터 동기화에 사용되는 또 다른 접근 방식입니다. 이전 단원에서 설명한 대로 이벤트 소싱 로그의 비동기식 사용을 해결한다.
이벤트 소싱 문제 완화
CDC 접근 방식에서 애플리케이션은 모든 업데이트 작업이 수행되는 신뢰할 수 있는 데이터 소스로 데이터 저장소를 선택한다. 그런 다음 이벤트 소싱과 동일한 방식으로 나머지 모든 작업에서 사용되는 이 데이터 저장소에서 이벤트 로그를 생성한다. 이 기본 데이터 저장소는 필요한 트랜잭션 의미 체계와 기본 데이터의 변경 사항을 모니터링하여 이벤트 로그를 생성하는 방법을 제공해야 한다. 관계형 데이터베이스는 대부분 강력한 트랜잭션 보장을 제공하며 수행된 작업에 순서를 지정하고 주문 이벤트 로그를 제공할 수 있는 WAL(Write Ahead-Log)을 내부적으로 사용하므로 일반적으로 이에 적합하다.
결과적으로 클라이언트는 현재 상태에 대해 조건부 업데이트를 수행할 수 있으며 나머지 애플리케이션은 해당 데이터 저장소에서 이러한 작업을 독립적으로 적용할 수 있다.
참고