DB/MongoDB

[MongoDB] Read/Write 제어

꾸준함. 2023. 11. 29. 15:29

Read Preference

  • 읽기 요청 트래픽 분산 및 쓰기 요청 처리하는 primary 멤버 부하 방지를 위한 옵션

 

종류

 

Read Preference 종류는 총 5가지가 있으며 앞서 설명했다시피 주목적이 Read 요청 트래픽 분산 및 Write 요청 처리하는 primary 멤버 부하 방지이기 때문에 주로 secondary 혹은 secondaryPreferred로 설정합니다.

  • primary: 무조건 primary 멤버로 읽기 요청
  • primaryPreferred: 가능하면 primary 멤버로 읽기 요청을 보내고 없으면 secondary 멤버에 요청
  • secondary: 무조건 secondary 멤버로 읽기 요청
  • secondaryPreferred: 가능하면 secondary 멤버로 읽기 요청을 보내고 없으면 primary 멤버에 요청
  • nearest:  평균 ping 시간을 기반으로 지연율이 가장 낮은 멤버에 요청

 

https://www.mongodb.com/docs/manual/replication

 

 

Read Preference를 secondary로 설정할 수 있는 이유는 각 멤버마다 oplog가 있고 각 secondary 멤버들이 비동기로 primary 멤버의 oplog를 동기화하기 때문에 멤버들의 데이터가 eventually consistent 특성을 지니기 때문입니다.

한 유저가 SNS에 게시글을 올렸을 때 다른 유저들에게 바로 노출되지 않아도 무방하므로 이런 경우 read preference를 secondary로 설정해도 되지만 상품 구매처럼 주문 내용을 바로 확인할 수 있어야 하는 케이스에서는 read preference를 primary로 설정해야 합니다.

  • MongoDB의 주목적은 일관성 유지가 아닌 빠른 응답과 유연한 도큐먼트이기 때문에 후자 같은 케이스에서는 굳이 mongoDB의 read preference를 primary로 설정하면서 사용하기보다는 관계형 데이터베이스를 사용하는 것이 낫다고 판단합니다.

 

https://engineering.linecorp.com/ko/blog/LINE-integrated-notification-center-from-redis-to-mongodb

 

 

Write Concern

  • Replica Set 멤버들 간의 동기화 정도를 제어하는 옵션으로 주목적은 rollback 방지
  • 사용자에게 응답을 주기 전에 지정한 개수만큼 Primary 멤버로부터 Secondary 멤버에 복제를 완료해야 함
    • w가 1일 경우 write concern 적용 X
    • w가 2일 경우 Primary 멤버 외 1개의 멤버에 복제 후 응답
    • majority일 경우 과반수 이상의 멤버에 복제 후 응답
  • w를 높일수록 데이터 일관성을 보장하지만 성능 저하 우려
    • majority로 설정 시 과반 수 이상의 멤버에 복제를 완료하므로 무난
    • 높은 쓰기 성능이 요구사항일 경우 w=1

 

https://www.mongodb.com/docs/manual/core/replica-set-write-concern/

 

 

예시

 

두 개의 데이터 센터에 나뉘어 있는 5개의 멤버들로 구성된 replica set

  • Primary 멤버: oplog 기준 7번째 로그
  • Secodary 멤버: Primary 멤버와 같은 데이터 센터에 위치한 멤버는 Primary 멤버의 oplog 6번째 로그까지 복제 완료한 상태이며 다른 데이터 센터에 위치한 멤버들은 5번째 로그까지 복제 완료한 상태

 

 

 

데이터 센터 간 연결이 끊겨 과반수 이상 투표를 얻은 Secondary 멤버가 Primary 멤버로 승격, 기존 Primary 멤버는 Secondary 멤버로 전향

 

 

새로운 Primary 멤버는 기존 Primary 멤버의 oplog 기준 5번 째 로그까지만 복제된 상태에서 자체적으로 네 번의 Write 요청을 받아 oplog #9가 된 상황이고 같은 데이터 센터에 위치한 Secondary 멤버는 9번째 로그까지 복제 완료된 상황

이때 데이터 센터끼리 다시 연결이 되고 데이터 센터 #1에 위치한 멤버들은 새로 승격된 Primary 멤버 기준으로 복제를 해야 하기 때문에 기존 6, 7번째 요청 롤백 후 새로 승격된 Primary 멤버가 자체적으로 받은 네 번의 쓰기 요청을 복제

 

 

* 주의할 점: 롤백이 자동으로 이루어지는 것이 아니기 때문에 정책에 따라 롤백 처리 직접 구현 필요

 

Read Concern

  • 데이터를 읽어올 때 어떤 데이터를 읽어올지 설정

 

종류

 

Read Concern의 종류는 아래와 같이 5 가지입니다.

  • local: 복제 상태를 확인하지 않고 요청한 멤버의 현재 데이터 반환
  • available: local과 동일하지만 고아 document를 반환할 수 있음
  • majority: 과반수 이상의 멤버가 들고 있는 동일한 데이터 반환
  • linearizable: majority write 진행 중일 경우 완료될 때까지 대기 후 majority write가 반영된 결과 반환
  • snapshot: 특정 시점에 대한 결과를 반환 (Point-In-Time 쿼리)

 

* 고아 document는 앞선 Write Concern 예제와 같이 Secondary 멤버들이 Primary 멤버의 oplog를 복제하기 전 이상이 생기고 별도 트랜잭션 처리를 지정하지 않을 경우 발생할 수 있습니다.

 

https://m.blog.naver.com/ijoos/221284913886

 

 

MongoDB 5.0 기준 Read & Write Concern

 

MongoDB 5.0 기준 Read Concern은 Primary와 Secondary 멤버 모두 local

MongoDB 5.0 기준 Write Concern은 디폴트 값으로 Majority

  • 복제 성능이 좋아짐에 따라 안정성을 보다 중시하는 방향

 

Casual Consistency

  • Read Concern linearizable과 유사한 개념으로 일관성을 위해 시간을 기준으로 복제가 완료될 때까지 대기 후 응답
  • MongoDB의 경우 앞서 설명했다시피 빠른 응답성 및 유연한 document가 주목적이므로 많이 쓰이는 기능은 아님
    • 일관성보다는 주목적이 중요

 

Casual Consistency vs Read Concern "linearizable"

 

  • Casual Consistency는 하나의 쓰레드에서 작업
  • Linearizable Read Concern은 다른 세션의 여러 쓰레드의 작업을 적용하여 대기
  • Linearizable Read Concern은 Primary Read에 대해서만 가능하고 Casual Consistency에서는 사용하지 못함
    • 공식 doc 기준 Linearizable 대신 Casual Consistency를 사용하라고 권장
    • Casual Consistency가 Read Concern을 대체하는 개념이 아니라 Read Concern과 같이 사용하면서 세션을 열었을 때 사용할 때 이용하는 옵션
    • 시간 기준 일관성 유지를 위해 Read/Write Concern 모두 majority

 

통상적으로 Casual Consistency를 적용하지 않더라도 Read/Write Concern을 모두 majority로 설정했을 때 데이터 일관성을 대체적으로 보장합니다.

아래 같은 케이스처럼 majority-commit point를 업데이트하기 전 그 찰나의 순간에 읽기 요청이 들어오는 케이스가 있고 일관성을 유지해야 하는 경우 Casual Consistency를 적용합니다.

 

Casual Consistency 적용 전

 

https://vkontech.com/causal-consistency-guarantees-in-mongodb-majority-read-and-write-concerns/

 

Casual Consistency 적용 후

 

https://vkontech.com/causal-consistency-guarantees-in-mongodb-lamport-clock-cluster-time-operation-time-and-causally-consistent-sessions/

 

Transaction

  • MongoDB 4.0버전부터 지원하는 기능
  • MongoDB 특성인 빠른 응답성에 반하는 기능이기 때문에 추천하지 않는 기능
    • Transaction을 적용하겠다는 것은 컬렉션을 정규화하겠다는 것과 동일한 의미
    • 앞선 게시글에서도 정리했다시피 MongoDB는 정규화를 진행하지 않기 때문에 데이터 접근성과 가시성이 좋은 것이 장점

 

RDBMS의 경우 트랜잭션 처리 시 Lock을 활용하지만 MongoDB의 경우 락을 사용하지 않고 TransientTransactionError를 발생시키고 4.2 버전까지는 이에 대한 별도 처리를 직접 구현했어야 했습니다. (보통 재요청)

4.2 버전 이후부터는 트랜잭션 오류 발생 시 자동으로 재요청하는 기능이 내장되어 코드 구현이 간결해졌지만 여전히 MongoDB에서는 추천하지 않는 기능입니다.

Transaction 필요시 MongoDB와 관계형 데이터베이스를 함께 사용한다는 가정 하에 RDBMS에서 처리하는 것을 추천합니다.

 

참고

백엔드 개발자를 위한 한 번에 끝내는 대용량 데이터 & 트래픽 처리 초격자 패키지 Online - 비즈니스 요구사항에 유연한 MongoDB

반응형

'DB > MongoDB' 카테고리의 다른 글

[MongoDB] 스키마 모델링 기법  (0) 2023.12.08
[MongoDB] 인덱스  (0) 2023.12.01
[MongoDB] MongoDB 개요  (0) 2023.11.26