최근 Next.js로 구성한 SSR 앱과 K8s 기반 MinIO 스토리지를 운영하면서 이미지 로딩이 말도 안 되게 느려지는 현상을 발견했다. 해결 과정을 기록해둔다.
문제 상황
-
MinIO Operator로 Tenant를 구성해서 단일 pool로 쓰고 있었는데, Next.js 앱에서 MinIO의 이미지를 다운로드하는 속도가 지나치게 느렸다.
-
이미지가 큰 것도 아니었다. 2.8KB짜리 썸네일을 받는 데 거의 1초 가까이 걸리는 경우도 있었다.

-
1개 이미지로 줄여서 다운받아봤는데 여전히 164ms 이미지 크기에 너무 느림

초기 시도 및 결과
처음엔 단순히 자원 문제라고 생각해서 이런저런 시도를 했다.
- Next.js 앱과 MinIO 서버를 무작정 증설했지만 별 효과 없었음.
- Next.js 앱 리소스를 CPU 1개, RAM 1GB까지 설정했는데, 이때는 이미지가 아예 렌더링조차 안되는 문제가 있었다.
→ 이건 Next.js 스케일 업으로 해결했음.
- MinIO 서버 증설은 효과가 거의 없었음.
MinIO Tenant 설정 시 주의사항
중간에 Tenant 구성을 변경하면서 알게 된 주의할 점은 다음과 같다.
- Pool 추가는 가능하지만, 삭제는 안 된다.
- Pool을 강제로 지우면 결국 Tenant 전체를 다시 만들어야 한다.
- Tenant 삭제할 때 볼륨을 남기면 PVC가 유지되는데, 이때 Tenant를 다시 만들 때는 이름과 서버, 노드 개수를 기존과 완전히 똑같이 설정해야 기존 PVC가 유지된다.
문제 분석
1. 네트워크/디스크 IO 문제?
- 네트워크 대역폭을 충분히 못 쓰는 것 같았고, HDD를 사용해서 디스크 IO가 느리긴 했음.
- 그래도 이 정도로 느린 건 이상하다. 직접 이미지를 MinIO에서 다운로드해보니 빠르게 잘 처리된다. 즉, 네트워크나 디스크 IO 자체의 문제는 아니었다.

2. 캐싱 문제인가?

- 브라우저 캐싱 확인해 보니 첫 조회만 200, 이후는 304로 잘 캐싱됨.
- 하지만 Next.js 앱에서는 새로고침할 때마다 항상 200으로 이미지를 다시 받았음. 브라우저 캐싱을 안 쓰는 게 맞긴 했지만, 그래도 이게 성능 문제의 핵심은 아닌 듯했다.
3. 부하 상황 추가 테스트 (MinIO warp 사용)
- MinIO 성능 측정 툴인 warp를 이용해서 테스트했다.
- MinIO에 부하가 걸렸을 때 Next.js 앱의 이미지 다운로드가 2~3배 더 지연되는 것을 확인했다. MinIO 부하가 영향을 주는 건 맞는 듯했다.
4. Next.js의 SSR 특성 때문?
-
혹시나 싶어 간단한 CSR 앱(CRA 기반)으로 동일한 이미지 목록을 렌더링해봤는데, 로컬에서 거의 지연 없이 잘 동작했다.

-
Next.js 앱에서 SSR을 하면 이미지 요청이 서버를 프록시로 거쳐 클라이언트로 나가는 구조인 것 같았고, 서버가 이를 제대로 처리하지 못하는 듯 보였다.
-
관련된 이슈를 찾아보니 Next 이런 이슈가 확인되는 것 같고, Next Image load super slow 이나 아래 방법들이 있다고 한다.

Next.js 서버 문제로 결론
- FE 쪽에서 Next.js 관련 최적화 작업을 하니 큰 이미지를 다수 요청할 때 발생했던 OOM(Out Of Memory)은 해결됨.
- 하지만 여전히 20개 정도의 이미지 요청만으로 병목이 발생했다. 이건 명백히 스토리지 서버 자체 문제로 보인다.
- 할당된 자원에 비해 K8s 기반 MinIO가 VM 기반보다 훨씬 느리다는 점이 의심스러웠다. 단순 증설이 효과가 없다는 건 분명했다.
longhorn 을 사용하고 있는데 볼륨 복제본을 3으로 사용하고 있다. vm 에 비해 처리량이 많을 수 밖에 없기 때문에 어느정도 성능저하는 있을 수 있다고 생각한다.