Skip to main content
Mandacode mandacode
M드라이브: S3 위에 POSIX 파일시스템을 얹다
·
Go S3

M드라이브: S3 위에 POSIX 파일시스템을 얹다

오브젝트 스토리지의 확장성과 POSIX의 편의성을 결합한 M드라이브의 설계 철학과 기술적 결정들

문제의식

테이블 기반의 파일 관리 시스템은 뛰어난 안정성을 제공하지만, 폴더 구조 표현이 복잡하고 권한 관리가 어려우며, 유연한 동작이 어렵습니다.

M드라이브는 리눅스의 Inode 구조를 재해석하여 파일시스템을 구성하였고, POSIX 파일시스템 인터페이스를 구현하여 리눅스 유저에게 친화적이고, 일반사용자 또한 유연한 동작이 가능하도록 설계하였습니다.

핵심 설계 1: Index Node 시스템

시스템 설계시 가장 큰 질문은 “어떻게 유연하고 효율적인 파일시스템을 제공할 것인가”였습니다.

테이블이 복잡해지고 릴레이션이 많아질 수록 쿼리 효율이 하락하거나 관리가 복잡해질 수 있고, 시스템의 핵심 로직에서 변경점이 많아 구조가 깨질 수 있다고 판단하였습니다.

그러던 중 리눅스의 inode 구조를 보고 영감을 얻을 수 있었습니다. Inode 는 리눅스 및 유닉스 계통 파일 시스템에서 파일의 핵심 정보를 담고 있는 데이터 구조입니다. 폴더나 심볼릭 링크 등도 파일로 표현되어 데이터 저장의 일관성을 가집니다.

이를 서비스에 도입한다면 일관적인 데이터 저장을 하면서 Join 연산 없이 한번에 데이터를 가져올 수 있다는 장점이 있었습니다. 이는 곧 성능 향상으로 이루어지고 불변하는 코어 로직을 만들어 안정성을 향상시킬 수 있었습니다.

필드명

타입

설명

제약 / 속성

id

uuid.UUID

기본 식별자 (UUID)

Unique, Immutable

type

enum

노드 타입

기본값: file

size

int64

크기 (object의 경우 외부 저장 데이터 크기)

기본값: 0

nlink

uint32

하드 링크 개수

기본값: 1

content

[]byte

인라인 콘텐츠

최대 4KiB

atime

time.Time

노드 접근 시간

mtime

time.Time

노드 수정 시간

ctime

time.Time

노드 변경 시간

crtime

time.Time

노드 생성 시간

flags

uint32

플래그 비트마스크

기본값: 0

revision

string

세대 식별자 (ULID)

최대 26자

node 시스템을 전부 따라하기보단 위와 같이 M드라이브 시스템에 알맞게 테이블을 설계하였습니다.

권한 및 블록 데이터 저장 등 외부 시스템의 역할이거나 현재의 시스템에 과하다고 생각된 부분들은 없애고 노드를 단순화하여 테이블을 작성하였습니다.

i_block[EXT4_N_BLOCKS=15] 또한 외부 스토리지에 데이터가 저장된 다는점을 감안하여 []byte 형태로 content 필드에 타입별로 정의된 json 데이터를 직렬화하여 저장합니다.

핵심 설계 2: POSIX 기반 파일 관리

M드라이브의 주요 특징 중 하나는 유연하고 정밀한 드라이브 조작 기능입니다. 웹부터 추후 추가될 CLI 툴까지 다양한 환경에서 유연하게 파일을 조작하여 일반적인 스토리지 서비스와 다르게 유저에게 다양한 인터페이스를 제공합니다. 또한 Inode 시스템과 결합하여 운영체제의 파일 시스템과 동작하는 것이 유저 친화적 구조라고 생각하였습니다.

따라서 POSIX 파일 인터페이스를 M드라이브 시스템에 도입하였습니다. rm, ln, cp 등 유저에게 친숙한 명령어 및 기능으로 파일을 조작할 수 있고, 다양한 기능들을 제공하기 때문에 드라이브 시스템에서 적합하게 사용할 수 있었습니다.