Mドライブ: S3上にPOSIXファイルシステムを搭載する
オブジェクトストレージの拡張性とPOSIXの利便性を組み合わせたMドライブの設計哲学と技術的決定
問題意識
テーブルベースのファイル管理システムは優れた安定性を提供しますが、フォルダ構造の表現が複雑で、権限管理が難しく、柔軟な操作が困難です。
MドライブはLinuxのInode構造を再解釈してファイルシステムを構成し、POSIXファイルシステムインターフェースを実装してLinuxユーザーに親しみやすく、一般ユーザーにも柔軟な操作が可能となるように設計しました。
設計の核 1: Index Nodeシステム
システム設計時の最大の質問は「どのように柔軟で効率的なファイルシステムを提供するか」でした。
テーブルが複雑になりリレーションが多くなるほど、クエリ効率が低下したり管理が複雑になったり、システムの核となるロジックで多くの変更点が出ると構造が崩れる可能性があると判断しました。
そのような中、Linuxのinode構造を見てインスピレーションを得ることができました。Inode はLinuxおよびUNIX系ファイルシステムでファイルのコア情報を持つデータ構造です。フォルダやシンボリックリンクなどもファイルとして表現され、データ保存の一貫性を持ちます。
これをサービスに導入すれば、一貫したデータ保存を行いながら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などユーザーに親しみのあるコマンドや機能でファイルを操作でき、多様な機能を提供しているため、ドライブシステムで適合して使用できました。