아요 개발 일기

APFS(Apple File System) 본문

iOS

APFS(Apple File System)

김망복 2024. 11. 13. 21:33
반응형

안녕하세요!

File System 부분 공부하면서 필수로 알아야하는 APFS에 대해서 알아보겠습니다!!

설명이 좀 길어져서 따로 뺐어요 ㅎㅎ

 

이 글은 Documentation - About Apple File System 을 기반으로 적었습니다!


HFS+와 APFS

APFS에 대해서 알아보기 전에 HFS+에 대해서 간단하게 알아볼까요?

HFS+는 APFS 이전에 기본 파일시스템인데, APFS 기능 소개할 때 비교군?으로 계속 언급이 될거에요!

 

HFS+(Hierarchical File System Plus)이란?

  • 도입 시기: 1998년, Mac OS 8.1과 함께 소개됨
  • 특징
    • HFS의 한계를 극복하기 위해 개발된 버전
    • 큰 파일대용량 디스크를 지원하여 현대적인 스토리지 요구 사항을 충족
    • 유니코드 파일 이름을 지원하여 다양한 언어와 문자를 사용할 수 있음
    • 저널링 기능 도입으로 시스템 오류나 예기치 않은 종료 시 데이터 무결성을 보소
    • 디스크 공간의 효율적인 사용과 성능 향상을 제공
💡 저널링(Journaling)이 뭐야?
파일 시스템에서 데이터의 무결성일관성을 유지하기 위한 기술
시스템 오류, 전원 장애 또는 예기치 않은 종료와 같은 문제가 발생했을 때, 파일 시스템의 손상을 방지하고 빠르게 복구할 수 있도록 도와줌

작동 원리
1. 변경 사항을 저널에 기록: 파일이나 디렉터리에 변경이 발생하면, 실제 데이터에 적용하기 전에 그 변경 사항을 “저널(journal)”이라는 특별한 로그 영역에 먼저 기록
2. 실제 데이터 업데이트: 변경 사항이 저널에 안전하게 기록되면, 그 후에야 실제 파일 시스템에 변경을 적용
3. 저널 기록 삭제 또는 업데이트: 변경 사항이 성공적으로 적용되면, 해당 저널 로그를 제거하거나 완료로 표시

APFS에도 저널링 기술이 적용되어있어요! 어려우시면 그냥 이런게 있다~ 정도만 알아도 될 것 같아요!!

이제 드디어 APFS에대해 알아봅시다ㅎㅎ

 

APFS(Apple File System)란?

  • 도입 시기: 2017년, macOS High Sierra(10.13)와 iOS 10.3부터 기본 파일 시스템으로 사용되었음
  • 특징
    • SSD와 플래시 스토리지에 최적화되어 빠른 속도와 효율성을 제공
    • 스냅샷 기능을 통해 특정 시점의 파일 시스템 상태를 저장하고 복원할 수 있음
    • 클론 기능으로 추가 저장 공간 사용 없이 파일이나 디렉터리의 복사본을 생성할 수 있음
    • 향상된 암호화 옵션으로 파일 및 메타데이터의 보안을 강화
    • 파일 및 디렉터리의 크기를 빠르게 계산하는 기능 제공

오호.. 일단 기능이 참 많은 것 같죠??

복제/복사(clone), 스냅샷, 공간 공유, 빠른 디렉토리 크기 계산, 안전한 저장(safe-save), 희소 파일(sparse files) 등등..

어떤 기능들이 있는지 한 번 자세히 알아봅시다!


APFS 기능

Clones을 통한 복사비용 절감

clone은 추가적인 디스크 공간을 차지하지 않는 파일 또는 디렉토리의 복사본입니다.

동일한 볼륨 내에서 빠르고 에너지 효율적인 파일 복사가 가능합니다

FileManager의 CopyItem(at:to:)copyItem(atPath:toPath:)메서드를 사용하면 APFS 볼륨에서 클론을 자동으로 생성합니다

 

🤔 파일을 복사하면 자동으로 클론기능이 추가되는거에요??

→ 아니요! CopyIten(at:to:)copyItem(atPath:toPath:)을 사용해야만 클론(복제본)이 생깁니다!

다른 방식으로 파일을 복사했을 때는 APFS의 기능이 적용되지 않을 수 있으니 주의하세요!!!

 

🤔  복사하는데 어떻게 디스트 공간을 차지 안 할 수 있는 거죠....?

→ 그건 원본 데이터의 위치를 공유하는 방식으로 복사본을 생성하기때문이에요! 아래에서 자세하게 설명해드리겠습니당

 

출처 - https://developer.apple.com/documentation/foundation/file_system/about_apple_file_system

 

위에 그림을 보면 이전에 사용하던 HFS+는 두 파일의 내용물이 동일하지만 공간을 각각 3개 블록씩 총 6개 블록을 차지하고 있는 것을 볼 수 있습니다!

반면에 APFS는 My file를 My file copy가 복사한 후, 수정했을때 (My File copy가 수정된 상태)

원본(My file)과 공통된 부분은 서로 공유하고 수정된 부분은 따로 블록을 생성해서 관리하고있습니다.

HFS+ 방식보다 블럭을 2개나 덜 사용하고 있으니 APFS가 디스크 공간을 효율적으로 사용하고있죠?!


여러 볼륨 간에 자유 공간을 공유

그림을 보면서 HFS+와 APFS의 특징에대해 알아봅시다!

출처 - https://developer.apple.com/documentation/foundation/file_system/about_apple_file_system

 

HFS+

- 파티션당 하나의 볼륨만 지원 함

- 각 볼륨은 파티션할 때 설정된 크기로 고정되며, 각 볼륨은 자신의 자유 공간 내에서만 확장할 수 있음

 

APFS(Apple File System)

- 하나의 파티션 내에서 여러 볼륨을 지원하여 모든 볼륨이 자유 공간을 공유할 수 있음

- 파티션 내의 모든 볼륨은 독립적으로 확장 및 축소가 가능하며, 하나의 볼륨이 축소되면서 확보된 공간을 다른 볼륨이 확장하는 데 사용할 수 있음

- 저장 공간을 보다 유연하게 사용할 수 있도록 하며, 공간 낭비를 줄이고 저장 효율을 높여줌

 

두가지를 쉽게 설명해보면 HFS+는 한 집에 방 하나 있는거고 APFS는 한 집에 여러 개의방(볼륨)이 있고, 각 방이 필요한 만큼 집 전체의 공간을 나누어 쓸 수 있는 거죠!

 

⚠️ 주의 ⚠️

FileManager의 attributesOfFileSystem(forPath:) 메서드를 사용하면 자유 공간을 모두 포함해서 반환합니다.

이를 사용하여 파티션 내의 전체 자유 공간을 계산하지 않도록 주의해야합니다!

if let attributes = try? FileManager.default.attributesOfFileSystem(forPath: "/") {
    let availableFreeSpace = attributes[.systemFreeSize] 
}

 

🤔 자유 공간을 모두 포함해서 반환하면 전체 자유 공간 아니야? 뭘 주의하라는 거죠???

제가 쉽게 예시를 들어보겠습니다!!

만약 하나의 파티션에 볼륨 A, 볼륨 B가 존재하고 남은 자유 공간이 100GB라고 가정해보겠습니다!

저는 볼륨의 자유 공간이 몇인지 알아내기 위해 attributesOfFileSystem(forPath:) 메서드를 호출하겠죠?

그때, 각각의 볼륨에서는 아래와 같이 알려줍니다.

 

볼륨 A: "100GB의 자유 공간이 있어!"

볼륨 B:  "100GB의 자유 공간이 있어!"

 

그럼 그냥 100GB로 값이 반환 될 것 같죠?? 

아닙니다!!! 볼륨 A에서 말 한 100GB + 볼륨 B에서 말 한 100GB = 총 200GB 로 값이 반환됩니다.

즉, 실제 보다 큰 자유 공간 값을 반환하는거죠!

 

 

🤔 그러면 제가 필요한 볼륨 공간이 있는지 어떻게 알아봐요?

아래 코드처럼 특정 작업을 수행하기에 필요한 공간 값이 해당 볼륨에 있는지 확인하는 방법을 사용하면 됩니다!

let requiredSpace: Int64 = 100 * 1024 * 1024 // 100MB

if let attributes = try? FileManager.default.attributesOfFileSystem(forPath: "/") {
    if let availableSpace = attributes[.systemFreeSize] as? Int64 {
        if availableSpace >= requiredSpace {
            print("충분한 공간이 있습니다.")
        } else {
            print("충분한 공간이 없습니다.")
        }
    }
}


Sparse Files(희소 파일)

파일의 빈 부분(데이터가 없는 공간)에 실제 디스크 공간을 할당하지 않는 파일 형식을 말합니다.

데이터가 있는 부분에만 디스크 공간을 할당하기때문에 디스크 공간을 더 효율적으로 사용할 수 있겠죠?

 

사용하는 법은 아주 간단합니다.

FileHandle 클래스를 사용해 새로운 쓰기(write(_:)) 핸들을 생성하면 자동으로 희소 파일이 만들어집니다

1번에 데이터 블록을 기록한 후 seek(toOffset:)메서드를 호출해 한 블록을 건너뛰고 3번 블록을 기록하면 아래와같이 중간을 건너뛴 데이터를 만들 수 있습니다.

💡 FileHandle
파일을 읽고 쓸 때 사용하는 고수준 API로, 파일 시스템의 복잡한 세부사항을 신경 쓰지 않고도 파일 입출력을 편리하게 수행할 수 있도록 해주는 클래스입니다

출처 - https://developer.apple.com/documentation/foundation/file_system/about_apple_file_system

 

위 사진을 보면 HFS+는 중간에 빈 블록이 생기지만,

APFS(Apple File System)의 희소 파일에서는 앞과 뒤에 데이터가 있고 중간이 비어 있는 경우에 앞 부분과 뒷 부분만 저장하고 빈 부분은 실제 디스크에 저장하지 않습니다.

 

출처 - https://developer.apple.com/documentation/foundation/file_system/about_apple_file_system

 

🤔 빈 블록을 저장하지 않으면 나중에 중간 부분에 데이터를 추가할 때 블록들이 원래 순서와 어긋날 수 있지 않나요??

: 맞습니다! 하지만 FileHandle API가 이 순서 어긋남(단편화)을 자동으로 처리해 주기 때문에, 개발자가 이를 직접 신경 쓸 필요가 없습니다. 또, 이로 인한 성능 저하도 대부분의 경우에 크게 문제되지 않습니다.

 

⚠️주의⚠️

FileHandle은 새로운 파일을 생성하거나 데이터를 추가할 때는 희소 파일 기능을 지원하지만,

이미 디스크에 저장된 파일이 공백 데이터를 포함하고 있는 경우에는 기존의 공백 블록을 제거해 희소 파일로 변환하지 않습니다!


 

반응형