13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] ext4 성능

  • [Linux] ext4 디스크 I/O 성능 저하 원인 분석 및 진단 방법

    [Linux] ext4 디스크 I/O 성능 저하 원인 분석 및 진단 방법

    [Linux] ext4 디스크 I/O 성능 저하 원인 분석 및 진단 방법

    안녕하세요, 13년차 서버실 지킴이입니다. 🤓

    어느 날 갑자기 서버가 느려졌는데, CPU나 메모리 사용량은 평온하고 네트워크 트래픽도 평소와 다를 바 없을 때, 문득 이런 생각이 들지 않으세요? “혹시 ext4의 디스크 I/O 문제인가?” 네, 정확한 추측일 수도 있어요. 리눅스 서버에서 가장 흔하게 사용되는 파일시스템인 ext4에서 성능 저하가 벌어지면 정말 당황스럽죠. 특히 서비스 운영 중이라면 심장이 덜컥 내려앉을 겁니다.

    저도 홈랩에서 이것저것 실험하다가 갑자기 디스크 읽기/쓰기 속도가 확 떨어져서 며칠 밤낮을 삽질했던 경험이 있거든요. 처음엔 설정 문제인가 싶었는데, 알고 보니 ext4 파일시스템 자체의 특성이나 잘못된 마운트 옵션, 혹은 숨겨진 병목 때문이었더라고요. 그래서 오늘은 ext4 디스크 I/O 성능 저하의 원인을 파헤치고, 어떻게 진단하고 해결할 수 있는지 제 경험을 바탕으로 솔직하게 풀어보려 합니다. 함께 리눅스 디스크 I/O 문제를 해결해 봅시다! 💡

    리눅스 서버의 ext4 파일시스템 I/O 흐름 및 잠재적 병목 지점 개요 다이어그램

    ext4 파일시스템과 디스크 I/O, 대체 뭐가 문제일까요? 🤔

    먼저, 기본적인 개념부터 짚고 넘어갈게요. 디스크 I/O(Input/Output)는 말 그대로 디스크에 데이터를 쓰고(write) 읽는(read) 작업을 말합니다. 서버 애플리케이션의 응답 속도는 이 디스크 I/O 성능에 크게 좌우되죠. 웹 서버의 로그 기록, 데이터베이스의 쿼리 처리, 캐시 파일 저장 등 거의 모든 작업이 디스크 I/O를 수반하거든요.

    ext4는 리눅스에서 가장 널리 사용되는 저널링 파일시스템(Journaling Filesystem)입니다. 저널링 덕분에 시스템 크래시(crash) 시 데이터 일관성(data consistency)을 보장하는 강력한 장점이 있지만, 이 저널링 과정 자체가 때로는 I/O 성능 오버헤드(overhead)로 작용할 수 있어요. 쉽게 말해, 데이터를 변경하기 전에 먼저 변경 내용을 저널(journal)이라는 특별한 영역에 기록하고 나서 실제 데이터 영역에 쓰는 방식이라, 안정성은 높지만 그만큼 추가적인 디스크 작업이 필요하다는 거죠.

    ext4의 성능에 영향을 미치는 주요 요소는 다음과 같습니다:

    • 저널링 모드 (Journaling Mode): data=journal, data=ordered, data=writeback 등 모드에 따라 데이터 안정성과 성능이 달라집니다.
    • 블록 사이즈 (Block Size): 파일시스템 생성 시 지정하는 데이터 처리 단위로, 작은 파일이 많으면 작은 블록 사이즈가, 큰 파일이 많으면 큰 블록 사이즈가 유리할 수 있습니다.
    • 마운트 옵션 (Mount Options): noatime, discard, barrier=0 등 다양한 옵션으로 성능을 튜닝할 수 있습니다.
    • 디스크 자체 성능: HDD냐 SSD냐, RAID 구성이냐 등 물리적인 디스크의 스펙도 중요하죠.
    • 파일 단편화 (Fragmentation): 파일이 디스크 여러 곳에 흩어져 저장되면 읽기/쓰기 성능이 저하됩니다.

    실전! ext4 디스크 I/O 성능 진단 도구 활용법 🛠️

    자, 이제 실제로 서버에서 디스크 I/O 병목을 어떻게 찾아내는지 알아볼 차례입니다. 리눅스에는 정말 유용한 도구들이 많아요. 제가 즐겨 쓰는 몇 가지를 소개합니다.

    1. iostat: 시스템 전체 디스크 I/O 통계

    iostat은 시스템 전체의 디스크 I/O 통계를 실시간으로 보여주는 강력한 도구예요. 특정 디스크의 사용률, 큐 길이, 응답 시간 등을 한눈에 파악할 수 있거든요.

    # iostat -x 1 5
    # -x: 확장 통계 정보 출력 (extended statistics)
    # 1: 1초 간격으로
    # 5: 5번 반복 출력
    
    Linux 5.15.0-78-generic (my-server) 	08/20/2023 	_x86_64_ 	(8 CPU)
    
    avg-cpu:  %user   %nice %system %iowait  %steal   %idle
               1.20    0.00    0.80    0.10    0.00   97.90
    
    Device             r/s   w/s   rkB/s   wkB/s  avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
    sda               0.10  0.00    2.00    0.00     40.00     0.00    0.20    0.20    0.00   0.20   0.00
    sdb               0.00  0.00    0.00    0.00      0.00     0.00    0.00    0.00    0.00   0.00   0.00
    

    여기서 봐야 할 핵심 지표들은 다음과 같습니다:

    • %util: 디스크 사용률입니다. 100%에 가깝다면 디스크가 항상 바쁘다는 뜻인데, 성능 병목의 강력한 신호일 수 있어요. (⚠️ 단, 고성능 NVMe SSD의 경우 100%에 가까워도 실제 성능은 좋을 수 있으니 다른 지표와 함께 봐야 합니다!)
    • avgqu-sz (Average Queue Size): 디스크 I/O 요청 큐의 평균 길이입니다. 이 값이 지속적으로 높다면 디스크가 요청을 처리하지 못하고 대기 중인 작업이 많다는 뜻이에요. 보통 1 이상이면 주의 깊게 봐야 합니다.
    • await (Average Wait Time): I/O 요청이 디스크에서 처리되기까지 걸리는 평균 시간(밀리초)입니다. 큐에서 대기하는 시간까지 포함하므로, 이 값이 높으면 응답성이 떨어진다는 의미죠.
    • svctm (Average Service Time): I/O 요청이 디스크 컨트롤러에 의해 실제로 처리되는 평균 시간(밀리초)입니다. await과 svctm의 차이가 크다면, 큐에서 대기하는 시간이 길다는 의미로 해석할 수 있어요.

    2. sar -d: 상세 디스크 활동 통계

    sar는 시스템 활동 리포트(System Activity Reporter)의 약자로, CPU, 메모리, 네트워크 등 다양한 시스템 통계를 기록하고 분석할 수 있습니다. 디스크 I/O를 보려면 -d 옵션을 사용하면 되죠.

    # sar -d 1 5
    # -d: 디스크 활동 통계 출력
    # 1: 1초 간격으로
    # 5: 5번 반복 출력
    
    Linux 5.15.0-78-generic (my-server) 	08/20/2023 	_x86_64_ 	(8 CPU)
    
    02:30:01 PM   DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz  await  svctm  %util
    02:30:02 PM   sda      0.10      2.00      0.00     40.00      0.00   0.20   0.20   0.00
    02:30:02 PM   sdb      0.00      0.00      0.00      0.00      0.00   0.00   0.00   0.00
    

    iostat과 비슷한 지표들을 제공하지만, sar는 기록된 데이터를 나중에 분석할 때 유용해요. 특히 tps (초당 전송 수), rd_sec/s (초당 읽기 섹터 수), wr_sec/s (초당 쓰기 섹터 수)를 통해 디스크의 처리량(throughput)을 가늠해볼 수 있습니다. sar는 sysstat 패키지에 포함되어 있으니, 설치되어 있지 않다면 sudo apt install sysstat (Debian/Ubuntu) 또는 sudo yum install sysstat (CentOS/RHEL)로 설치해 주세요.

    3. iotop: 프로세스별 디스크 I/O 사용량

    시스템 전체나 특정 디스크의 I/O 통계를 봤는데, 어떤 프로세스가 디스크를 많이 쓰고 있는지 궁금할 때가 있습니다. 이럴 땐 iotop이 아주 유용해요. 마치 top 명령어처럼 프로세스별 I/O 사용량을 실시간으로 보여주거든요.

    # iotop
    # -o: 현재 I/O를 사용하는 프로세스만 표시
    # -P: 프로세스만 표시 (스레드 제외)
    
    Total DISK READ :       0.00 B/s | Total DISK WRITE :       0.00 B/s
    Actual DISK READ:       0.00 B/s | Actual DISK WRITE:       0.00 B/s
      TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
        1 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % init
        2 be/4 root        0.00 B/s    0.00 B/s  0.00 %  0.00 % [kthreadd]
      ...
    

    iotop을 실행하면 어떤 프로세스가 디스크를 가장 많이 쓰고 있는지 바로 알 수 있어요. IO> 컬럼을 통해 I/O 대기(wait) 상태를 파악할 수 있고, 이를 통해 특정 애플리케이션이나 서비스가 디스크 병목을 유발하는 주범인지 쉽게 찾아낼 수 있습니다. 💡

    iotop 명령어로 확인하는 프로세스별 디스크 I/O 사용량

    iotop 명령어를 통해 실시간 프로세스별 디스크 I/O 사용량을 확인하는 모습

    ⚠️ 삽질 경험담: ext4 마운트 옵션과 저널링의 함정

    제가 가장 많이 삽질했던 부분 중 하나가 바로 ext4의 마운트 옵션(Mount Options)과 저널링(Journaling)이었습니다. 단순히 디스크를 마운트할 때 아무 생각 없이 기본값으로 쓰다가 나중에 피를 본 적이 많거든요. 특히 작은 파일을 빈번하게 읽고 쓰는 웹 서버나 캐시 서버에서 이런 문제가 자주 발생하더라고요.

    1. atime 업데이트 오버헤드

    기본적으로 리눅스 파일시스템은 파일에 접근(access)할 때마다 atime(access time)을 업데이트합니다. 이게 참 좋은 기능이지만, 문제는 파일에 접근할 때마다 디스크 쓰기 작업이 발생한다는 거예요. 즉, 읽기 작업인데도 쓰기 I/O가 발생해 성능 저하를 일으킬 수 있어요. 그래서 저는 특별한 이유가 없다면 noatime 옵션을 즐겨 사용합니다.

    # /etc/fstab 파일 예시
    UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /data ext4 defaults,noatime,errors=remount-ro 0 1
    
    # 변경 후 적용
    sudo mount -o remount /data
    

    noatime은 atime 업데이트를 완전히 비활성화합니다. 만약 atime 정보가 필요하지만 I/O 오버헤드를 줄이고 싶다면 relatime 옵션을 사용할 수도 있어요. relatime은 마지막 접근 시간이 마지막 변경 시간(mtime)보다 오래되었을 때만 atime을 업데이트합니다. 대부분의 경우 relatime으로도 충분하고, 극단적인 성능이 필요하면 noatime을 사용하죠.

    2. 저널링 모드 선택

    앞서 설명했듯이, ext4는 저널링 모드에 따라 성능과 데이터 안정성이 달라집니다. 주요 모드는 세 가지입니다.

    • data=journal: 데이터와 메타데이터(metadata) 모두 저널에 기록합니다. 가장 안전하지만, 가장 느려요. 데이터 일관성이 최우선인 경우에만 고려해볼 만합니다.
    • data=ordered (기본값): 메타데이터만 저널에 기록하고, 데이터는 메타데이터가 커밋(commit)되기 전에 디스크에 쓰여지도록 보장합니다. 안정성과 성능의 균형이 좋아서 대부분의 경우에 적합하죠.
    • data=writeback: 메타데이터만 저널에 기록하고, 데이터는 저널링되지 않습니다. 가장 빠르지만, 시스템 크래시 시 데이터 손실 위험이 있어요. 캐시 디스크나 로그 디스크처럼 데이터 손실이 치명적이지 않은 경우에 고려할 수 있습니다.

    저널링 모드 변경은 파일시스템 생성 시 또는 tune2fs 명령으로 변경 가능하지만, 마운트 옵션으로도 지정할 수 있어요. 예를 들어, 성능을 최우선으로 한다면:

    # /etc/fstab 파일 예시
    UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /cache ext4 defaults,noatime,data=writeback 0 2
    
    # 변경 후 적용
    sudo mount -o remount /cache
    

    ⚠️ data=writeback은 데이터 손실 위험이 있으니 신중하게 사용하세요!

    3. 그 외 유용한 마운트 옵션

    몇 가지 더 유용한 옵션들을 표로 정리해봤습니다.

    옵션 설명 효과 주의사항
    noatime 파일 접근 시간(atime) 업데이트 비활성화 읽기 I/O 발생 시 쓰기 I/O 감소 atime 정보가 필요한 애플리케이션에 문제 발생 가능
    relatime mtime보다 오래된 atime만 업데이트 noatime과 atime 업데이트의 절충안 대부분의 경우 noatime 대신 사용 권장
    data=writeback 데이터 저널링 비활성화 가장 빠른 쓰기 성능 시스템 크래시 시 데이터 손실 위험
    barrier=0 디스크 쓰기 배리어(write barrier) 비활성화 일부 환경에서 쓰기 성능 향상 RAID 컨트롤러 또는 가상 환경에서 데이터 손실 위험 증가, 신중히 사용
    discard TRIM 명령 활성화 (SSD에 유용) SSD 성능 유지 및 수명 연장 지속적인 TRIM으로 인한 오버헤드 발생 가능 (주기적인 fstrim 권장)
    ext4 마운트 옵션별 성능 및 데이터 안정성 비교 인포그래픽

    ext4 마운트 옵션별 성능 및 데이터 안정성 비교

    ✅ 검증 및 결과 확인: 성능 개선을 눈으로 확인하기!

    마운트 옵션을 변경했거나, 문제가 되는 프로세스를 해결했다면, 이제 정말로 성능이 개선되었는지 확인해야겠죠? 저는 주로 iostat이나 sar로 다시 한번 지표를 확인해요. 특히 await, avgqu-sz, %util 값이 어떻게 변했는지 집중해서 봅니다.

    • await 값이 5ms 미만으로 꾸준히 유지된다면 양호한 수준입니다. 10ms 이상으로 지속된다면 여전히 I/O 병목이 있을 가능성이 높아요.
    • avgqu-sz 값이 1 이하로 떨어졌는지 확인해요. 이 값이 높으면 I/O 요청이 계속 밀리고 있다는 뜻이거든요.
    • %util은 무조건 낮다고 좋은 건 아니지만, 과도하게 높으면서 다른 지표들(await, avgqu-sz)도 높다면 문제가 있다는 신호예요.

    만약 특정 애플리케이션의 성능 저하가 문제였다면, 해당 애플리케이션의 응답 시간(response time)이나 처리량(throughput) 지표를 직접 확인하는 것이 가장 정확해요. 예를 들어, 데이터베이스 쿼리 속도가 빨라졌는지, 웹 페이지 로딩 시간이 단축되었는지 등을 측정해보는 거죠. 저는 Grafana와 Prometheus를 활용해서 I/O 지표를 시각화해서 보곤 하는데, 이렇게 하면 변화 추이를 한눈에 파악하기 정말 편하더라고요. 🎉

    Grafana 대시보드에서 디스크 I/O 성능 개선 추이를 시각적으로 확인하는 예시

    마무리: 나의 ext4는 어떤 길을 가야 할까? 🚀

    ext4 디스크 I/O 성능 문제는 정말 흔하고, 처음엔 막막하게 느껴질 수 있어요. 하지만 iostat, sar, iotop 같은 도구들을 활용해서 정확한 원인을 파악하고, 적절한 마운트 옵션 튜닝이나 저널링 모드 변경을 통해 충분히 해결할 수 있습니다.

    결론적으로, “내 ext4는 어떤 설정이 최적일까?”라는 질문에 대한 답은 “어떤 데이터를, 어떻게 사용하는지에 따라 다르다”는 거예요.

    • 만약 데이터 일관성과 안전성이 최우선이라면, data=ordered (기본값)를 유지하고, noatime보다는 relatime을 고려하는 것이 좋습니다.
    • 로그 파일이나 캐시처럼 데이터 손실에 비교적 관대한 환경에서 최고의 쓰기 성능을 원한다면, data=writeback과 noatime 조합을 신중하게 테스트해볼 수 있습니다. 하지만 이 경우 백업 전략을 더욱 철저히 해야겠죠.
    • SSD를 사용 중이라면, discard 옵션을 사용하거나 주기적으로 fstrim 명령을 실행하여 성능을 유지하는 것이 좋아요.

    이번 글이 여러분의 ext4 성능 문제 해결에 작은 도움이 되었기를 바랍니다. 다음번에는 파일 단편화(fragmentation) 문제를 깊이 다루거나, 더 나아가 ZFS나 Btrfs 같은 다른 파일시스템의 성능 튜닝에 대해서도 이야기해볼까 합니다. 궁금한 점이 있다면 언제든 댓글로 남겨주세요! 저의 삽질 경험이 또 다른 글이 될 수 있으니까요. 😉

  • [Linux] NVMe SSD 환경 파일 시스템 벤치마크: ext4, XFS, Btrfs, ZFS 성능 비교

    [Linux] NVMe SSD 환경 파일 시스템 벤치마크: ext4, XFS, Btrfs, ZFS 성능 비교

    [Linux] NVMe SSD 환경 파일 시스템 벤치마크: ext4, XFS, Btrfs, ZFS 성능 비교

    NVMe SSD 리눅스 파일 시스템 조합, 이거 생각보다 성능 차이가 꽤 크게 나더라고요. 저도 홈랩에서 VM 스토리지랑 컨테이너 볼륨을 굴리면서 처음엔 그냥 ext4로 통일했었는데, 실제로 써보니까 워크로드(작업 부하)에 따라 XFS가 더 편한 경우도 있고, Btrfs나 ZFS처럼 기능이 많은 파일 시스템이 운영 안정성 면에서 더 낫다고 느낀 순간도 있었습니다. 그래서 이번 글에서는 NVMe SSD 환경 리눅스 파일 시스템을 기준으로, ext4 성능, XFS 성능, Btrfs 성능, ZFS 성능을 어떻게 비교해야 하는지, 그리고 파일 시스템 벤치마크를 할 때 어떤 함정을 피해야 하는지 정리해보겠습니다.

    중요한 포인트부터 말씀드리면, 벤치마크 숫자 하나만 보고 파일 시스템을 고르면 나중에 꼭 후회합니다. 순차 읽기/쓰기만 빠르다고 끝이 아니거든요. 메타데이터(파일 정보) 처리, 작은 파일 다량 생성, 스냅샷(시점 복사), 압축, 복구 편의성까지 같이 봐야 합니다. 여기서 제일 중요한 건 벤치마크는 숫자 놀이가 아니라 운영 시나리오 검증이어야 한다는 거예요.

    NVMe SSD 위에서 여러 리눅스 파일 시스템이 서로 다른 특성과 워크로드를 가지는 모습을 한눈에 보여주는 개요 이미지입니다.

    1. 왜 NVMe SSD에서는 파일 시스템 선택이 더 중요할까요?

    예전 SATA SSD 시절에도 파일 시스템 차이는 있었지만, NVMe SSD로 오면 대기 시간(지연 시간)이 낮아지고 병렬 처리 성능이 올라가면서 병목이 더 위로 올라옵니다. 쉽게 말해, 디스크가 느려서 묻히던 차이가 파일 시스템 계층에서 더 잘 드러난다는 뜻입니다.

    • ext4: 기본기가 탄탄하고 범용성이 좋습니다.
    • XFS: 큰 파일, 병렬 I/O, 서버 워크로드에서 자주 거론됩니다.
    • Btrfs: 스냅샷과 서브볼륨(하위 볼륨)이 강점입니다.
    • ZFS: 데이터 무결성(데이터 정확성)과 고급 기능이 강력하지만 메모리 사용과 운영 복잡도도 같이 따라옵니다.

    실제로 써보니까, VM 이미지처럼 큰 파일을 연속으로 다루는 환경과, CI 캐시나 컨테이너 레이어처럼 작은 파일이 쏟아지는 환경은 체감이 완전히 다르더라고요. 그래서 NVMe SSD 리눅스 파일 시스템 비교는 단순 평균이 아니라 시나리오별 해석이 핵심입니다.

    2. ext4, XFS, Btrfs, ZFS를 쉽게 정리해보면

    저도 처음엔 헷갈렸는데, 이렇게 보면 좀 편합니다.

    파일 시스템 성격 강점 주의할 점
    ext4 표준형 안정적, 관리 쉬움, 범용성 좋음 고급 스냅샷 기능은 별도 계층 필요
    XFS 병렬 처리형 큰 파일, 높은 동시성, 서버 환경 적합 작은 파일/특정 메타데이터 패턴은 직접 검증 필요
    Btrfs 기능 통합형 스냅샷, 압축, 서브볼륨 CoW(Copy-on-Write) 특성 이해 필요
    ZFS 무결성 중심형 체크섬, 스냅샷, 압축, 관리 기능 풍부 메모리와 운영 방식 이해가 필요, 리눅스 기본 내장 FS는 아님

    ext4 성능은 대체로 예측 가능하고 무난한 편입니다. 반면 XFS 성능은 병렬 쓰기나 대용량 파일 위주에서 장점이 보이는 경우가 많고요. Btrfs 성능은 기능을 많이 켜는 대신 워크로드에 따라 편차가 생길 수 있습니다. ZFS 성능도 압축, recordsize, ARC(메모리 캐시) 설정에 영향을 꽤 받습니다.

    3. 벤치마크 전에 꼭 정해야 할 테스트 원칙

    여기서 삽질을 가장 많이 합니다 ㅎㅎ 저도 예전에 캐시를 비우는 절차 없이 돌렸다가 결과가 너무 예쁘게 나와서 좋아했는데, 다시 보니까 거의 메모리 테스트였던 적이 있거든요.

    1. 같은 NVMe SSD, 같은 파티션 크기, 같은 커널(운영체제 핵심) 환경에서 비교합니다.
    2. 가능하면 파일 시스템마다 새로 생성한 빈 볼륨에서 시작합니다.
    3. 순차 읽기/쓰기와 랜덤 읽기/쓰기, 둘 다 측정합니다.
    4. 작은 파일 메타데이터 성능과 큰 파일 처리 성능을 분리해서 봅니다.
    5. 압축, CoW, atime 같은 옵션은 켠 상태와 끈 상태를 구분합니다.
    6. 최소 2~3회 반복 실행해서 편차를 확인합니다.

    벤치마크 도구는 보통 fio를 많이 씁니다. 이유는 간단합니다. 블록 크기, 큐 깊이, 동시 작업 수를 세밀하게 조절할 수 있어서 실제 서버 부하에 가깝게 흉내 내기 좋거든요.

    4. NVMe SSD 리눅스 파일 시스템 벤치마크 실전 준비

    아래 예시는 테스트 디바이스를 별도 디스크 또는 실험용 파티션으로 가정합니다. 운영 중인 루트 파일 시스템에 바로 적용하면 위험합니다. 반드시 테스트 환경에서 진행하세요.

    4-1. 테스트 장치 확인

    lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT,MODEL
    nvme list
    

    먼저 대상 NVMe 장치를 정확히 확인합니다. 장치명을 잘못 잡으면 진짜 눈물 납니다. 저도 예전에 테스트한다고 했다가 다른 디스크를 지울 뻔했었네요.

    4-2. 파일 시스템 생성 예시

    # ext4
    sudo mkfs.ext4 /dev/nvme1n1p1
    
    # XFS
    sudo mkfs.xfs -f /dev/nvme1n1p1
    
    # Btrfs
    sudo mkfs.btrfs -f /dev/nvme1n1p1
    
    # ZFS는 별도 풀(pool) 생성 방식 사용
    sudo zpool create benchpool /dev/nvme1n1p1
    sudo zfs create benchpool/testfs
    

    ZFS는 ext4, XFS, Btrfs처럼 단순 mkfs 흐름과는 좀 다릅니다. 처음엔 이게 뭔가 싶었는데, ZFS는 파일 시스템만 따로 보는 게 아니라 스토리지 관리 계층까지 같이 보는 구조라서 그렇습니다.

    4-3. 마운트 옵션 예시

    # ext4
    sudo mount -o noatime /dev/nvme1n1p1 /mnt/bench
    
    # XFS
    sudo mount -o noatime /dev/nvme1n1p1 /mnt/bench
    
    # Btrfs
    sudo mount -o noatime,compress=zstd /dev/nvme1n1p1 /mnt/bench
    
    # ZFS
    sudo zfs set atime=off benchpool/testfs
    sudo zfs set compression=lz4 benchpool/testfs
    

    noatime은 접근 시간(access time) 갱신을 줄여서 불필요한 쓰기를 줄이는 데 도움이 됩니다. 다만 환경에 따라 기본값이나 운영 정책이 다를 수 있으니 무조건 정답은 아닙니다.

    NVMe SSD 리눅스 파일 시스템 벤치마크 구성도

    벤치마크 대상 NVMe SSD, 마운트 포인트, fio 테스트 흐름을 단계별로 보여주는 실전 구성 이미지입니다.

    4-4. fio 벤치마크 스크립트 예시

    cat > fio-randread.fio <<'EOF'
    [global]
    ioengine=libaio
    direct=1
    runtime=60
    time_based=1
    group_reporting=1
    filename=/mnt/bench/testfile.bin
    size=8G
    
    [randread-4k]
    bs=4k
    rw=randread
    iodepth=32
    numjobs=4
    EOF
    
    fio fio-randread.fio
    
    cat > fio-seqwrite.fio <<'EOF'
    [global]
    ioengine=libaio
    direct=1
    runtime=60
    time_based=1
    group_reporting=1
    filename=/mnt/bench/testfile.bin
    size=8G
    
    [seqwrite-1m]
    bs=1m
    rw=write
    iodepth=32
    numjobs=1
    EOF
    
    fio fio-seqwrite.fio
    

    여기서 4K 랜덤 읽기는 작은 I/O가 많은 데이터베이스나 VM 메타데이터 패턴을 보는 데 좋고, 1M 순차 쓰기는 큰 파일 복사나 백업 이미지 생성 같은 상황을 가정하기 좋습니다.

    5. 파일 시스템별로 벤치마크 해석 포인트가 다릅니다

    같은 fio 결과라도 읽는 법이 다릅니다. 숫자만 보지 말고 특성까지 같이 봐야 합니다.

    • ext4: 전반적으로 균형이 좋고, 기본 설정에서도 큰 이슈 없이 결과가 나오는 편입니다.
    • XFS: 동시성(동시에 여러 작업 처리)과 대용량 파일 흐름에서 강점을 기대할 수 있습니다.
    • Btrfs: 압축과 스냅샷은 장점이지만, CoW 특성 때문에 일부 쓰기 패턴은 결과를 따로 봐야 합니다.
    • ZFS: recordsize, compression, ARC 같은 설정이 결과에 영향을 주므로 기본값만 보고 단정하면 안 됩니다.

    실제로 써보니까 Btrfs와 ZFS는 기능이 성능 결과에 직접 개입합니다. 그래서 기능을 끈 상태, 켠 상태를 분리해서 비교하는 게 맞더라고요. 예를 들어 압축이 켜졌다고 무조건 느려지는 게 아니라, CPU 여유가 있고 데이터 압축률이 괜찮으면 오히려 체감 I/O가 줄어드는 경우도 있습니다.

    6. ⚠️ 제가 실제로 겪었던 트러블슈팅 포인트

    이 섹션은 진짜 중요합니다. 벤치마크는 잘못하면 재현성(다시 해도 비슷한 결과가 나오는 성질)이 박살 나거든요.

    6-1. 페이지 캐시 때문에 결과가 이상하게 잘 나올 때

    첫 실행보다 두 번째 실행이 비정상적으로 빠르면 페이지 캐시를 의심해야 합니다. direct I/O를 써도 워크로드에 따라 캐시 영향이 완전히 사라지지 않는 경우가 있어서, 테스트 순서와 파일 초기화 상태를 일정하게 맞추는 게 중요합니다.

    6-2. Btrfs의 CoW가 로그/DB 파일에 불리할 때

    작은 랜덤 업데이트가 많은 파일은 CoW 특성 때문에 쓰기 증폭(실제 기록량 증가)이 체감될 수 있습니다. 이런 경우는 파일 단위 NOCOW 설정 같은 운영 전략을 별도로 검토합니다. 다만 이건 워크로드 의존성이 커서, 무조건 끄는 식으로 접근하면 또 다른 장점을 놓칠 수 있습니다.

    6-3. ZFS는 메모리와 설정을 같이 봐야 합니다

    ZFS는 데이터 무결성과 관리 기능이 강력한 대신, 메모리 캐시 활용이 중요한 편입니다. ARC가 잘 동작하는 환경과 그렇지 않은 환경의 체감 차이가 꽤 있습니다. 저도 처음엔 “왜 이렇게 다르지?” 했었는데, 결국 테스트 장비 메모리 구성과 dataset 속성 차이였더라고요.

    6-4. discard/TRIM 처리 방식 차이

    온라인 discard를 바로 걸지, 주기적으로 fstrim을 돌릴지는 배포판과 운영 정책에 따라 다를 수 있습니다. 벤치마크 중에는 이 배경 작업이 개입하지 않게 관리하는 게 좋습니다.

    6-5. 압축 옵션은 공정하게 맞춰야 합니다

    Btrfs나 ZFS에서 압축을 켠 상태와 ext4/XFS 기본 상태를 그대로 비교하면, 그건 “파일 시스템 비교”이면서 동시에 “기능 켠 상태 비교”가 됩니다. 글의 목적에 따라 비교 기준을 명확히 나눠야 합니다.

    Btrfs와 ZFS 옵션이 NVMe SSD 성능에 미치는 영향 이미지

    CoW, 압축, 캐시, TRIM 같은 요소가 벤치마크 결과를 흔드는 원인을 설명하는 트러블슈팅 이미지입니다.

    7. 검증과 결과 정리: 숫자보다 패턴을 보세요

    이번 글에서는 의도적으로 특정 수치를 단정해서 넣지 않았습니다. NVMe SSD 모델, 커널, 마운트 옵션, 메모리 용량, 테스트 데이터 특성에 따라 결과가 꽤 달라지기 때문입니다. 대신 일반적으로 많이 보는 해석 패턴을 정리해보면 아래와 같습니다.

    비교 항목 자주 관찰되는 경향 체크할 포인트
    순차 읽기/쓰기 ext4, XFS가 단순 구성에서 무난한 결과를 내기 쉬움 대용량 파일 위주인지 확인
    랜덤 4K 옵션과 큐 깊이에 따라 차이가 크게 남 DB/VM 패턴과 유사한지 확인
    메타데이터 작업 파일 생성/삭제/rename 패턴에서 차이가 드러남 작은 파일 수가 많은지 확인
    스냅샷/압축 Btrfs, ZFS가 기능상 이점이 큼 성능과 운영 편의성 함께 평가
    운영 단순성 ext4가 가장 익숙하고 단순한 편 장애 대응 경험도 고려

    검증 명령은 이런 식으로 같이 보시면 됩니다.

    fio fio-randread.fio
    fio fio-seqwrite.fio
    iostst -x 1
    vmstat 1
    mount | grep /mnt/bench
    

    iostat로 장치 사용률과 대기 시간을 보고, vmstat로 메모리와 시스템 상태를 같이 봅니다. 벤치마크 결과 파일만 보는 것보다 훨씬 해석이 쉬워집니다. 드디어 됐다! 싶은 순간이 여기서 오는데, 사실 이때부터가 진짜 시작입니다. 왜 빨랐는지, 왜 느렸는지를 설명할 수 있어야 하거든요.

    8. 그래서 어떤 파일 시스템을 고르면 좋을까요?

    정답은 하나가 아닙니다. 제가 직접 해보니 용도별로 이렇게 접근하는 게 현실적이었습니다.

    1. 범용 서버, 운영 단순성 우선: ext4
    2. 대용량 파일, 병렬 I/O, 로그성 서버: XFS 검토
    3. 스냅샷, 서브볼륨, 유연한 관리: Btrfs 검토
    4. 무결성, 스냅샷, 압축, 스토리지 통합 관리: ZFS 검토

    혹시 이런 경험 있으신가요? 벤치마크만 보면 A가 빨랐는데, 운영해보니 B가 훨씬 편했던 경우요. 이게 진짜 자주 일어납니다. 그래서 파일 시스템 벤치마크는 최종 결론이 아니라 의사결정 재료로 보는 게 맞습니다.

    체크리스트도 남겨보겠습니다.

    • 내 워크로드는 작은 파일 위주인가, 큰 파일 위주인가
    • 스냅샷이 꼭 필요한가
    • 압축으로 얻을 이점이 있는가
    • 복구와 운영 난이도를 감당할 수 있는가
    • 팀이 익숙한 파일 시스템인가
    NVMe SSD 리눅스 파일 시스템 선택 기준 비교 이미지

    워크로드별로 ext4, XFS, Btrfs, ZFS 중 어떤 선택이 어울리는지 요약한 비교 인포그래픽입니다.

    9. 마무리: 성능 비교보다 더 중요한 것

    NVMe SSD 리눅스 파일 시스템을 비교할 때 가장 중요한 건, “누가 더 빠르냐”보다 “내 환경에서 어떤 특성이 더 맞느냐”입니다. ext4 성능, XFS 성능, Btrfs 성능, ZFS 성능은 모두 의미가 있지만, 그 숫자는 설정과 부하에 따라 달라집니다. 반면 운영 편의성, 복구 경험, 스냅샷 전략, 백업 체계는 생각보다 오래 갑니다.

    저는 요즘도 홈랩에서 새 워크로드를 올릴 때 먼저 fio로 최소한의 패턴 검증부터 합니다. 한 번 해두면 감이 생기고, 다음에는 훨씬 덜 헤매게 되더라고요. 다음 글에서는 fio 결과를 읽는 법, 그리고 VM/컨테이너/DB별로 어떤 테스트 프로파일을 써야 하는지를 따로 정리해볼 예정입니다. 이전 글에서 다룬 스토리지 모니터링 내용과 함께 보시면 더 이해가 쉬우실 겁니다.

    정리 FAQ

    Q1. NVMe SSD에서는 무조건 XFS가 빠른가요?

    아닙니다. 워크로드에 따라 ext4가 더 무난하거나, 기능 요구 때문에 Btrfs나 ZFS가 더 적합할 수 있습니다.

    Q2. Btrfs나 ZFS는 느리기만 한가요?

    그렇게 단순하지 않습니다. 압축, 스냅샷, 무결성 같은 기능 가치까지 같이 봐야 합니다. 일부 상황에서는 운영 효율이 더 큰 장점이 됩니다.

    Q3. 벤치마크는 어떤 도구부터 시작하면 될까요?

    대부분의 경우 fio부터 시작하시면 됩니다. 순차/랜덤, 블록 크기, 큐 깊이를 조절해 실제 부하와 비슷하게 맞추기 좋습니다.

    Q4. 결과가 매번 다르게 나오는데 정상인가요?

    어느 정도는 정상입니다. 캐시, 백그라운드 작업, SSD 상태, 테스트 순서가 영향을 줄 수 있으니 조건을 최대한 통제해야 합니다.