백엔드/Spring
[Spring] Reactive MongoDB Stream의 Flux, Mono 조회 방법 비교
작은소행성
2024. 11. 22. 13:30
Reactive MongoDB 를 사용할 때 Flux, Mono 는 데이터를 처리하는 중요한 두가지 방식이다.
buffer 와 next 를 사용한 스트리밍 방식
Flux<ResultResponse> dataStream = mongoTemplate.aggregate(aggregation, "result_data", ResultResponse.class);
return dataStream
.buffer(pageSize) // 요청한 사이즈만큼 버퍼링
.next() // 첫 번째 페이지만 가져오기
.defaultIfEmpty(Collections.emptyList()) // 데이터가 없을 경우 빈 리스트 반환
.map(res -> {
String newLastSeenId = res.isEmpty() ? null : res.get(res.size() - 1).getId();
PagedResponse<ResultResponse> pagedData = new PagedResponse<>(
res,
pageRequestDTO.getPage(),
pageRequestDTO.getPageSize(),
totalCount,
(int) Math.ceil((double) totalCount / pageRequestDTO.getPageSize()),
res.isEmpty() || res.size() < pageRequestDTO.getPageSize(),
newLastSeenId
);
return pagedData;
});
limitRequest, collectList를 사용한 전체 데이터 처리
Mono<Object> pageMono =
mongoTemplate.aggregate(aggregation, "result_data", ResultResponse.class)
.limitRequest(pageSize) // 한 번에 요청할 데이터 수 제한
.collectList() // 전체 데이터를 List로 수집
.map(res -> {
String newLastSeenId = res.isEmpty() ? null : res.get(res.size() - 1).getId();
PageImpl<ResultResponse> pageResponse = new PageImpl<>(res, pageRequestDTO.toPageRequest(), totalCount);
PagedResponse<ResultResponse> pagedData = new PagedResponse<>(
pageResponse.getContent(),
pageResponse.getNumber(),
pageResponse.getSize(),
pageResponse.getTotalElements(),
pageResponse.getTotalPages(),
pageResponse.isLast(),
newLastSeenId
);
return pagedData;
});
요약
첫 번째 코드 | 두 번째 코드 | |
메모리 사용 | 메모리 효율적 (pageSize만큼만 메모리에 로드) | 메모리 사용량 큼 (전체 데이터를 메모리에 로드) |
성능 | 빠름 (필요한 데이터만 점진적으로 소비) | 느림 (전체 데이터를 수집한 후 처리) |
Reactive Streams 친화성 | 높음 (스트리밍 처리 방식에 충실) | 낮음 (스트리밍 특성을 충분히 활용하지 않음) |
적합한 데이터 크기 | 대규모 데이터 처리에 적합 | 소규모 데이터 처리에 적합 |
복잡성 | 약간 높음 (Reactive Streams의 동작을 이해해야 함) | 낮음 (단순한 처리) |
대규모 데이터 및 Reactive Streams 방식을 사용하려면은 첫번째 코드가 적합하다.
반응형