MongoDB 읽기 선호도

MongoDB 읽기 선호도 (Read Preference)

MongoDB 클라이언트가 복제 세트의 어떤 멤버에 읽기 연산을 보낼지는 읽기 선호도(read preference)가 결정해요. 기본적으로 애플리케이션의 읽기는 복제 세트의 프라이머리로 향하지만, 상황에 따라 세컨더리로 읽기를 보내고 싶을 때 이 설정을 바꾸면 됩니다. 읽기 분산을 조절해서 부하를 나누거나, 지연(latency)에 따라 가까운 멤버를 고르는 데 쓰여요.

출처: Read Preference - MongoDB 공식 매뉴얼

읽기 선호도 모드

읽기 선호도는 모드(mode)로 표현돼요. 주요 모드를 정리하면 다음과 같아요.

모드 설명
primary 기본 모드예요. 모든 연산이 현재 복제 세트의 프라이머리에서 읽어요. 읽기 연산을 포함하는 트랜잭션은 반드시 primary를 써야 해요.
primaryPreferred 대부분 상황에서는 프라이머리에서 읽지만, 프라이머리를 사용할 수 없으면 세컨더리 멤버에서 읽어요.
secondary 복제 세트의 세컨더리 멤버에서만 읽어요.
secondaryPreferred 주로 세컨더리에서 읽어요. 복제 세트에 프라이머리 하나만 있고 다른 멤버가 없다면 프라이머리에서 읽습니다.
nearest 지정한 지연 임계값(latency threshold)을 기준으로, 프라이머리든 세컨더리든 상관없이 선정 가능한 멤버 중 무작위로 읽어요.

동작 특성

읽기 선호도를 이해할 때 몇 가지 동작 특성을 기억해두면 좋아요.

  • primary를 제외한 모든 모드는 세컨더리가 프라이머리의 연산을 비동기로 복제하기 때문에 오래된(stale) 데이터를 돌려줄 수 있어요. primary가 아닌 모드를 쓴다면 애플리케이션이 오래된 데이터를 견딜 수 있는지 확인해야 해요.
  • 읽기 선호도는 데이터의 **가시성(visibility)**에는 영향을 주지 않아요. 클라이언트는 쓰기가 승인되거나 복제 세트 대다수 멤버에 전파되기 전에도 쓰기 결과를 볼 수 있어요.
  • 읽기 선호도는 인과적 일관성(causal consistency)에도 영향을 주지 않아요.

읽기 선호도 설정

MongoDB 드라이버를 쓸 때는 드라이버가 제공하는 읽기 선호도 API로 설정할 수 있어요. 복제 세트나 샤딩된 클러스터에 연결할 때도 읽기 선호도를 지정할 수 있는데, 연결 문자열(connection string) 옵션으로 설정할 수 있습니다. 주어진 읽기 선호도에 대해 MongoDB 드라이버들은 동일한 멤버 선택(member selection) 로직을 사용해요.

mongosh를 쓸 때는 cursor.readPref()Mongo.setReadPref() 메서드를 사용할 수 있어요.

읽기 선호도와 트랜잭션

읽기 연산을 포함하는 트랜잭션은 반드시 primary 읽기 선호도를 사용해야 해요. 또한 주어진 트랜잭션의 모든 연산은 같은 멤버로 라우팅돼야 합니다.

추가 고려사항

  • 버전 5.0 이상이고 읽기 선호도가 세컨더리 읽기를 허용하면, $merge$out 스테이지는 세컨더리 노드에서 실행되지만 쓰기는 프라이머리 노드로 전송돼요.
  • 일부 드라이버 버전은 세컨더리 노드로 $merge 연산을 보내는 것을 지원하지 않을 수 있어요.
  • 이전 MongoDB 버전에서는 $out이나 $merge 스테이지를 포함한 파이프라인이 항상 프라이머리 노드에서 실행되고 읽기 선호도가 고려되지 않았어요.

더 알아보기