Skip to content

Latest commit

 

History

History
121 lines (87 loc) · 9.44 KB

mongodb-cursorBatchSize.md

File metadata and controls

121 lines (87 loc) · 9.44 KB

1. cursorBatchSize란 무엇인가?

  • 의미
    Spring Data MongoDB의 AggregationOptions에서 cursorBatchSize는 MongoDB 서버가 한 번에 가져오는 배치(batch) 크기를 지정합니다.
    즉, MongoDB 서버에서 한 번에 가져올 문서 개수를 제한함으로써, 네트워크 왕복과 메모리 사용량을 조절할 수 있습니다.

  • 동작 방식
    cursorBatchSize를 설정하면, 내부적으로 MongoDB 드라이버가 서버에 “한 번에 이만큼씩 보내 달라”라고 요청하여, 클라이언트가 큰 데이터를 한 번에 다 불러오지 않고 여러 번에 걸쳐 나누어 받습니다.


2. limit, skip와의 차이점

  • limit
    Aggregation 파이프라인에서 \$limit 스테이지를 사용하면 최종으로 가져올 문서 개수 자체를 제한합니다.
    반면, cursorBatchSize는 가져올 총 개수가 아니라, 한 번에 가져올 배치 단위를 조절합니다.

  • skip
    \$skip 스테이지는 앞의 일부 문서를 건너뛰는 역할이며, cursorBatchSize와는 직접적인 연관은 없습니다.
    cursorBatchSize는 문서 전송 단위(배치)에 관한 설정이므로, skiplimit 같은 파이프라인 연산과는 역할이 다릅니다.


3. 성능 및 메모리 고려 사항

  • 메모리 사용
    batchSize가 너무 크면, 클라이언트(애플리케이션) 측에서 한꺼번에 많은 문서를 로드해야 하므로 메모리 사용량이 급격히 늘어날 수 있습니다.
    반면, batchSize가 너무 작으면, 왕복이 잦아져 네트워크 오버헤드가 늘어날 수 있습니다.

  • 네트워크 왕복
    한 번에 가져오는 배치 크기가 커질수록 왕복 횟수는 줄어들지만, 한 번의 응답 덩어리가 커지므로 전송 시간이 길어질 수 있습니다.
    따라서 적절한 batchSize 설정이 중요합니다.

  • 예시

    • 대량 데이터(수만~수십만 건)를 처리하는 상황에서 cursorBatchSize를 적절히 설정하면,
      • OutOfMemory와 같은 문제를 방지할 수 있고,
      • 클라이언트가 Streaming 방식으로 데이터를 처리하기 수월해집니다.

4. 실제 사용 시 주의사항

  • AggregationOptions와 함께 쓰는 상황
    Aggregation.newAggregationOptions()에서 cursorBatchSize(2000)를 지정하면, 실제로는 MongoDB의 커서(cursor) 기반으로 결과를 가져오게 됩니다.

    • Spring Data MongoDB가 내부적으로 AggregationCursor를 열고, 설정된 batchSize만큼씩 가져옵니다.
  • MongoDB 서버 버전
    특정 MongoDB 버전 이하에서는 Aggregation 파이프라인의 커서 옵션이 다를 수 있으므로, 사용 중인 서버 버전을 확인해야 합니다.

  • Spring Data MongoDB 버전
    cursorBatchSize 옵션이 추가된 버전(SDM 1.9 이후)에선 AggregationOptions와 함께 이 기능을 활용할 수 있습니다.
    (버전에 따라 메서드나 옵션 이름이 다를 수 있으므로, 릴리스 노트를 참고하는 것이 좋습니다.)

  • 기본 batchSize
    Spring Data MongoDB나 드라이버 레벨에서 기본 batchSize가 정해져 있을 수 있습니다(예: 101개).
    별도 설정을 하지 않으면 해당 기본값이 적용됩니다.


5. 샘플 코드 및 사용 예시

val options = Aggregation.newAggregationOptions()
    .cursorBatchSize(2000)
    .build()

val aggregation = Aggregation.newAggregation(
    // 예: match, project, group 등 다양한 스테이지
).withOptions(options)

val results = mongoTemplate.aggregate(
    aggregation,
    "post",
    Post::class.java
).mappedResults
  • 의미: 위 코드에서는 Aggregation 파이프라인 결과를 배치 단위 2000건씩 나누어 가져옵니다.
  • 적용 사례: 대량의 Post 문서를 한 번에 조회해야 하지만, 메모리 사용량을 제어하고 싶을 때 유용합니다.

6. 실제 운영 시나리오 예시

  1. 배치(ETL) 작업
    대량의 MongoDB 데이터를 한꺼번에 읽어 다른 저장소로 옮기는 ETL 시나리오에서, batchSize를 크게 설정해 네트워크 왕복 횟수를 줄이면서도 메모리를 과도하게 사용하지 않도록 조정할 수 있습니다.

  2. 스트리밍 처리
    데이터 양이 매우 많을 때, 클라이언트에서 한 번에 모두 로드하지 않고, 일부씩 읽으면서 스트리밍 처리(예: Kafka 전송, 파일 쓰기)를 진행할 수 있습니다.

  3. 페이징과의 병행
    클라이언트 측 페이징 UI를 구현하는 대신, 서버에서 커서를 유지하면서 일정 배치 단위로 클라이언트에 전송할 수도 있습니다.


7. 결론

cursorBatchSize(2000) 같은 설정은 MongoDB Aggregation 결과를 배치 단위로 가져올 때의 성능과 메모리 사용을 제어하기 위해 유용합니다.
너무 큰 batchSize는 메모리 사용량이 커질 수 있고, 너무 작은 batchSize는 네트워크 왕복이 잦아질 수 있으므로, 실제 운영 환경에 맞춰 적절한 값을 테스트하며 조정하는 것이 중요합니다.
AggregationOptions를 통해 세밀하게 커서 기반 쿼리를 제어할 수 있으니, 대규모 데이터 처리 시 꼭 고려해 보는 것을 권장합니다.

다음은 주어진 find 명령의 옵션들과 함께 singleBatch 옵션의 역할 및 다른 옵션들을 정리한 테이블입니다.

옵션 설명
find 쿼리할 컬렉션의 이름을 지정합니다. 예를 들어, "author" 컬렉션을 대상으로 합니다.
filter 쿼리 조건을 JSON 형식으로 지정합니다. 예제에서는 _id 필드를 기준으로 특정 문서를 찾습니다.
projection 반환할 필드를 선택하거나 제외할 때 사용합니다. (예시에는 포함되지 않았지만 자주 사용되는 옵션입니다.)
sort 결과 문서의 정렬 기준을 지정합니다. (예시에는 포함되지 않았지만, 정렬 시 사용됩니다.)
skip 결과에서 건너뛸 문서의 수를 지정합니다. (예시에는 포함되지 않음)
limit 반환할 최대 문서 수를 지정합니다. 예제에서는 1로 설정되어 한 개의 문서만 반환합니다.
batchSize 한 번에 반환할 문서 수를 지정합니다. 단, singleBatch가 true인 경우 전체 결과가 한 번에 반환됩니다.
singleBatch 결과를 한 번의 배치로 반환하도록 요청합니다. true로 설정하면 서버는 쿼리 결과를 한 번에 모두 반환하고 커서를 유지하지 않아 추가적인 getMore 요청 없이 결과를 전달합니다. false 또는 생략 시, 서버는 결과를 여러 배치로 나눠 반환할 수 있습니다.
collation 문자열 비교 시 사용할 언어별 규칙(예: 대소문자 구분, 악센트 처리 등)을 지정합니다.
maxTimeMS 쿼리 실행에 허용되는 최대 시간을 밀리초 단위로 설정합니다.
hint 특정 인덱스를 강제하여 쿼리 성능을 최적화할 때 사용합니다.
comment 쿼리에 주석을 추가하여 프로파일링이나 로깅 시 참고할 수 있도록 합니다.
readConcern 데이터 읽기 시의 일관성 수준을 설정합니다.
readPreference 데이터를 읽을 때 사용할 노드의 우선순위를 지정합니다.

이 테이블을 참고하여, singleBatch 옵션은 결과 집합을 한 번의 배치로 반환해 커서 유지 없이 빠른 결과 전송을 원하는 경우에 사용되며, 다른 옵션들은 쿼리의 조건, 반환 방식, 성능 최적화 등 다양한 기능을 제공한다는 점을 확인할 수 있습니다.