요약. Rediacc의
rdc machine query --storage-health는 저장소별 단편화 수치를 보고합니다. 한 프로덕션 머신에서 GitLab이 기가바이트당 약 19,650개의 익스텐트로 표시됩니다. 본능적으로 조각 모음을 실행하고 싶어집니다. 저는 대신 측정해봤습니다.
- 이웃 저장소보다 16배 더 단편화된 저장소가 순차 읽기에서 149 MB/s 대 143 MB/s로 읽혔고, 무작위 4K 읽기에서는 더 빨랐습니다 (719 us 대 957 us).
- 해당 장치는 플래시입니다. 단편화는 탐색 시간을 통해 회전 디스크에 영향을 줍니다. SSD에서는 단편화가 해를 끼칠 메커니즘이 거의 남아 있지 않습니다.
- 여기서
btrfs filesystem defragment를 실행하면 4.4 GB만 여유가 있는 풀에서 reflink로 연결된 포크와 스냅샷 약 250 GB의 공유가 해제됩니다. 이것이 실제 위험이고, 벤치마크는 그에 맞설 이득이 없음을 보여줍니다.
스토리지 상태 보고서는 한 가지 질문에 답하기 위해 존재합니다: 내 디스크가 어디로 가고 있는가. 각 저장소의 크기, 포크와 공유하는 데이터의 양, 그리고 단편화 수치를 보여줍니다. 마지막 수치가 무섭게 보일 수 있습니다. 제가 운영하는 머신에서 GitLab의 저장소 이미지는 14.6 GB에 걸쳐 268,771개의 익스텐트를 보고합니다. 이는 기가바이트당 약 19,650개의 익스텐트이며, 도구는 이것을 “높음”으로 표시합니다.
그 뒤에 따라오는 반사는 자동입니다. 단편화가 높으니 조각 모음을 합니다. 저는 이 반사를 15년 동안 회전 디스크의 셸 스크립트에 작성해왔습니다. Rediacc에 조각 모음 버튼을 추가하기 전에, 실제로 운영하는 하드웨어에서 그 숫자의 실제 비용이 무엇인지 알고 싶었습니다. 그래서 라이브 머신에서 벤치마크를 실행했습니다.
숫자가 실제로 무엇을 세는가
Rediacc 저장소는 btrfs 풀에 있는 단일 LUKS 이미지 파일입니다. 단편화 수치는 해당 이미지 파일에서 filefrag를 실행하여 얻습니다. 암호화된 컨테이너의 익스텐트를 세는 것이지, 그 안의 애플리케이션이 읽는 파일의 익스텐트가 아닙니다.
데이터가 쌓이는 방식 때문에 이것이 중요합니다. 아래에서 위로: 물리적 SSD, 그 위에 호스트 ext4 루트 파일시스템, 그 위에 루프 기반 풀 파일, 그 위에 loop0, 그 위에 btrfs 풀, 그 위에 LUKS 이미지, 그 위에 device-mapper crypt 장치, 그 위에 컨테이너가 보는 내부 ext4입니다. btrfs는 copy-on-write입니다. 저장소 내의 모든 무작위 쓰기는 이미지에 새로운 익스텐트를 씁니다. 데이터베이스와 컨테이너 오버레이 레이어는 하루 종일 무작위로 쓰기 때문에, 이미지는 설계상 익스텐트를 축적합니다.
볼륨 내부의 파일은 다른 이야기입니다. GitLab 저장소를 확인해보니: gitaly 바이너리는 10개의 익스텐트, git 팩 파일은 17개였습니다. 내부 파일시스템은 단편화되어 있지 않습니다. 기가바이트당 19,650개 수치는 copy-on-write 컨테이너를 설명하는 것으로, 이는 정확히 예상되는 모습이며 읽기가 느린지 여부에 대해서는 아무것도 말해주지 않습니다.
벤치마크
단편화 척도의 양 끝에 있는 두 저장소를 선택하고, 페이지 캐시를 우회하여 물리적 읽기를 강제하는 direct IO로 읽기를 수행했습니다.
| 저장소 | 평균 익스텐트 | GB당 익스텐트 | 순차 읽기 |
|---|---|---|---|
| GitLab | 54 KB | ~19,650 | 149 MB/s |
| Stack Overflow 데모 | 880 KB | ~1,190 | 143 MB/s |
단편화가 16배 차이가 나도 처리량 패널티는 없었습니다. 단편화가 심한 파일이 약간 더 빨랐습니다. 그다음으로 실제로 사람들을 걱정하게 만드는 패턴인, 소규모 무작위 읽기 (데이터베이스 트래픽의 형태)를 확인했습니다.
| 저장소 | 무작위 4K 지연 | IOPS |
|---|---|---|
| GitLab (단편화됨) | 719 us | 1,390 |
| Stack Overflow 데모 (덜 단편화됨) | 957 us | 1,045 |
단편화된 파일이 여기서도 더 빠릅니다. 작은 차이는 익스텐트 레이아웃이 아닌 파일 크기와 백엔드 캐싱을 반영합니다. 플래시에서 무작위 읽기는 주변 익스텐트가 어디에 있든 관계없이 한 번의 조회와 한 번의 읽기입니다. 움직일 헤드가 없습니다.
절대적인 수치로는 처리량이 약 145 MB/s와 1,000 IOPS 정도로 낮은 편인데, 장치가 공유 호스트의 가상화된 디스크이고 데이터 경로가 깊기 때문입니다. 이 상한선은 btrfs 위아래에 있는 가상화 및 crypt 레이어에 의해 설정됩니다. 이미지를 조각 모음한다고 해서 이것을 높일 수는 없습니다.
단편화가 실제로 비용을 치르는 한 가지
솔직하게 반대편도 살펴봐야 합니다. 단편화에는 정확히 하나의 측정 가능한 비용이 있고, 그것은 읽기 속도가 아닙니다. 익스텐트 맵을 열거하는 시간입니다.
- GitLab의
filefrag(268,771개 익스텐트): 3.19초 - Stack Overflow 데모의
filefrag(152,364개 익스텐트): 0.74초
모든 익스텐트를 순회하는 작업은 이 비용을 치릅니다. 스토리지 상태 스캔 자체, 백업 동기화, 델타 도구가 여기에 포함됩니다. 초 단위이고, 익스텐트 수에 따라 대략 비례하며, 애플리케이션이 아닌 백그라운드 작업에 영향을 줍니다. 익스텐트 순회 시간이 실제 병목이 된다면, 그것은 좁은 문제로 좁은 해결책이 있습니다. 라이브 데이터를 재작성할 이유가 아닙니다.
Rediacc가 조각 모음 명령을 제공하지 않는 이유
btrfs filesystem defragment는 커널 3.9 이후로 reflink를 보존하지 않습니다. 매뉴얼 페이지에 명확히 나와 있습니다: 조각 모음은 copy-on-write 데이터의 reflink를 해제하여 상당한 공간 사용량 증가를 초래할 수 있습니다. 파일을 연속적으로 재작성하면 모든 공유 익스텐트가 개별 복사본으로 복사됩니다.
이 머신에서는 거의 모든 것이 공유되어 있습니다. 포크는 reflink를 통해 부모의 데이터를 공유하고, 백업 타이머는 역시 공유하는 읽기 전용 스냅샷을 추가합니다. 풀은 4.4 GB의 여유 공간으로 99% 차 있습니다. GitLab은 97% 공유되어 있어, 조각 모음하면 약 14 GB를 4.4 GB에 복사하려다 도중에 실패할 것입니다. Stack Overflow 데모는 26 MB의 고유 데이터로 137 GB이므로, 조각 모음하면 실제로 존재하지 않는 137 GB를 실체화하려 할 것입니다. 모든 저장소에 걸쳐 약 250 GB가 reflink로 연결되어 있습니다. 조각 모음 패스는 튜닝이 아니라 공간 폭탄입니다.
맞아 들어간다 해도 오래 가지 않을 것입니다. 이 이미지들은 동일한 무작위 쓰기 워크로드 아래 수분 내에 다시 단편화됩니다. 포크의 공유를 잠깐 해제하고, 벤치마크가 이미 갖고 있다고 말하는 읽기 속도를 얻게 될 뿐입니다.
단편화 대신 읽어야 할 것
같은 보고서에서 주목할 가치가 있는 열은 분기(Divergence)입니다. 이는 포크와 스냅샷과 공유되지 않고 해당 저장소에만 고유한 이미지 비율입니다. 새로운 포크는 거의 모든 것을 공유하기 때문에 0%에 가깝습니다. 포크된 이후 쓰기가 많았던 저장소는 100%를 향해 올라갑니다.
분기는 단편화가 답할 수 없는 질문에 답합니다: 이 저장소가 얼마나 많은 실제 회수 가능한 디스크를 차지하는가. 풀이 빡빡할 때, 분기가 낮은 저장소는 정리하기 좋은 대상이 아닙니다. 해당 바이트들은 공유되어 있어 삭제해도 거의 해제되지 않기 때문입니다. 바이트는 분기가 높은 곳에 있습니다.
결론
단편화 수치는 실제이고, copy-on-write 이미지에서 무작위 쓰기 아래에서는 항상 높게 보일 것입니다. 플래시에서는 정보 제공용입니다. 저는 16배의 차이를 측정했고 읽기 패널티를 발견하지 못했으며, 더 단편화된 파일에서 더 빠른 무작위 프로필을 확인했고, 백그라운드 스캔 시간에서 하나의 작은 비용을 발견했습니다. 숫자를 “수정”할 도구는 대신 포크들을 4분의 1 테라바이트 분량으로 공간이 없는 풀에 공유 해제시킬 것입니다.
그래서 Rediacc는 단편화를 보고하고 설명하며, 이에 대해 조치할 버튼을 제공하지 않습니다. 솔직한 엔지니어링 답변은 반사를 자동화하는 것이 아니라 가정을 벤치마크하는 것이었습니다.