파일·리소스 처리 · Java I/O

558개 파일 복사를 Java NIO로 바꿔 160,556ms에서 714ms로 줄이기

CES 결과 ZIP 생성 과정에서 파일 복사 병목을 찾아 Java NIO로 전환했습니다. 같은 558개 파일의 복사 시간을 160,556ms에서 714ms로 줄인 운영 사례입니다.

JavaJava NIOZIPPerformance

다운로드 준비 단계를 나눠 측정했습니다

CES 결과 다운로드는 여러 결과 파일을 임시 폴더에 모은 뒤 ZIP으로 압축해 내려주는 방식이었습니다. 파일이 많아질수록 준비 시간이 길어졌지만, 한 번의 요청 안에 대상 조회·복사·압축·HTTP 전송이 모두 들어 있어 전체 시간만으로는 병목을 알기 어려웠습니다.

전체 응답시간만 보면 압축이나 네트워크가 느리다고 추측하기 쉽습니다. 그래서 먼저 처리 단계를 나누고 각 구간이 소비하는 시간을 확인했습니다.

  • 다운로드 대상 파일 목록 확인
  • 원본 파일을 임시 폴더로 복사
  • 임시 폴더의 파일을 ZIP으로 압축
  • 압축 결과를 HTTP 응답으로 전송
  • 작업 후 임시 파일과 폴더 정리

병목을 파일 복사 구간으로 좁힌 근거

같은 558개 파일로 구간별 시간을 재보니 FileInputStream·FileOutputStream 기반 복사에만 160,556ms가 걸렸습니다. 압축 알고리즘을 바꾸기 전에 파일 복사 경로부터 손봐야 한다는 근거가 생겼습니다.

여기서 측정한 값은 사용자가 버튼을 누른 뒤 다운로드가 끝날 때까지의 시간이 아닙니다. 임시 폴더에 파일을 복사하는 구간만 분리해 측정한 결과입니다. 압축과 네트워크 전송을 포함하지 않았기 때문에 이 수치를 HTTP 전체 응답시간 개선으로 표현하지 않았습니다.

파일 복사를 Java NIO로 바꿨습니다

FileInputStream·FileOutputStream 기반 복사를 FileChannel을 사용하는 Java NIO 방식으로 바꿨습니다. 비교에서는 같은 558개 파일을 복사할 때 두 방식의 처리 시간이 얼마나 달라졌는지만 확인했습니다.

파일 복사를 Java NIO로 바꿨습니다 데이터 표
구분확인된 구현 범위
변경 전FileInputStream·FileOutputStream 기반 복사
변경 후FileChannel을 사용하는 Java NIO 기반 복사
비교 조건동일한 558개 파일의 복사 구간

성능 비교에는 파일 조회·ZIP 압축·HTTP 전송을 섞지 않았습니다. 같은 파일 집합의 복사 구간만 따로 측정했기 때문에 개선 결과도 이 범위에 한정해 해석해야 합니다.

운영 로그와 임시 파일 정리도 함께 고쳤습니다

기존 처리 과정에는 System.out.println 중심의 출력이 섞여 있었습니다. 운영 환경에서 처리 단계와 실패 원인을 일관된 방식으로 추적할 수 있도록 애플리케이션 로깅으로 변경했습니다.

성능 개선과 함께 다운로드가 끝난 뒤 임시 파일을 비우는 처리도 정비했습니다. 최초 변경 직후에는 삭제 대상 폴더를 잘못 가리키는 문제가 발견돼, 후속 변경에서 실제 작업 폴더를 삭제하도록 바로잡았습니다. 복사와 정리 로직이 같은 임시 경로 규칙을 사용해야 한다는 점도 함께 확인했습니다.

정상 다운로드 뒤 임시 디렉터리가 비워지고 파일 처리 과정이 애플리케이션 로그에 남는지도 확인했습니다. 다만 복사나 압축을 의도적으로 실패시키는 테스트 기록은 없어서, 모든 예외 경로에서 정리가 보장된다고 말할 수는 없습니다.

복사 속도만 확인하지 않고 정상 다운로드가 끝난 뒤의 임시 리소스 상태까지 같은 작업 범위에서 점검했습니다.

같은 파일 집합으로 개선 전후 비교

개선 전후 모두 동일한 558개 파일을 입력으로 사용하고 복사 구간을 비교했습니다.

  • 대상 파일: 558개
  • 개선 전: 160,556ms
  • 개선 후: 714ms
  • 개선 결과: 같은 복사 구간의 처리 성능을 약 224배 개선

복사 성능을 약 224배 개선했다는 결과는 기존 Stream 기반 복사와 Java NIO 기반 복사를 같은 파일 집합으로 비교한 값입니다. 캐시·스토리지 상태 같은 세부 실행 조건은 남아 있지 않아, 다른 서버나 파일 구성에서도 같은 결과가 나온다고 일반화할 수는 없습니다.

다운로드 결과와 임시 파일 삭제를 검증했습니다

  • 정상 선택 결과 다운로드 확인
  • 다운로드 완료 후 임시 디렉터리가 비워지는지 확인
  • 파일 처리 흐름이 애플리케이션 로그에 남는지 확인

성능뿐 아니라 기존 다운로드 기능과 정상 완료 뒤 임시 파일 정리 결과도 함께 확인했습니다.

운영 반영 결과

동일한 558개 파일의 복사 시간이 160,556ms에서 714ms로 줄었습니다. 같은 복사 구간의 처리 성능을 약 224배 개선했고, 테스트와 운영 검증을 거쳐 2023.08.22 운영에 반영했습니다.

운영에는 NIO 기반 복사와 함께 출력 로깅 변경, 정상 다운로드 뒤 임시 리소스 정리도 반영했습니다. 다만 측정한 수치는 파일 복사 구간에만 해당합니다. ZIP 압축과 네트워크 전송까지 포함한 전체 응답시간으로 넓혀 말할 수는 없습니다.

정리

CES 결과 ZIP 생성에서는 복사 구간을 따로 측정하고, 같은 558개 파일로 Stream 기반 복사와 Java NIO 기반 복사를 비교했습니다. 정상 완료 뒤 임시 파일이 삭제되는지와 처리 과정이 운영 로그에 남는지도 함께 확인했습니다.