주로 업로드 되는 이미지
우리 회사 서비스에서 주로 업로드되는 이미지는 병원 병리 데이터 이미지다. 일반적인 PNG나 JPG 형식이 아니라, 현미경으로 촬영된 사진이기 때문에 .svs
확장자를 사용한다.
.svs 파일은 병리학에서 사용되는 대용량 슬라이드 이미지 포맷으로, 하나의 슬라이드 이미지를 매우 높은 해상도로 저장할 수 있다.
그만큼 파일 크기가 수백 MB에서 수 GB에 달하는 경우가 많다. 또한, 연구에 사용되는 이 데이터는 한 장만 업로드되는 것이 아니라, 한 번에 수십 장에서 많게는 수백 장까지 업로드되는 경우가 흔하다.
대충 저런 빨간 사진들이다
그냥 올린다면 어떻게 되나
만약 업로드되는 이미지에 .svs와 .png 파일이 함께 있다면, 현재 방식에서는 업로드 순서에 따라 처리 순서가 고정된다. 예를 들어 .png가 .svs 뒤에 있다면, .png는 앞에 있는 .svs가 업로드를 마칠 때까지 기다려야 한다.
문제는 .svs 파일 자체가 크고 처리 시간이 오래 걸린다는 점이다. 이 때문에 중요한 .svs 파일도, 앞서 업로드된 다른 .svs가 처리되는 동안 대기해야 하며, 정작 먼저 처리할 수 있는 작업조차 순서 때문에 지연된다.
즉, 모든 파일을 순차적으로 처리하는 구조에서는 이런 병목 현상이 필연적으로 발생한다.
사실 구글 드라이브
같은 대형 클라우드 서비스조차, 이처럼 대용량 이미지만 전문적으로 올리는 경우는 드물다. 그리고 대용량 업로드의 경우에도 파이프라인이 순차적으로 진행되기 때문에, 비슷한 대기와 지연 문제에서 완전히 자유롭지 않다.
제한된 환경에서의 최대의 효율
스프린트와 마일스톤, 그리고 매우 소규모 인원으로 전혀 다른 프로토콜을 새로 설계해 업로드 방식을 바꾸는 것은 스타트업 환경에서 쉽지 않다. 즉, 제한된 상황에서 가장 효율적인 방법을 찾는 것이 우선이었다. 이때 해결한 방법이 다음이 같다.
파일을 ‘chunk’ 단위로 나누어 업로드하는 것
여기서 chunk란, 하나의 대용량 파일을 여러 개의 작은 조각으로 분할한 단위
를 뜻한다. 이런 방식에서는 다음과 같이 기존의 문제를 해결할 수 있었다.
병렬 업로드 가능
- 여러 chunk를 동시에 업로드해 전체 소요 시간을 줄인다.
우선순위 조정 가능
- 중요한 파일의 chunk부터 먼저 전송할 수 있다.
서버단에서, 대용량 이미지를 한번에 처리하지 않음
- 대부분의 서비스는, 용량 제한이 있지만, 이것을 chunk로 나누게 된다면, 네트워크 통신에서는 그냥 작은 크기로 전송이 되기 때문에 네트워크측면에서도 효율적으로 처리가 가능하다.
다만 이때 브라우저에서의 하나의 문제가 있었는데, 크롬 브라우저를 기준으로 보면, 동시에 지나치게 많은 chunk를 업로드(즉, API 요청)하면 브라우저가 이를 정상적으로 처리하지 못하고 연결이 끊기는 문제가 발생했다. 따라서 동시 업로드 개수를 제한하는 방식을 적용했다.
예를 들어, 한 번에 4~6개의 chunk만 병렬로 전송하고, 전송이 완료된 chunk가 생기면 그때 다음 chunk를 업로드하는 queue기반 처리를 사용했다.
실제 서비스 환경과 비슷한 조건에서 여러 번 테스트를 했다. Wi-Fi, 유선, VPN 등 다양한 네트워크 환경에서 테스트, 3개, 5개, 7개, 9개씩 동시 업로드하면서 속도와 실패율 비교 실패가 발생하면 재시도 횟수와 전체 소요 시간을 확인했다.
테스트 결과, 3~5개를 동시에 올릴 때가 가장 빠르면서도 실패율이 낮았다. 그 이상 올리면 오히려 재시도가 늘어나서 전체 시간이 더 길어졌다. 결국, 최대 3개의 chunk를 동시에 올리기로 했다.
여기서 말하는 건 파일 3~4개를 동시에 올린다는 개념이 아니라, 하나의 파일을 잘게 쪼갠 chunk들을 동시에 올리는 것이다. 그래서 절대 느리지 않고, 오히려 병렬 전송 덕분에 대용량 파일도 훨씬 빨리 업로드가 가능하다.
- 파일을 10MB 단위로 chunk로 분할
- 동시에 최대 3개 chunk만 업로드
- 각 chunk 업로드 후 진행률(progress) 콜백 호출
회사 코드라, 올릴수는 없지만, 위와같은 프로세스로 적용을 시켰고 결과는
올린 여러 SVS 파일들이, 각각 chunk로 전송되면서 하나의 파이프라인으로 병목이 되던 현상을 없애고, 대용량 이미지를 처리할 수 있었다.