13년차의 서버실

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

[태그:] fio 벤치마크

  • [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 상태, 테스트 순서가 영향을 줄 수 있으니 조건을 최대한 통제해야 합니다.

  • [Linux] 커널 튜닝 ext4 파일 시스템 성능 최적화 실전 사례

    [Linux] 커널 튜닝 ext4 파일 시스템 성능 최적화 실전 사례

    [Linux] 커널 튜닝 ext4 파일 시스템 성능 최적화 실전 사례

    리눅스 서버를 오래 보다 보면 CPU나 메모리보다도 디스크 I/O가 먼저 발목을 잡는 순간이 꼭 옵니다. 특히 로그가 많이 쌓이거나 작은 파일이 계속 생성되는 워크로드에서는 커널 튜닝 ext4 한 번으로 체감이 확 달라지기도 하거든요. 저도 홈랩과 운영 환경에서 비슷한 문제를 몇 번 겪었는데, 처음엔 애플리케이션 문제인 줄 알고 한참 돌아갔었습니다. 근데 막상 뜯어보니 ext4 마운트 옵션과 writeback(라이트백, 커널의 지연 쓰기) 동작이 핵심이더라고요. 이번 글에서는 Linux 성능 최적화 관점에서 ext4 파일 시스템을 어떻게 점검하고, 어떤 순서로 조정해야 덜 위험하게 성능을 끌어올릴 수 있는지 실제 사례 흐름으로 정리해보겠습니다.

    특히 이 글은 벤치마크 숫자를 과장해서 보여주는 방식이 아니라, 제가 실제로 자주 쓰는 확인 절차와 안전한 튜닝 기준 위주로 풀어갑니다. 혹시 디스크 사용률은 높지 않은데 응답이 한 번씩 뚝 끊기는 경험 있으신가요? 여기서 중요한 포인트가 바로 파일 시스템 자체보다도 파일 시스템 튜닝과 커널 writeback 정책을 같이 봐야 한다는 점입니다.

    커널 튜닝 ext4와 I/O 경로를 설명하는 개요 다이어그램

    애플리케이션 쓰기 요청이 페이지 캐시와 ext4 저널을 거쳐 블록 디바이스로 내려가는 흐름을 보여주는 개요 이미지입니다.

    왜 ext4 성능 개선이 생각보다 큰 차이를 만들까

    쉽게 말해 ext4는 그냥 디스크에 바로 쓰는 시스템이 아닙니다. 애플리케이션이 파일을 쓰면 먼저 page cache(페이지 캐시, 메모리 기반 캐시)에 반영되고, 이후 커널이 적절한 시점에 실제 저장 장치로 내립니다. 여기에 journaling(저널링, 메타데이터 일관성을 위한 기록)까지 얹히니까, 같은 SSD를 써도 마운트 옵션과 커널 파라미터에 따라 체감이 꽤 달라질 수 있어요.

    제가 처음 이걸 제대로 체감한 건 로그 수집 서버였습니다. 디스크는 NVMe였고 CPU도 여유가 있었는데, 특정 시간대만 되면 flush(플러시, 메모리의 변경 내용을 디스크로 밀어내는 작업)가 몰리면서 응답이 출렁이더라고요. 처음엔 “스토리지가 느린가?” 싶었는데 사실 스토리지보다는 쓰기 패턴과 ext4 기본 동작이 workload(워크로드, 실제 작업 특성)과 안 맞았던 겁니다.

    ext4와 커널 튜닝 개념 먼저 정리해보겠습니다

    ext4에서 먼저 봐야 할 핵심 포인트

    • atime: 파일 읽기 때 접근 시간(access time)을 갱신할지 여부입니다.
    • commit: 저널 커밋 주기 관련 옵션입니다. 너무 공격적으로 늘리면 장애 시 최근 변경 유실 범위가 커질 수 있습니다.
    • journaling mode: <code>data=ordered, data=writeback, data=journal 같은 모드가 있습니다.
    • discard: SSD/TRIM 처리 방식입니다. 연속 discard가 편할 때도 있지만, 주기적 fstrim이 더 나은 경우가 많습니다.
    • dirty page: 커널이 메모리에 쌓아두는 더티 페이지 비율입니다. 이게 높아지면 한 번에 밀어내는 양이 커질 수 있어요.

    자주 쓰는 옵션 비교

    항목 의미 장점 주의할 점
    noatime 읽기 시 access time 갱신 비활성화 불필요한 메타데이터 쓰기 감소 atime 의존 프로그램이 있으면 영향 확인 필요
    lazytime 시간 정보 갱신을 지연 반영 메타데이터 쓰기 감소 일부 운영 정책과 충돌 없는지 확인 필요
    commit=30 저널 커밋 간격 증가 잦은 커밋 부담 완화 가능 장애 시 최근 변경 유실 범위 증가 가능
    data=ordered 일반적인 기본 저널링 모드 안정성과 성능 균형 쓰기 특성에 따라 병목 가능
    data=writeback 데이터 기록 순서 보장 완화 일부 쓰기 성능 유리 가능 일관성 측면 주의, 무조건 권장 아님

    여기서 제가 강조하고 싶은 건, ext4 성능 개선은 옵션 몇 개 붙인다고 끝나는 작업이 아니라는 점이에요. 파일 생성이 많은지, 순차 쓰기가 많은지, fsync(에프싱크, 즉시 디스크 반영 요청)가 잦은지에 따라 접근이 달라져야 하거든요.

    실전 사례: 로그 적재 서버에서 지연 스파이크를 줄인 과정

    상황은 이랬습니다. 작은 로그 파일이 자주 쓰이고, 1분 단위 배치 작업이 돌 때 응답 지연이 크게 튀었습니다. 시스템을 보면 CPU는 넉넉했고 메모리도 부족하지 않았습니다. 그런데 iostat와 vmstat를 같이 보니 특정 시점마다 writeback이 몰리더라고요. 저도 처음엔 애플리케이션 쓰레드 문제인 줄 알고 삽질 좀 했습니다 ㅎㅎ 결국 원인은 “작은 쓰기 + 메타데이터 갱신 + flush 집중” 조합이었습니다.

    1. 현재 ext4 마운트 상태부터 확인

    1. 대상 파일 시스템의 마운트 옵션을 확인합니다.
    2. 저널링 모드와 예약 블록, 파일 시스템 특성을 확인합니다.
    3. 실제 장치의 readahead와 I/O 패턴을 함께 봅니다.
    findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /data
    mount | grep ' /data '
    sudo tune2fs -l /dev/nvme0n1p1 | egrep 'Filesystem features|Reserved block count|Block size|Journal'
    sudo dumpe2fs -h /dev/nvme0n1p1 2>/dev/null | egrep 'Filesystem state|Errors behavior|Journal mode'

    이 단계에서 중요한 건 “이미 어떤 옵션이 걸려 있는지”예요. 의외로 relatime 기본값으로 충분한 환경도 있고, 반대로 불필요한 discard가 항상 켜져 있어서 쓰기 경로를 괜히 복잡하게 만드는 경우도 있었습니다.

    2. 병목이 파일 시스템인지, 블록 계층인지 분리

    iostat -xz 1
    vmstat 1
    pidstat -d 1
    sar -b 1

    제가 실제로 자주 보는 건 이 네 가지입니다. iostat로 디바이스 지연과 큐를 보고, vmstat로 dirty page와 writeback 타이밍 감을 잡고, pidstat로 어떤 프로세스가 얼마나 쓰는지 확인합니다. 여기서 애플리케이션 fsync 호출이 잦으면 ext4 튜닝보다 앱 설정 조정이 먼저일 수 있어요. 그러니까 커널 튜닝 ext4는 언제나 계층 분리를 먼저 해야 합니다.

    3. 안전한 범위의 1차 조정

    제가 처음부터 무리하게 건드리지 않는 항목은 대체로 아래 정도입니다.

    sudo cp /etc/fstab /etc/fstab.bak
    sudo editor /etc/fstab
    UUID=xxxx-xxxx  /data  ext4  defaults,noatime,lazytime,commit=30  0  2

    noatime은 읽기 위주의 접근에서도 불필요한 메타데이터 갱신을 줄이는 데 꽤 도움이 돼요. lazytime은 시간 정보 반영을 지연시켜서 메타데이터 쓰기 부담을 줄일 수 있고요. commit=30은 저널 커밋 빈도를 낮춰 writeback이 너무 자주 발생하는 상황을 완화하는 데 써볼 만합니다. 다만 이 값은 서비스 특성에 따라 보수적으로 잡아야 합니다. 데이터 안전성이 아주 민감하면 함부로 늘리면 안 돼요.

    커널 튜닝 ext4 설정 변경 과정을 보여주는 시스템 점검 이미지

    fstab 편집, findmnt 확인, sysctl 조정 흐름을 한눈에 보여주는 구성 이미지입니다.

    4. 커널 writeback 파라미터도 함께 조정

    파일 시스템 옵션만 바꾸고 끝내면 절반만 본 셈입니다. 실제로 써보니까 flush가 몰리는 서버에서는 이쪽 영향도 꽤 크더라고요.

    sysctl vm.dirty_background_ratio
    sysctl vm.dirty_ratio
    sysctl vm.dirty_expire_centisecs
    sysctl vm.dirty_writeback_centisecs
    sudo tee /etc/sysctl.d/99-ext4-tuning.conf >/dev/null <<'EOF'
    vm.dirty_background_ratio = 5
    vm.dirty_ratio = 20
    vm.dirty_expire_centisecs = 3000
    vm.dirty_writeback_centisecs = 500
    EOF
    sudo sysctl --system

    이 수치는 만능 정답이 아닙니다. 다만 dirty page가 너무 많이 쌓였다가 한꺼번에 내려가는 패턴을 줄이는 출발점으로는 꽤 무난했어요. 저는 메모리가 큰 서버에서 기본값 그대로 두었다가 writeback 몰림이 생긴 적이 있었는데, 이 값을 조정하고 나서 지연 스파이크가 훨씬 덜해졌습니다.

    5. SSD라면 discard 운영 방식 점검

    여기서 한 번 더 많이 헷갈립니다. SSD니까 discard를 무조건 마운트 옵션에 넣어야 할 것 같죠? 저도 예전엔 그렇게 했었는데, 실제론 주기적 TRIM이 더 나은 경우가 적지 않아요.

    systemctl status fstrim.timer
    sudo systemctl enable --now fstrim.timer
    systemctl list-timers | grep fstrim

    즉시 discard보다 주기적 fstrim을 선호하는 이유는, 연속 discard가 쓰기 경로에 부담을 줄 수 있기 때문입니다. 물론 환경에 따라 다르니 확인은 꼭 필요해요.

    ⚠️ 실무에서 자주 만나는 트러블슈팅

    문제 1: noatime 넣었더니 일부 프로그램 동작이 달라졌습니다

    아주 드문 편이긴 하지만 atime을 실제로 참조하는 도구가 있을 수 있습니다. 이런 경우 noatime 대신 기본 relatime 유지가 더 안전해요. 무조건 성능만 보고 밀어붙이면 안 됩니다.

    문제 2: commit 값을 늘렸더니 찜찜합니다

    이건 정상적인 감각입니다. commit 간격을 늘리면 메타데이터 커밋 빈도는 줄 수 있지만, 장애 발생 시 최근 변경이 디스크에 완전히 반영되지 않았을 가능성은 커집니다. 그래서 데이터 무결성이 중요한 DB 데이터 디렉터리에는 저는 보수적으로 접근해요. 로그, 캐시, 재생성 가능한 데이터인지 먼저 구분하세요.

    문제 3: data=writeback으로 바꾸면 더 빠른가요?

    경우에 따라 다를 수는 있어도, 이걸 기본 추천으로 보시면 안 돼요. data=writeback은 데이터 기록 순서 보장이 더 약하므로 장애 시 예상 못 한 상태를 만날 수 있습니다. 제가 운영 서버에서는 대부분 data=ordered를 유지합니다. 성능 때문에 일관성을 희생하는 선택은 언제나 마지막이어야 하거든요.

    문제 4: reserved block이 너무 크게 잡혀 있습니다

    대용량 데이터 볼륨이라면 예약 블록(reserved block) 비율이 과한 경우가 있습니다. 루트 파일 시스템이 아니라 일반 데이터 파티션이면 점검해볼 만해요.

    sudo tune2fs -m 1 /dev/nvme0n1p1

    다만 이것도 서비스 성격을 봐야 합니다. 시스템 영역과 일반 데이터 볼륨은 판단 기준이 다르니까요.

    검증: 바꿨으면 반드시 재현 테스트를 해봐야 합니다

    튜닝은 느낌으로 하면 안 돼요. 저도 처음엔 “체감상 좋아진 것 같은데?” 하고 넘어가려다가 다시 문제를 만난 적이 있습니다. 그래서 지금은 꼭 동일한 패턴의 테스트를 다시 돌립니다.

    fio로 쓰기 패턴 재현

    fio --name=ext4-logtest \
        --directory=/data/fiotest \
        --size=2G \
        --bs=4k \
        --rw=randwrite \
        --iodepth=16 \
        --ioengine=libaio \
        --direct=0 \
        --numjobs=4 \
        --runtime=60 \
        --time_based \
        --group_reporting

    여기서 포인트는 숫자 한 줄만 보지 않는 거예요. IOPS만 보고 “성공!” 하면 나중에 다시 당합니다. 저는 아래 항목을 같이 확인합니다.

    • 지연(latency) 분포가 덜 튀는지
    • 테스트 중 writeback 몰림이 줄었는지
    • 애플리케이션 응답이 실제로 안정적인지
    • 마운트 옵션 변경 후 오류 로그가 없는지
    dmesg -T | tail -n 50
    journalctl -k -n 50
    findmnt -no OPTIONS /data
    ext4 성능 개선 결과를 검증하는 대시보드 이미지

    튜닝 전후의 지연 분포, 쓰기 대기열, writeback 패턴을 비교하는 성능 검증 이미지입니다.

    실제로 해보니까 단순 최고 성능보다 최악 구간이 얼마나 줄었는지가 훨씬 중요했어요. 운영 환경은 평균값보다 꼬리 지연(tail latency, 최악 구간 지연)이 문제를 만들거든요. 이 부분은 다음 글에서 XFS와 ext4를 워크로드별로 비교하면서 더 자세히 다뤄볼 예정입니다.

    정리: 제가 ext4 튜닝할 때 지키는 순서

    1. 현재 마운트 옵션과 저널 상태를 확인합니다.
    2. 디스크 병목인지, 앱의 fsync 패턴인지 먼저 분리합니다.
    3. noatime, lazytime, commit 같은 안전한 범위부터 조정합니다.
    4. 커널 dirty page 정책을 함께 봅니다.
    5. SSD라면 discard 대신 fstrim.timer 운영도 검토합니다.
    6. 반드시 재현 테스트와 커널 로그 확인으로 검증합니다.
    튜닝 대상 먼저 볼 상황 제가 보통 취하는 액션
    메타데이터 쓰기 많음 작은 파일, 잦은 읽기/쓰기 noatime, lazytime 검토
    주기적 지연 스파이크 writeback 몰림 dirty page 관련 sysctl 점검
    SSD 지속 쓰기 부담 discard 상시 사용 fstrim.timer 전환 검토
    데이터 안정성 민감 DB, 중요 서비스 공격적 journaling 변경 지양

    자주 묻는 질문

    ext4보다 다른 파일 시스템이 항상 더 빠른가요?

    항상 그렇진 않아요. 워크로드에 따라 다릅니다. ext4는 여전히 범용성과 안정성 면에서 아주 강한 선택지입니다.

    모든 서버에 noatime을 넣어도 되나요?

    대부분 문제 없지만, atime 의존 프로그램이 아예 없는지 확인은 필요합니다. 운영 표준으로 넣기 전에는 테스트 서버에서 먼저 검증하세요.

    커널 튜닝 ext4는 어느 정도까지 해야 하나요?

    제 기준은 간단해요. 관찰 가능한 병목이 있을 때만, 그리고 되돌릴 수 있는 범위부터입니다. 근거 없는 튜닝은 그냥 리스크죠.

    커널 튜닝 ext4 적용 전후를 요약한 비교 인포그래픽

    운영 반영 전 점검 항목과 튜닝 우선순위를 한 장으로 정리한 요약 이미지입니다.

    마무리

    커널 튜닝 ext4는 화려한 작업은 아닙니다. 그런데 운영 서버에서 한 번 병목이 터졌을 때 가장 현실적으로 효과를 보는 지점이기도 합니다. 제가 직접 해보니 핵심은 “옵션 많이 넣기”가 아니라 “현재 쓰기 패턴을 이해하고, 안전한 범위부터 검증하는 것”이었어요. 드디어 됐다 싶을 때도 로그와 지연 분포를 꼭 다시 보셔야 합니다. 진짜 편하더라고요.

    이번 글에서는 ext4 기준으로 정리했지만, 다음 글에서는 Linux 성능 최적화 관점에서 XFS와 ext4를 어떤 워크로드에서 나눠서 볼지 이어서 다뤄보겠습니다. 이전 글에서 다룬 I/O 스케줄링과 블록 디바이스 점검 내용도 함께 보시면 흐름이 더 잘 잡히실 겁니다. 혹시 지금 운영 중인 서버에서 파일 시스템 튜닝을 고민하고 계시다면, 먼저 현재 마운트 옵션과 iostat 출력부터 확인해보세요. 거기서 절반은 이미 답이 보입니다.

  • [HomeLabs] TrueNAS 파일 시스템 성능 비교: ZFS, Btrfs, ext4 실측 벤치마크

    [HomeLabs] TrueNAS 파일 시스템 성능 비교: ZFS, Btrfs, ext4 실측 벤치마크

    TrueNAS 파일 시스템 성능 비교: ZFS, Btrfs, ext4 실측 벤치마크

    TrueNAS 파일 시스템 성능 이야기는 생각보다 단순하지 않더라고요. 저도 처음엔 “같은 SSD에 올리면 파일 시스템만 바꿔서 보면 되는 거 아닌가?” 싶었는데, 실제로 파고들어 보니 정말 그렇지 않더라고요. 특히 TrueNAS Scale은 기본 저장소 계층이 사실상 ZFS(OpenZFS, 오픈지에프에스) 중심으로 설계돼 있어서, Btrfs(비트리 에프에스)나 ext4(익스트포)를 TrueNAS 풀(pool, 스토리지 집합) 대체재처럼 다루면 바로 비교가 틀어집니다. 그래서 이번 글은 “TrueNAS에서 ZFS를 써야 하나?”라는 질문에 답하기 위해, 동일한 리눅스 계열 환경에서 ZFS, Btrfs, ext4를 같은 방식으로 벤치마크하고 그 결과를 NAS 성능 관점에서 해석하는 방향으로 정리해보겠습니다.

    제가 홈랩에서 이런 테스트를 할 때 가장 많이 보는 건 절대 수치 하나가 아니라 패턴입니다. 순차 읽기/쓰기, 작은 블록 랜덤 I/O, 스냅샷 이후 쓰기 지연, 체크섬(checksum, 데이터 무결성 검사용 해시) 오버헤드 같은 것들이요. 숫자 한 줄만 보면 쉬워 보이는데, 실제 운영에서는 그 숫자보다 “왜 이런 결과가 나왔는지”를 이해하는 쪽이 훨씬 중요하거든요.

    TrueNAS 파일 시스템 성능 비교를 위한 ZFS, Btrfs, ext4 개요 다이어그램

    TrueNAS 환경에서 ZFS를 기준으로 두고 Btrfs, ext4를 비교하는 전체 구조를 보여주는 개요 이미지입니다.

    TrueNAS 파일 시스템 성능 비교에서 먼저 짚어야 할 전제

    여기서 중요한 포인트가 하나 있습니다. TrueNAS의 저장소 풀은 ZFS 기반으로 다루는 것이 공식 문서 흐름과 기능 구조에 맞습니다. 스냅샷(snapshot, 시점 복제), 스크럽(scrub, 무결성 검사), 데이터셋(dataset, ZFS 하위 파일 시스템), 풀 업그레이드 같은 핵심 기능이 ZFS를 중심으로 설계돼 있거든요. 그래서 TrueNAS 파일 시스템 성능을 논할 때 Btrfs나 ext4를 TrueNAS 내부의 동등한 선택지처럼 비교하면 오해가 생기더라고요.

    쉽게 말해 이렇게 보시면 됩니다.

    • ZFS: TrueNAS의 본체에 가까운 기본 철학입니다.
    • Btrfs: 리눅스에서 ZFS와 비교 대상으로 자주 거론되는 COW(Copy-On-Write, 쓰기 시 새 블록 생성) 파일 시스템입니다.
    • ext4: 기능은 비교적 단순하지만 오버헤드가 낮아서 기준선(baseline)으로 보기 좋은 전통적인 저널링 파일 시스템입니다.

    그래서 이 글의 비교는 “TrueNAS에서 셋 중 하나를 선택한다”가 아니라, ZFS 벤치마크 결과가 왜 다르게 보이는지 이해하기 위한 상대 비교라고 보시면 정확합니다.

    ZFS, Btrfs, ext4를 쉽게 풀어보면

    저도 처음엔 이게 뭔가 싶었는데, 파일 시스템은 결국 “데이터를 어떤 방식으로 쓰고, 보호하고, 복구하느냐”의 차이더라고요.

    파일 시스템 핵심 구조 강점 성능 해석 포인트
    ZFS COW, 체크섬, 풀/데이터셋 통합 무결성, 스냅샷, 복제, 관리성 안전장치가 많아서 쓰기 오버헤드가 생길 수 있음
    Btrfs COW, 서브볼륨(subvolume, 하위 볼륨), 스냅샷 유연성, 리눅스 친화성 워크로드에 따라 COW 비용이 민감하게 드러남
    ext4 저널링(journaling, 메타데이터 기록) 단순함, 폭넓은 호환성 기능 오버헤드가 적어 순수 I/O 기준선으로 좋음

    ZFS는 파일 시스템과 볼륨 매니저(volume manager, 디스크 집합 관리)를 같이 들고 가는 느낌이더라고요. 그래서 스냅샷, 압축(compression, 데이터 압축), 스크럽 같은 기능이 아주 자연스럽게 붙습니다. 대신 메모리와 설계 이해도가 어느 정도 필요한 게 맞습니다.

    Btrfs 성능은 꽤 흥미로운데요. 같은 COW 계열이라도 구현 방식과 운영 습관에 따라 체감이 달라집니다. 스냅샷을 많이 쓰는 환경, 작은 파일이 자주 바뀌는 환경에서는 생각보다 결과가 요동치기도 하더라고요.

    ext4 NAS 구성을 따로 운영해보면, 기능보다 단순성과 예측 가능성이 장점으로 드러나더라고요. 다만 TrueNAS처럼 스토리지 무결성과 스냅샷 자동화까지 한 번에 챙기려는 목적이라면 결국 ZFS 쪽으로 다시 돌아오게 되는 경우가 많습니다.

    벤치마크 설계: 숫자보다 조건 통제가 먼저입니다

    벤치마크는 명령어보다 조건 통제가 더 중요합니다. 제가 직접 해보니 여기서 한 번 삐끗하면 결과가 완전히 엉뚱하게 나와요. 특히 ARC(Adaptive Replacement Cache, ZFS 메모리 캐시), 리눅스 페이지 캐시(page cache, 운영체제 파일 캐시), SSD SLC 캐시 같은 요소가 섞이면 파일 시스템 차이가 아니라 캐시 차이만 보게 되거든요.

    1. 동일한 하드웨어를 사용합니다. CPU, RAM, SSD/HDD, 컨트롤러를 고정합니다.
    2. 각 파일 시스템은 빈 디스크에서 새로 생성합니다.
    3. 같은 마운트 포인트 구조와 같은 테스트 파일 크기를 사용합니다.
    4. 벤치마크 전에 캐시 영향을 최소화합니다.
    5. 순차 읽기/쓰기와 랜덤 읽기/쓰기를 분리해서 봅니다.
    6. 스냅샷 이후 쓰기 성능도 따로 확인합니다.

    테스트 워크로드는 보통 아래 네 가지면 충분합니다.

    • 대용량 순차 읽기
    • 대용량 순차 쓰기
    • 4K 또는 16K 랜덤 읽기/쓰기
    • 동시 접속 환경을 가정한 mixed read/write

    혹시 이런 경험 있으신가요? 같은 장비인데 한 번은 ZFS가 느리고, 다른 날은 ext4가 이상하게 느립니다. 이런 경우 대부분 파일 시스템 문제가 아니라 캐시가 안 지워졌거나 테스트 순서가 꼬인 경우가 많더라고요. 저도 삽질 좀 했습니다 ㅎㅎ

    실전 구현: ZFS, Btrfs, ext4 테스트 환경 만들기

    여기서는 리눅스 셸 기준으로 예시를 잡겠습니다. TrueNAS 본체에서 ext4나 Btrfs를 운영용 풀로 올리는 흐름이 아니라, 동일한 리눅스 계열 테스트 노드에서 상대 비교를 수행하는 방식입니다.

    1. 디스크 확인

    lsblk -o NAME,SIZE,MODEL,FSTYPE,MOUNTPOINT
    sudo wipefs -a /dev/sdb
    sudo wipefs -a /dev/sdc
    sudo wipefs -a /dev/sdd

    테스트용 디스크는 반드시 비워두세요. 기존 시그니처(signature, 디스크 식별 정보)가 남아 있으면 생성 단계에서 꼬일 수 있습니다.

    2. ext4 생성

    sudo mkfs.ext4 -F /dev/sdb
    sudo mkdir -p /mnt/bench-ext4
    sudo mount /dev/sdb /mnt/bench-ext4

    3. Btrfs 생성

    sudo mkfs.btrfs -f /dev/sdc
    sudo mkdir -p /mnt/bench-btrfs
    sudo mount /dev/sdc /mnt/bench-btrfs

    4. ZFS 풀 생성

    sudo zpool create bench /dev/sdd
    sudo zfs create bench/data
    sudo zfs set compression=lz4 bench/data

    ZFS는 풀과 데이터셋을 나눠서 보는 습관이 중요합니다. TrueNAS Scale에서도 운영 관점은 거의 이 사고방식으로 이어집니다.

    TrueNAS 파일 시스템 성능 테스트를 위한 ZFS 풀과 ext4, Btrfs 구성 이미지

    ZFS 풀과 데이터셋, ext4와 Btrfs 마운트 경로를 같은 조건으로 맞춘 테스트 구성 이미지입니다.

    5. fio 작업 파일 준비

    cat > fio-seq-write.fio <<'EOF'
    [global]
    ioengine=libaio
    direct=1
    runtime=60
    time_based=1
    group_reporting=1
    size=8G
    filename=testfile
    
    [seqwrite]
    bs=1M
    rw=write
    iodepth=32
    EOF

    랜덤 I/O도 별도 job 파일로 분리하는 게 좋습니다.

    cat > fio-randrw.fio <<'EOF'
    [global]
    ioengine=libaio
    direct=1
    runtime=60
    time_based=1
    group_reporting=1
    size=4G
    filename=testfile
    
    [randrw]
    bs=4k
    rw=randrw
    rwmixread=70
    iodepth=32
    EOF

    6. 각 파일 시스템에서 동일하게 실행

    cd /mnt/bench-ext4 && fio ~/fio-seq-write.fio
    cd /mnt/bench-btrfs && fio ~/fio-seq-write.fio
    cd /bench/data && fio ~/fio-seq-write.fio

    경로는 배포판과 설정에 따라 달라질 수 있습니다. ZFS 데이터셋 마운트 경로는 zfs list로 먼저 확인하세요.

    ⚠️ 실제로 많이 겪는 문제와 트러블슈팅

    이 섹션은 꼭 넣고 싶었습니다. 벤치마크는 명령어보다 삽질 포인트가 더 중요하거든요.

    • 캐시 때문에 두 번째 결과가 더 잘 나오는 문제
      첫 번째 테스트가 디스크 성능이 아니라 캐시 예열 역할을 해버릴 수 있어요. 테스트 순서를 바꾸면서 여러 번 반복해서 평균적인 경향만 보세요.
    • ZFS 압축 설정을 빼먹는 문제
      TrueNAS에서 많이 쓰는 compression=lz4를 끄고 측정하면 실제 운영과 괴리가 생기더라고요. 반대로 비교를 엄격히 하려면 세 파일 시스템 모두 압축 없는 기준과 운영 기준을 나눠 보시는 게 좋습니다.
    • Btrfs에서 스냅샷 후 쓰기 지연이 체감되는 문제
      작은 파일이 자주 바뀌는 워크로드에서는 COW 영향이 꽤 보일 수 있어요. 로그성 데이터나 VM 이미지 파일은 별도로 성격을 나눠 측정해야 합니다.
    • ext4가 무조건 빠르다고 단정하는 문제
      순수 쓰기만 보면 그럴 때가 있지만, 스냅샷/체크섬/복구 편의성까지 포함하면 운영 총비용(total cost of operation, 실제 운영 부담)은 완전히 다른 얘기입니다.
    • TrueNAS에서 ext4, Btrfs를 그대로 대체재처럼 보는 문제
      이건 비교 관점 자체가 어긋난 경우예요. TrueNAS의 핵심 기능 체인은 ZFS를 전제로 보는 편이 맞습니다.

    저는 예전에 ARC를 충분히 비우지 않은 상태에서 ZFS 벤치마크를 돌리고 “이상하게 읽기가 너무 잘 나오네?” 하고 한참 들여다본 적이 있습니다. 나중에 보니 디스크가 아니라 메모리 읽기였어요. 드디어 원인을 찾았을 때 허탈하더라고요.

    검증과 결과 해석: 무엇을 보면 되는가

    TrueNAS 파일 시스템 성능을 해석할 때는 절대값보다 아래 순서로 보시면 훨씬 정확해요.

    1. 순차 읽기/쓰기: 대용량 미디어, 백업 파일, 아카이브 용도에 가깝습니다.
    2. 랜덤 I/O: VM, DB, 메타데이터가 많은 워크로드와 더 가깝습니다.
    3. 스냅샷 이후 성능 변화: 운영 환경에서 체감이 크게 나는 부분입니다.
    4. 복구와 무결성: 장애 이후 사람을 살리는 기능인지 봐야 합니다.

    제가 실제로 써보는 관점에서 정리하면 보통 이런 경향으로 읽혀요.

    항목 대체로 유리한 쪽 해석
    순차 쓰기 ext4 또는 튜닝된 ZFS 오버헤드가 적은 ext4가 기준선 역할을 잘함
    무결성 검증 ZFS 체크섬과 스크럽 체계가 강점
    스냅샷 관리 ZFS, Btrfs ext4는 기본 구조상 비교 우위가 적음
    운영 일관성 ZFS TrueNAS와의 결합도가 높아 관리 흐름이 자연스러움
    단순한 범용성 ext4 호환성과 익숙함이 장점

    ZFS 벤치마크를 볼 때 흔히 하는 오해가 하나 있어요. ext4보다 숫자가 조금 낮게 나오면 “ZFS가 느리다”라고 바로 결론 내리는 건데요. 사실 ZFS는 체크섬, 스냅샷, 풀 관리, 데이터 무결성 같은 운영 기능까지 포함한 저장소 플랫폼에 가깝습니다. 그래서 같은 MB/s라도 의미가 다르더라고요.

    TrueNAS 파일 시스템 성능과 ZFS 벤치마크 결과를 보여주는 대시보드 이미지

    순차 I/O와 랜덤 I/O 결과를 한눈에 비교하고, TrueNAS 스타일의 스토리지 대시보드 느낌을 함께 담은 이미지입니다.

    반대로 Btrfs 성능은 꽤 상황 의존적이더라고요. 스냅샷 활용과 유연한 운영이 장점이지만, NAS를 장기 보관 스토리지처럼 운영할 때는 ZFS의 관리 모델이 더 편하다고 느끼는 분이 많습니다. 저도 백업과 아카이브는 결국 ZFS 쪽으로 정착했었습니다.

    TrueNAS Scale 기준으로 보면 무엇을 선택해야 하나

    결론은 생각보다 명확해요. TrueNAS Scale을 메인 NAS로 운영한다면, 파일 시스템 선택 문제는 사실상 ZFS를 어떻게 잘 쓸 것인가의 문제에 가깝습니다. ext4와 Btrfs는 비교 대상으로는 유익하지만, TrueNAS 내부 운영 철학까지 합치면 ZFS가 중심입니다.

    • 백업 무결성이 최우선이면 ZFS
    • 스냅샷과 복제가 중요하면 ZFS
    • 순수 리눅스 범용 서버에서 단순 볼륨이 필요하면 ext4도 여전히 강력
    • 리눅스 네이티브 스냅샷 실험용이라면 Btrfs도 재미있음

    여기서 중요한 포인트! TrueNAS 파일 시스템 성능은 결국 “가장 빠른 파일 시스템”이 아니라 “내 데이터와 운영 방식에 맞는 저장소 모델”을 찾는 과정입니다. 숫자만 따라가면 나중에 복구, 스냅샷, 확장성에서 후회하는 경우가 꽤 많더라고요.

    TrueNAS 파일 시스템 성능 관점에서 ZFS, Btrfs, ext4를 요약한 인포그래픽

    ZFS, Btrfs, ext4의 장단점과 추천 사용 시나리오를 한 장으로 정리한 요약 이미지입니다.

    정리와 다음 단계

    이번 비교를 한 줄로 정리하면 이렇습니다. ext4는 기준선, Btrfs는 비교군, TrueNAS의 실전 선택은 ZFS입니다. 저도 처음엔 파일 시스템별 최고 속도만 보려고 했었는데, 실제로 써보니까 NAS는 속도보다 무결성, 스냅샷, 장애 대응이 훨씬 오래 남더라고요.

    다음 단계로는 아래 세 가지를 권합니다.

    1. 같은 SSD 또는 HDD로 직접 fio를 돌려 보세요.
    2. ZFS에서는 압축 on/off, 레코드 크기(recordsize, 블록 크기 정책), 동기 쓰기(sync) 조건을 나눠 보세요.
    3. 실사용 워크로드, 예를 들어 SMB 공유, 백업 저장소, VM 스토어를 따로 측정해 보세요.

    이전 글에서 다룬 스토리지 튜닝 내용이 있다면 같이 보셔도 좋고, 다음 글에서는 TrueNAS Scale에서 ZFS 튜닝: recordsize, compression, ARC를 어떻게 잡아야 하는가를 이어서 다뤄볼 예정입니다. 이 부분이 진짜 체감 성능에 더 크게 영향을 주거든요. 혹시 지금 벤치마크를 준비 중이시라면, 먼저 테스트 조건 통제부터 챙겨보세요. 그게 반은 먹고 들어갑니다. 진짜로요.

  • [Nas] TrueNAS SCALE ZFS 성능 벤치마크: 하드웨어별 최적화 전략

    [Nas] TrueNAS SCALE ZFS 성능 벤치마크: 하드웨어별 최적화 전략

    안녕하세요, 13년차의 서버실 주인장입니다. 오늘은 많은 홈랩 유저와 중소기업에서 사랑받는 TrueNAS SCALE, 그중에서도 ZFS 성능 벤치마크와 최적화 전략에 대해 이야기해보려고 해요. 제가 직접 여러 하드웨어 조합으로 삽질하면서 얻은 경험들을 솔직하게 풀어보겠습니다. 혹시 NAS 속도가 답답하다고 느끼셨다면, 이 글이 좋은 가이드가 될 겁니다.

    저도 처음 TrueNAS를 구축했을 때, ‘이 정도면 충분하겠지?’ 했는데 막상 데이터를 쓰고 읽으려니 생각보다 느려서 당황했던 기억이 있거든요. 특히 가상 머신(Virtual Machine)이나 컨테이너(Container)를 돌리거나, 여러 사람이 동시에 접근할 때는 그 느림이 더 확 체감되더라고요. 결국 ‘이건 안 되겠다!’ 싶어서 하드웨어부터 소프트웨어 설정까지 뜯어고쳤죠. 그 과정을 통해 어떤 요소들이 ZFS 성능에 가장 큰 영향을 미치는지 몸소 깨달을 수 있었습니다.

    TrueNAS SCALE의 ZFS 스토리지 아키텍처와 성능에 영향을 미치는 요소들을 시각화한 다이어그램입니다.

    ZFS 성능의 핵심 요소 이해하기

    TrueNAS SCALE의 핵심은 ZFS (Zettabyte File System)입니다. ZFS는 단순히 파일을 저장하는 것 이상의 강력한 데이터 무결성(Data Integrity), 스냅샷(Snapshot), 복제(Replication) 기능을 제공하지만, 그만큼 성능 최적화가 중요하죠. ZFS 성능에 영향을 미치는 주요 개념들을 먼저 짚고 넘어가 볼까요?

    • ARC (Adaptive Replacement Cache, 적응형 교체 캐시): ZFS가 시스템 RAM을 사용하여 자주 접근하는 데이터를 캐싱하는 방식입니다. RAM이 많을수록 캐시 히트율(Cache Hit Ratio)이 높아져 읽기 성능이 비약적으로 향상되죠.
    • L2ARC (Level 2 Adaptive Replacement Cache, 2단계 적응형 교체 캐시): ARC가 부족할 때 SSD 같은 고속 스토리지를 2차 캐시로 활용하는 기능입니다. 주로 읽기(Read) 성능 향상에 기여합니다.
    • SLOG (Separate Intent Log, 분리된 의도 로그) / ZIL (ZFS Intent Log): ZFS는 동기 쓰기(Synchronous Write) 작업을 할 때 데이터를 먼저 ZIL에 기록하여 데이터 무결성을 보장합니다. 이 ZIL을 전용 고속 저장 장치(보통 NVMe SSD)에 분리하여 사용하는 것이 SLOG입니다. SLOG는 쓰기(Write) 성능, 특히 동기 쓰기 성능을 크게 개선해줍니다.
    • VDEV (Virtual Device, 가상 장치): ZFS 풀(Pool)을 구성하는 기본 단위입니다. 여러 디스크를 RAIDZ, 미러(Mirror), 스트라이프(Stripe) 등으로 묶어 VDEV를 만듭니다. VDEV 구성 방식에 따라 성능 특성이 달라집니다.

    하드웨어별 최적화 전략: 뭘 업그레이드해야 할까요?

    NAS 성능은 단순히 디스크 개수를 늘린다고 좋아지는 게 아닙니다. 각 하드웨어 요소들이 ZFS의 특징과 맞물려 복합적으로 작용하거든요. 제가 경험했던 대표적인 하드웨어별 최적화 포인트를 알려드릴게요.

    1. CPU: 뇌가 좋아야 모든 게 빠르다

    ZFS는 데이터 무결성 검사(Checksum), 압축(Compression), 중복 제거(Deduplication) 등 다양한 연산 작업을 수행합니다. 이 모든 작업에 CPU 파워가 필요하죠. 특히 여러 클라이언트가 동시에 접근하거나, 가상 머신이 많이 돌아가는 환경에서는 고성능 CPU가 필수입니다. 저는 처음엔 저전력 CPU를 썼다가 병목 현상 때문에 고생 좀 했습니다. 결국 코어(Core) 수가 많고 클럭(Clock)이 높은 CPU로 바꿨더니 전체적인 응답성이 확 좋아지더라고요.

    2. RAM: 많을수록 좋은 ZFS의 친구

    앞서 설명했듯이 ZFS는 RAM을 ARC로 활용합니다. RAM이 많으면 많을수록 디스크에 접근할 필요 없이 캐시에서 데이터를 바로 읽어올 확률이 높아져요. TrueNAS 공식 권장 사양은 8GB지만, 최소 16GB, 가능하다면 32GB 이상을 권장합니다. 저도 8GB에서 32GB로 업그레이드하고 나서 웹 인터페이스 반응 속도부터 파일 접근 속도까지 전반적인 성능 향상을 체감했습니다. 물론 ECC RAM(Error-Correcting Code RAM)을 사용하면 데이터 무결성을 더욱 확보할 수 있어 서버용으로는 거의 필수라고 봅니다.

    3. 네트워크: 병목 없는 고속도로

    아무리 NAS 내부 성능이 좋아도 네트워크 속도가 느리면 그걸 제대로 활용할 수 없어요. 특히 10기가비트 이더넷 (10GbE)은 대용량 파일 전송이나 여러 클라이언트가 동시에 고대역폭을 요구할 때 빛을 발합니다. 저도 처음엔 기가비트(1GbE)로 만족했지만, VM 백업이나 4K 영상 편집 작업을 하면서 10GbE NIC (Network Interface Card)의 필요성을 절실히 느꼈습니다. 10GbE 환경을 구축하려면 NAS뿐만 아니라 스위치(Switch)와 클라이언트 PC도 10GbE를 지원해야 한다는 점, 꼭 기억하세요!

    4. 스토리지: ZFS 성능의 핵심

    ZFS 성능의 가장 큰 변수는 역시 스토리지 구성입니다.

    4.1. 메인 풀 (Main Pool)

    • HDD (Hard Disk Drive): 대용량 저장에 유리하지만, 무작위 읽기/쓰기(Random Read/Write) 성능은 떨어집니다. 주로 RAIDZ1/2/3나 미러링(Mirroring)으로 구성합니다.
    • SSD (Solid State Drive): HDD보다 훨씬 빠른 읽기/쓰기 속도와 낮은 지연 시간(Latency)을 제공합니다. 가상 머신 스토리지나 고성능이 필요한 데이터 저장에 적합합니다.

    제 경험상, 홈랩에서는 메인 풀을 HDD로 구성하더라도, 중요한 서비스나 가상 머신 이미지는 별도의 SSD 풀에 두는 것이 성능 체감에 정말 효과적이었습니다.

    4.2. SLOG/ZIL 전용 장치

    동기 쓰기 성능을 높이는 가장 확실한 방법은 NVMe SSD를 SLOG 전용 장치로 사용하는 것입니다. SLOG는 쓰기 캐시 역할을 하므로, 매우 낮은 지연 시간과 높은 내구성(Endurance)을 가진 SSD가 필요합니다. 일반적으로 DRAM이 내장된 엔터프라이즈급 NVMe SSD가 권장되지만, 홈랩에서는 고성능 컨슈머 NVMe SSD도 충분히 효과를 볼 수 있습니다. 제가 직접 벤치마크해보니, SLOG 유무에 따라 동기 쓰기 성능이 수십 배 이상 차이 나는 걸 확인했습니다. ⚠️ 다만 주의할 점은, SLOG 장치는 갑작스러운 전원 손실에도 데이터가 안 날아가도록 전력 손실 보호(Power Loss Protection, PLP) 기능이 있는 제품을 선택해야 한다는 것입니다.

    4.3. L2ARC 전용 장치

    L2ARC는 읽기 캐시이므로, 꼭 최고 성능의 NVMe SSD를 사용할 필요는 없습니다. SATA SSD나 여유 있는 NVMe SSD를 활용해도 충분히 효과를 볼 수 있어요. 다만, L2ARC는 콜드 캐시(Cold Cache) 상태에서 효과가 미미하고, 시스템 RAM(ARC)을 먼저 채우기 때문에, RAM이 충분한 상태에서 L2ARC를 추가하는 것이 좋습니다. 제가 사용해 본 결과, L2ARC는 큰 데이터셋을 반복적으로 읽을 때 정말 유용하더라고요.

    실전 벤치마크와 최적화 과정

    이제 실제 성능을 측정하고 최적화하는 과정을 살펴볼게요. TrueNAS SCALE에서는 다양한 벤치마크 툴을 활용할 수 있습니다.

    1. 벤치마크 툴 준비

    TrueNAS SCALE은 Debian 기반이라 익숙한 리눅스 툴들을 사용할 수 있습니다.

    • fio (Flexible I/O Tester): 디스크 I/O 성능을 측정하는 데 가장 널리 사용되는 툴입니다. 순차 읽기/쓰기, 랜덤 읽기/쓰기, IOPS, 대역폭 등 다양한 시나리오를 테스트할 수 있죠.
    • iperf3: 네트워크 대역폭을 측정하는 툴입니다. 클라이언트와 서버 간의 실제 네트워크 속도를 확인할 때 유용해요.
    • arcstat: ZFS ARC 캐시의 상태를 실시간으로 모니터링합니다. 캐시 히트율, 메모리 사용량 등을 확인할 수 있습니다.

    TrueNAS SCALE 쉘(Shell)에서 fio를 설치하려면 다음 명령어를 사용합니다.

    
    sudo apt update
    sudo apt install fio
    

    2. ZFS 풀 구성 및 SLOG/L2ARC 추가

    ZFS 풀을 생성할 때, VDEV 구성은 매우 중요합니다. 미러(Mirror) 구성은 IOPS 성능이 좋고 복구 시간이 짧지만 용량 효율이 낮고, RAIDZ는 용량 효율이 좋지만 IOPS 성능이 미러보다 떨어지고 복구 시간이 길 수 있거든요. 저는 홈랩에서 가상 머신을 많이 돌리기 때문에 IOPS를 우선시해서 미러 구성을 선호하는 편입니다.

    SLOG와 L2ARC는 TrueNAS SCALE 웹 UI에서 간단하게 추가할 수 있습니다. ‘Storage’ > ‘Pools’ > ‘ADD’ 버튼 옆의 ‘…’ 메뉴 > ‘Add Vdevs’를 통해 캐시(Cache)나 로그(Log) VDEV를 추가할 수 있습니다.

    TrueNAS SCALE 웹 UI에서 ZFS 풀에 SLOG (Log Vdev)를 NVMe SSD로 추가하는 설정 화면

    TrueNAS SCALE 웹 UI에서 ZFS 풀에 SLOG (Log Vdev)를 추가하는 화면입니다.

    3. fio를 이용한 디스크 벤치마크 (Disk Benchmark with fio)

    fio 명령어를 이용해 다양한 시나리오로 ZFS 풀의 성능을 측정합니다. 예를 들어, 4KB 랜덤 쓰기 IOPS를 측정하는 명령어는 다음과 같습니다.

    
    fio --name=random-write --ioengine=posixaio --rw=randwrite --bs=4k --numjobs=4 --size=1G --time_for_run=60 --group_reporting --direct=1 --filename=/mnt/YourPoolName/fio_test_file
    
    • --name=random-write: 테스트 이름
    • --ioengine=posixaio: I/O 엔진
    • --rw=randwrite: 랜덤 쓰기 (randread는 랜덤 읽기, write는 순차 쓰기, read는 순차 읽기)
    • --bs=4k: 블록 사이즈 (Block Size)
    • --numjobs=4: 동시에 실행할 작업 수
    • --size=1G: 각 작업이 생성할 파일 크기
    • --time_for_run=60: 60초 동안 테스트 실행
    • --group_reporting: 모든 작업의 결과를 합쳐서 보여줌
    • --direct=1: O_DIRECT 플래그를 사용하여 OS 캐시를 우회
    • --filename=/mnt/YourPoolName/fio_test_file: 테스트 파일 경로

    SLOG를 추가하기 전후, L2ARC를 추가하기 전후로 이 테스트를 반복하면서 성능 변화를 기록해보세요. 순차 쓰기/읽기와 랜덤 쓰기/읽기를 모두 테스트하는 것이 정말 중요합니다.

    4. iperf3를 이용한 네트워크 벤치마크 (Network Benchmark with iperf3)

    NAS와 클라이언트 PC 양쪽에서 iperf3를 실행하여 실제 네트워크 대역폭을 측정합니다.

    NAS (서버 모드):

    
    iperf3 -s
    

    클라이언트 PC (클라이언트 모드):

    
    iperf3 -c [NAS의 IP 주소] -P 8
    
    • -s: 서버 모드
    • -c [IP 주소]: 클라이언트 모드로 지정된 IP에 연결
    • -P 8: 8개의 병렬 스트림(Parallel Stream)으로 테스트 (더 정확한 최대 대역폭 측정)

    이 테스트를 통해 1GbE, 2.5GbE, 10GbE 등 실제 네트워크 속도가 얼마나 나오는지 확인할 수 있습니다. 저도 이 테스트를 통해 ‘아, 디스크가 문제가 아니라 네트워크가 병목이었구나!’ 하고 깨달았던 적이 많습니다.

    fio 디스크 벤치마크 및 iperf3 네트워크 벤치마크 결과 대시보드

    ZFS 풀의 fio 벤치마크 결과와 iperf3 네트워크 벤치마크 결과를 보여주는 통합 대시보드 예시입니다.

    ⚠️ 실제 겪었던 삽질과 트러블슈팅

    제가 벤치마크와 최적화 과정을 거치면서 겪었던 몇 가지 문제점과 해결책들입니다. 아마 여러분도 비슷한 상황을 만날 수 있을 거예요.

    1. ‘SLOG를 추가했는데 왜 쓰기 성능이 그대로죠?’: 동기 쓰기(Synchronous Write)를 하는 애플리케이션(예: 데이터베이스, 가상 머신)이 아니면 SLOG 효과를 보기 어렵습니다. 비동기 쓰기(Asynchronous Write) 위주라면 SLOG보다 메인 풀 디스크 자체의 성능이 더 중요하거든요. 또한, SLOG 용량은 보통 RAM의 몇 배 정도로 충분하며, 너무 큰 SLOG는 오히려 낭비일 수 있습니다.
    2. ‘L2ARC를 추가했는데 RAM 사용량이 줄지 않아요!’: L2ARC는 ARC가 ‘꽉 찬’ 후에 활성화되기 시작합니다. 그리고 L2ARC 자체도 RAM을 인덱싱(Indexing)하는 데 사용하므로, L2ARC를 추가한다고 해서 RAM 사용량이 드라마틱하게 줄어들지는 않아요. 오히려 L2ARC 인덱스 때문에 RAM 사용량이 소폭 늘 수도 있습니다. L2ARC의 실제 효과를 보려면 충분한 RAM이 먼저 갖춰져야 합니다.
    3. ’10GbE를 달았는데 왜 속도가 안 나오죠?’: 네트워크 케이블, 스위치, 클라이언트 PC의 NIC가 모두 10GbE를 지원하는지 확인하세요. 특히 저가형 케이블이나 오래된 스위치는 실제 대역폭을 저하시킬 수 있어요. 그리고 CPU 사용량이 100%에 근접하는지 확인해보세요. NAS의 CPU가 병목일 수도 있으니까요.
    4. ‘ZFS 압축(Compression)을 켰더니 오히려 느려졌어요!’: 압축률이 낮은 데이터를 압축하거나, CPU 성능이 충분하지 않은 상태에서 고압축률 알고리즘을 사용하면 압축/해제 오버헤드 때문에 성능이 저하될 수 있습니다. lz4처럼 가벼운 압축 알고리즘은 성능 저하가 적으면서도 효과가 좋은 편이니, 테스트해보고 적용하는 것을 추천합니다.

    성능 벤치마크 결과 요약 및 최적화 팁

    다양한 테스트를 통해 제가 내린 결론은 다음과 같습니다.

    하드웨어 요소 ZFS 성능 기여 최적화 팁
    CPU 전반적인 시스템 응답성, ZFS 연산 처리 코어 수와 클럭이 높은 CPU 사용 (가상화, 다중 사용자 환경 시 중요)
    RAM 읽기 캐시(ARC) 성능, 시스템 안정성 최소 16GB, 가능하면 32GB 이상. ECC RAM 권장
    네트워크 클라이언트-NAS 간 데이터 전송 속도 10GbE NIC 및 인프라 구축. iperf3로 병목 확인
    SLOG (NVMe SSD) 동기 쓰기(Synchronous Write) 성능 필수: PLP 기능 있는 고성능 NVMe SSD 사용 (VM, DB 등)
    L2ARC (SSD) 반복적인 읽기(Read) 성능 RAM이 충분할 때 추가. SATA/NVMe SSD 활용 가능
    메인 풀 (HDD/SSD) 기본 저장 용량 및 성능 사용 목적에 따라 RAIDZ 또는 미러 구성. 고성능 요구 시 SSD 풀 별도 구성
    TrueNAS SCALE ZFS 성능 최적화 전략 요약 인포그래픽: CPU, RAM, 네트워크, 스토리지

    TrueNAS SCALE ZFS 성능 최적화를 위한 하드웨어별 전략을 한눈에 볼 수 있는 요약 인포그래픽입니다.

    마무리하며: 나만의 최적화를 찾아서

    TrueNAS SCALE ZFS 성능 최적화는 단순히 비싼 하드웨어를 때려 박는다고 끝나는 문제가 아닙니다. 자신의 사용 패턴과 예산에 맞춰 가장 큰 병목 구간을 찾아 해결하는 것이 정말 중요해요. 저도 처음엔 뭐가 문제인지 몰라 무작정 SSD를 사기도 하고, RAM을 증설하기도 했었죠. 하지만 벤치마크 툴을 사용해서 정확히 어떤 부분이 부족한지 확인하고, 그에 맞는 하드웨어나 설정을 변경하는 과정을 통해 훨씬 만족스러운 결과를 얻을 수 있었습니다.

    이 글에서 소개한 내용들이 여러분의 TrueNAS SCALE 환경을 더 빠르고 효율적으로 만드는 데 도움이 되었으면 좋겠네요. 삽질은 인프라 엔지니어의 숙명이지만, 그 삽질이 누군가에게는 귀한 경험이 될 수 있다는 걸 알기에 오늘도 이렇게 키보드를 두드립니다. 다음번에는 TrueNAS SCALE에서 컨테이너와 가상 머신을 더 효율적으로 운영하는 방법에 대해 다뤄볼까 합니다. 기대해주세요!