MongoDB와 Redis는 기본적으로 분산 트랜잭션이나 관계형 데이터베이스에서 사용하는 트랜잭션을 완벽하게 지원하지 않는다.
두개를 동시에 사용하면서 데이터 변경 작업을 진행할 때 트랜잭션을 구현하는 것은 어렵다. 하지만 몇 가지 방법으로 트랜잭션과 유사한 일관성을 유지할 수 있다.
MongoDB의 트랜잭션 한계
MongoDB는 기본적으로 단일 도큐먼트 수준의 원자성을 보장한다. 즉, 한 도큐먼트 내의 모든 쓰기 연산은 원자적으로 처리된다.
MongoDB 4.0부터는 다중 도큐먼트를 대상으로 한 트랜잭션을 지원하지만, 다음과 같은 한계가 있다.
- Replica Set이나 Sharded Cluster 환경에서만 트랜잭션 사용 가능
- 트랜잭션은 성능 저하를 야기할 수 있음
- 기본적으로 트랜잭션은 60초 안에 완료되어야 함
Redis의 트랜잭션 한계
Redis는 MULTI/EXEC 명령어를 통해 간단한 트랜잭션을 제공한다. 하지만 다음과 같은 한계가 있습니다.
- Redis는 롤백을 지원하지 않으며, 실행 중 오류가 발생하면 나머지 명령도 그대로 처리됨
- 분산 환경에서 트랜잭션 보장은 어려움
MongoDB와 Redis를 하나의 트랜잭션처럼 사용하기 어려운 이유
MongoDB와 Redis는 서로 다른 데이터 모델과 작동 방식을 가지기 때문에 둘을 하나의 작업 단위로 묶는 트랜잭션을 구현하기가 어렵다.
- ACID 보장의 한계: MongoDB는 다중 도큐먼트 트랜잭션을 지원하지만, Redis는 완전한 ACID 트랜잭션을 지원하지 않음
- 분산 환경의 복잡성: 두 시스템은 각각의 복제 및 클러스터링을 사용하므로, 분산 트랜잭션 관리가 까다로움
- 복구의 복잡성 : 트랜잭션 중 한쪽이 실패했을 때 복구를 수행하는 것이 복잡함
트랜잭션 대안
2단계 커밋 방식 흉내내기
- MongoDB 업데이트 후 Redis 업데이트:
- MongoDB에서 업데이트를 수행합니다.
- MongoDB 업데이트가 성공적으로 완료되면 Redis 업데이트를 진행합니다.
- Redis 업데이트 실패 시 롤백 처리:
- Redis 업데이트 중 오류가 발생하면 MongoDB 업데이트를 보상하거나 롤백 로직을 구현합니다. (주의: MongoDB는 본질적으로 롤백을 지원하지 않으므로 복잡할 수 있음.)
아웃박스 패턴과 최종 일관성(Eventual Consistency)
- 변경 로그 저장:
- MongoDB에 업데이트 대신 아웃박스 테이블을 추가하여 변경 로그를 저장합니다.
- 작업자 활용:
- 별도의 작업자가 변경 로그를 읽고 Redis 업데이트를 비동기로 수행합니다.
- 최종 일관성 보장:
- 시스템에 약간의 지연을 허용하면서 데이터를 일관되게 유지합니다.
사가 패턴(Saga Pattern)
- 보상 트랜잭션 활용:
- MongoDB 업데이트 후 Redis 업데이트가 실패하면, MongoDB 상태를 원래대로 복구하는 보상 작업을 수행합니다.
- 분산 작업 관리:
- 각 작업 단계를 독립적으로 처리하고, 실패 시 복구 단계를 트리거합니다.
따라서, MongoDB 와 Redis를 하나의 트랜잭션으로 관리하는 것은 쉽지 않다.
각 방법은 일관성 , 복잡성, 성능에 따라 요구사항에 맞게 선택해서 사용해야하며, 완벽한 트랜잭션 대신 최종 일관성(Eventual Consistency)을 목표로 설계하면 현실적인 대안을 구현할 수 있다.
반응형
'백엔드 > Spring' 카테고리의 다른 글
[Spring] Spring MongoTemplate에서 @LastModifiedDate와 Auditing 사용 (0) | 2024.12.02 |
---|---|
[Spring] MongoDB - MongoTemplate 과 Auditing (0) | 2024.12.01 |
[Spring] Spring Web MVC, WebFlux 의존성 동시 사용 (0) | 2024.11.28 |
[Spring] Reactive MongoDB Stream의 Flux, Mono 조회 방법 비교 (0) | 2024.11.22 |
[Spring] ReactiveMongoTemplate vs ReactiveMongoRepository (0) | 2024.11.07 |