Vercel Sandbox snapshot 최적화
S3 병렬 다운로드·병렬 decompression·NVMe cache로 p75 restore가 40초에서 1초 미만으로 줄었다.
Vercel Sandbox는 처음엔 신뢰성에 집중했지만, 안정화 이후 성능이 병목이 됐다. snapshot restore의 p75가 40초를 넘었고, 팀은 다운로드와 decompression, 캐시를 차례로 개선해 이를 1초 미만으로 끌어내렸다.
Vercel Sandbox는 내부 빌드 제품인 Hive와 같은 인프라 위에서 동작하며, 각 sandbox는 Firecracker microVM 안의 격리된 컨테이너다. snapshot은 sandbox 디스크의 압축 복사본이고, 원본 .img와 업로드/다운로드용 압축 포맷 .vhs(Vercel Hive Snapshot)를 사용한다. sandbox.snapshot()은 .img를 .vhs로 압축해 S3에 올리고, Sandbox.create()는 이를 내려받아 다시 .img로 푼다.
처음의 restore 경로는 완전히 순차적이었다.
- S3에서
.vhs전체를 한 번에 다운로드 - 다운로드 완료 후 단일 스레드로 decompression
이 구조는 수백 MB에서 수 GB에 이르는 snapshot에서 수 초에서 수십 초까지 지연을 만들었다.
첫 번째 개선은 Range HTTP header를 활용한 병렬 다운로드였다. AWS Go SDK의 transfermanager로 청크를 나눠 동시에 받아오게 했고, 튜닝 끝에 다운로드 속도를 2~5배 높였다. 다음으로 .vhs의 각 frame을 여러 goroutine에 분산해 decompression을 병렬화했고, 이 단계만으로도 restore가 2~4배 빨라졌다.
하지만 여전히 다운로드한 데이터를 디스크에 먼저 쓰고 나서 decompression을 시작했다. S3 range request stream을 decompression으로 바로 연결해 중간 파일을 없애자 end-to-end restore 시간이 추가로 2배 줄었다.
여기서 끝이 아니었다. 처음엔 아예 fast path가 없어 모든 요청이 cache miss였기 때문에, 팀은 metal instance의 대용량 NVMe를 이용한 로컬 disk cache를 도입했다. 캐시는 압축본이 아니라 decompressed .img를 직접 저장하고, 항목 수가 아니라 총 디스크 사용량 기준으로 LRU eviction을 적용한다. 많은 고객이 base snapshot을 반복 사용해 95% cache hit rate를 기록했고, hit 시에는 microVM과 container를 띄우는 시간만 남게 됐다.
결과적으로 p75는 40초에서 sub-second로, p95는 50초에서 5초로 내려갔다. 앞으로는 cache affinity로 인기 snapshot을 이미 캐시된 머신에 라우팅하는 방안도 있지만, 특정 머신에 부하가 몰릴 수 있어 신중하게 검토 중이다. 이 최적화는 현재 beta인 Automatic Persistence에도 적용돼, sandbox를 멈출 때 filesystem을 snapshot하고 다시 시작할 때 즉시 복원한다.
이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.
요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.