가상 머신에서의 파일 시스템 성능 비교
원문은 Mitchell Hashimoto님이 에 게재했습니다. 이 블로그 구독하기
수년간 Vagrant를 이용한 가상 머신 기반 개발 환경에서 가장 큰 병목은 파일 시스템 성능이었다. CPU 차이는 미미해서 거의 체감되지 않고, RAM은 가상 머신을 여러 개 동시에 실행할 때만 문제가 된다.
어제 거의 하루 종일 주요 파일 시스템 메커니즘들을 벤치마킹하고 분석했으며, 그 결과를 여기에서 공유하려 한다.
가장 많은 사람들이 궁금해하는 부분인 결과 분석부터 시작하겠다. 정확한 테스트 방법, 사용한 소프트웨어, 그리고 원시 데이터는 이 분석 아래에서 확인할 수 있다.
아래에 표시된 모든 차트에서는 어떤 방식으로든 파일을 읽거나 쓰는 테스트를 수행했다. 각 그래프마다 쓰기 대상 파일의 전체 크기는 고정되어 있다. Y축은 처리량(KB/s)이며, X축은 ‘레코드 크기’, 즉 한 번에 읽고 쓰는 데이터 청크의 크기(KB)이다.
테스트 환경은 native, VirtualBox native, VMware native, VirtualBox 공유 폴더(vboxsf), VMware 공유 폴더(vmhgfs), 그리고 NFS로 구분된다. ‘native’ 환경이란 해당 환경에서 파일 시스템을 단독으로 사용하는 경우를 의미한다. ‘native’는 호스트 머신, ‘VirtualBox native’는 VirtualBox 가상 머신 내부의 루트 디바이스 등을 가리킨다. NFS는 VirtualBox와 VMware에서 성능 특성이 비슷할 것으로 예상되어 VirtualBox에서만 테스트했다.
모든 차트에서 처리량(Y축)이 높을수록 좋다.
작은 파일 순차 읽기
먼저 64KB 파일에 대한 순차 읽기를 다양한 읽기 레코드 크기로 테스트한 결과다. 작은 파일 순차 읽기가 실제로 적용되는 사례로는 애플리케이션 실행, 컴파일 또는 테스트를 위해 소스 파일을 불러오는 경우를 들 수 있다.

가장 먼저 눈에 띄는 점은 NFS의 읽기 성능이 작은 레코드 크기에서 엄청나게 뛰어나다는 것이다. NFS는 이런 성능을 내기 위해 상당한 수준의 리드 어헤드 작업과 캐싱을 수행하고 있을 가능성이 높다. NFS가 네이티브 가상 파일 시스템보다 뛰어난 성능을 내는 이유에 대해서는 마땅한 설명을 갖고 있지 않다.
여기서는 VMware 공유 폴더가 VirtualBox 공유 폴더를 압도한다. VirtualBox 공유 폴더의 읽기 성능은 그야말로 처참하다. 원시 데이터를 보면 처리량이 실제로 100MB/s를 넘지 않는 반면, VMware는 500MB/s 아래로 내려가지 않고 최고 900MB/s 이상까지 치솟는다.
흥미로운 점은 가상 머신 내부의 네이티브 파일 시스템이 때때로 호스트 머신의 네이티브 파일 시스템을 능가한다는 것이다. 이 테스트는 사용자 공간 버퍼링이 전혀 없는 순수 read 시스템 호출을 사용한다. 하이퍼바이저가 가상 머신으로부터의 읽기에 대해 버퍼링을 수행하고 있어 네이티브 커널로의 컨텍스트 스위칭이 줄어들어 더 좋은 성능이 나오는 것일 가능성이 높다. 이 가설은 fread 벤치마크의 원시 결과 데이터를 보면 더욱 뒷받침된다. 해당 테스트에서는 네이티브 파일 시스템이 항상 가상 파일 시스템을 이긴다.
대용량 파일 랜덤 읽기
이번에는 64MB 파일의 여러 부분을 무작위로 읽을 때의 처리량을 다양한 읽기 레코드 크기로 테스트했다. 이 파일은 이전 테스트보다 1000배 크다. 이러한 동작은 파일 시스템에 접근하는 데이터베이스 읽기 작업 등에서 볼 수 있다.

작은 파일 순차 읽기와 비교하면 VMware 공유 폴더와 VirtualBox 공유 폴더 간의 격차는 훨씬 더 벌어진다. VirtualBox는 성능이 너무 낮아 그래프에서 거의 보이지 않을 정도다. 여기서도 VirtualBox 처리량은 100MB/s를 넘지 않는다. 반면 VMware는 최고 7GB/s까지 나온다. 다양한 테스트 케이스에서 VirtualBox 처리량의 편차가 매우 작다는 점을 볼 때, VirtualBox 공유 폴더 시스템 어딘가에 이를 제한하는 단일 핫 패스 코드가 존재한다고 추측한다. 분명 무언가 잘못하고 있는 것이다.
NFS는 이 테스트 케이스에서는 리드 어헤드의 이점이 드러나지 않아 예전만큼 압도적이지는 않다. 그럼에도 다른 선택지들에 비하면 여전히 매우 우수한 성능을 보인다.
그리고 작은 파일 순차 읽기의 경우와 마찬가지로, 가상 머신 내부에서의 성능이 외부보다 여전히 더 좋게 나타난다. 이 역시 하이퍼바이저가 영리하게 버퍼링을 수행하기 때문으로 볼 수 있으며, 호스트 머신에 대한 순수 시스템 호출에서는 이러한 버퍼링이 일어나지 않는다.
작은 파일 순차 쓰기
이번에는 작은 파일에 대한 순차 쓰기 성능을 살펴보자. 이는 세션 상태 저장, 임시 파일 생성, 혹은 새로운 소스 파일 작성 등을 가장 잘 설명하는 경우다.

가장 먼저 눈에 띄는 점은 이러한 종류의 쓰기에서 NFS 성능이 끔찍하다는 것이다. NFS가 여기서 할 수 있는 실질적인 캐싱이 없기 때문에, 네트워크 오버헤드에 대한 비용을 전부 감수하고, 호스트 측에서 디스크에 쓰고, 다시 VM에서 쓰기가 성공했다는 ack를 기다려야 한다. 정말 뼈아프다.
다양한 ‘native’ 파일 시스템들은 매우 우수한 성능을 보인다. 여기서도 가상 머신이 호스트를 능가한다. 역시 하이퍼바이저의 버퍼링 덕분으로 볼 수 있다.
공유 파일 시스템들 간의 차이는 크지 않지만, 이 테스트 케이스에서는 VirtualBox가 VMware를 확실히 앞선다.
대용량 파일 랜덤 쓰기
마지막으로 살펴볼 차트는 대용량(64MB) 파일에 대한 랜덤 쓰기를 테스트한 결과다. 대용량 랜덤 읽기 테스트와 마찬가지로, 데이터베이스 성능을 가늠하기에 좋은 테스트다.

작은 파일 순차 쓰기와 비교했을 때 여기서는 큰 차이가 없다. 파일이 크기 때문에 테스트 환경 간의 격차는 더 크지만, 그 외에는 결과가 대부분 비슷하다.
NFS는 쓰기에서 계속해서 형편없는 성능을 보인다. VirtualBox 공유 폴더는 쓰기에서 VMware를 계속 앞서며, 하이퍼바이저는 호스트 머신보다 우수한 성능을 보인다.
하이퍼바이저가 호스트 머신보다 뛰어난 성능을 보이는 점이 내게는 가장 흥미롭다. 이 테스트 결과는 하이퍼바이저가 성능을 위해 동기화된 쓰기에 대해 거짓말을 하고 있음을 분명히 보여준다. 이는 Packer에서도 본 바와 일치하는데, 가상 머신이 정상적으로 종료되지 않으면 커밋된 쓰기가 유실된다. 가상 머신에서의 fsync()는 데이터가 호스트에 기록되었다는 의미가 아니라 하이퍼바이저 내에서 커밋되었다는 의미일 뿐이다.
종합 분석
공유 파일 시스템에 관해서는 VMware가 원하는 동작을 보여준다. 웹 페이지 로딩, 테스트 스위트 실행, 소프트웨어 컴파일은 모두 읽기에 크게 의존한다. VMware 공유 폴더의 읽기 성능은 VirtualBox를 압도하는 반면, VirtualBox 공유 폴더의 쓰기 성능은 VMware보다 근소하게 나을 뿐이다.
NFS를 사용할 수 있는 선택지가 있다면 사용하라. 다시 말하지만 읽기 성능이 쓰기 성능보다 훨씬 더 중요하다.
하이퍼바이저의 읽기/쓰기 성능은 환상적이다(속임수를 쓰기 때문이다). 이 데이터 덕분에 앞으로 Vagrant에서 네이티브 파일 시스템만을 사용하는 새로운 동기화 폴더 구현(예: rsync, 또는 호스트 머신을 NFS 서버 대신 클라이언트로 사용하는 방식)에 더 집중할 계획이다.
하지만 당장 적용할 수 있는 팁은 다음과 같다: 개발용으로 가상 머신을 사용한다면 가능하다면 데이터베이스 파일을 공유 파일 시스템 밖으로 옮겨라. 아마도 엄청난 성능 향상을 체감할 수 있을 것이다.
마지막으로, 이 결과에 큰 의외는 없다고 생각한다. Vagrant는 공유 폴더의 성능이 좋지 않다는 것을 일찍 깨닫고 2010년부터 NFS 동기화 폴더를 지원해 왔다. 하지만 서로 다른 동작을 보여주는 명확한 데이터를 갖게 된 것은 반가운 일이며, 각 시스템이 내부적으로 무엇을 하고 있을지에 대한 흥미로운 통찰을 제공한다.
글을 무작위로 읽기
댓글
로그인하고 댓글 남기기