オンプレミスで ReFS+記憶域スペースを使って SSD ミラーと HDD パリティの階層ストレージを組んだのに、膨大な小さなファイルが原因で「ファイルの列挙や削除がとにかく遅い……」という悩みはよくあります。そこで出てくるのが「せめてファイルシステムのメタデータだけでも SSD に置けないか?」という発想です。本記事では、この疑問に対する現実的な答えと、オンプレ環境で実際に取れる改善策を、PowerShell の具体例まで含めて詳しく解説します。
想定している構成と課題の整理
まずは前提条件をはっきりさせておきます。
| 項目 | 内容 |
|---|---|
| ファイルシステム | ReFS(Resilient File System) |
| 記憶域スペース構成 | SSD×2 のミラー=ホット階層(Performance Tier) HDD×3 のパリティ=コールド階層(Capacity Tier) |
| ワークロード | 約 10 億件レベルの小さなファイル(多数の小さいファイル) |
| 問題 | ファイル列挙、削除、属性変更など FS(ファイルシステム)操作が極端に遅い |
| やりたいこと | 「ファイルデータはともかく、メタデータだけでも SSD 階層に常駐させたい」 |
ここでいう「メタデータ」とは、ディレクトリエントリや属性情報(サイズ、タイムスタンプ、セキュリティ情報など)、インデックス構造など、ファイルの中身そのものではない管理情報のことです。小さいファイルが大量にある場合、ディレクトリの列挙や ACL の変更など、メタデータ関連 I/O がボトルネックになりがちです。
結論:現状の標準機能では「メタデータだけ SSD 固定」はできない
いきなり結論から言うと、現時点の Windows Server + ReFS + 記憶域スペースの公開機能だけでは、「ファイルシステムのメタデータだけを SSD 階層に強制配置する」ことはできません。
理由を整理すると次の通りです。
- 記憶域スペースの階層化(Storage Spaces Tiering)は、基本的にファイルデータのアクセス頻度(ヒート/温度マップ)にもとづいてブロックを SSD/HDD 間で移動させる仕組みです。
- ReFS のメタデータを、ユーザーが任意に「この階層に置け」と指示するためのスイッチや API は公開されていません。
- Microsoft Q&A でも、「ReFS+記憶域スペースではメタデータのみを SSD ティアに移動させる手段はない」旨の回答が公式に示されています。
つまり、どれだけ SSD 側を高速にしても、メタデータ関連 I/O が HDD(パリティ階層)に当たる可能性が残るため、「10 億件規模の極端に小さいファイル」というワークロードでは体感速度を劇的に改善するのは難しい、というのが現実です。
例外的な実装としての「SMR+ReFS」
なお、ReFS の内部実装としては、SMR(Shingled Magnetic Recording)ドライブ向けの設計資料に「すべてのメタデータを SSD(フラッシュ)ティアに置き、SMR 側にはデータのみを置く」という構成が紹介されているスライドも存在します。
しかしこれはあくまで SMR 対応の特殊な構成における内部挙動の説明であり、一般的な「SSD ミラー+HDD パリティ」の記憶域スペースで ユーザーが選択・制御できる機能として提供されているわけではありません。
したがって、オンプレ Windows Server で ReFS+記憶域スペースを使う場合、「メタデータだけ SSD に固定」は現実的には不可能と考えて運用設計を行う必要があります。
ReFS と記憶域スペースの階層化の仕組みをざっくり理解する
対策を考えるうえで、ReFS と記憶域スペースの役割分担を軽くおさらいしておきましょう。
ReFS の役割
- NTFS の後継として設計された Microsoft の次世代ファイルシステム
- メタデータ(と任意でデータ)にチェックサムを持ち、整合性チェックと自己修復をサポート
- ブロッククローン、スパース VDL など、仮想化向けの最適化機能
- 記憶域スペースと連携し、ミラーやパリティ構成での自動修復や「mirror-accelerated parity」などの階層化機能を利用
公式ドキュメントでも、ReFS が記憶域スペースと組み合わさることでミラー/パリティ/階層化構成を実現し、大規模データセット向けのスケーラビリティや信頼性を提供することが示されています。
記憶域スペースの階層化の役割
記憶域スペース側は、プール内の物理ディスクをもとに、次のような「ティア」を作ります。
| ティア | 想定デバイス | 典型的な構成例 | 役割 |
|---|---|---|---|
| パフォーマンスティア(ホット階層) | SSD / NVMe | ミラー(2 方向または 3 方向) | 頻繁にアクセスされるデータを置き、低レイテンシと高 IOPS を提供 |
| キャパシティティア(コールド階層) | HDD(SAS / SATA) | パリティまたはミラー | あまりアクセスされないデータを大容量・低コストで保持 |
階層化の肝は、「どのブロックをどのティアに置くか」をヒートマップで自動的に決める点です。定期的な最適化処理により、よくアクセスされるブロックは SSD ティアに、ほとんどアクセスされないブロックは HDD ティアに移動されます。
重要なのは、このヒートマップの対象があくまで「データブロック」であり、ファイルシステムのメタデータだけを狙い撃ちする仕組みはない、ということです。
なぜ小さいファイルが多いと「メタデータ地獄」になるのか
小さいファイルが大量にあると「体感が遅い」理由を、メタデータの観点から整理してみます。
| 操作内容 | 主に関与する I/O | 小さいファイルが多い場合の特徴 |
|---|---|---|
| ディレクトリの列挙 | ディレクトリエントリの読み込み(メタデータ中心) | ファイル数に比例してメタデータ読み込みが増え、HDD 階層にあると極端に遅くなる |
| ファイルの削除 | 参照カウンタ更新、インデックス更新などのメタデータ更新 | 1 ファイルごとに複数のメタデータ更新が発生し、パリティ HDD 側に当たるとレイテンシが跳ね上がる |
| 属性変更(ACL、タイムスタンプなど) | メタデータ更新が中心 | ファイルサイズに関係なく、ファイル数に比例して I/O 回数が増える |
| 実データの読み書き | データブロックへの I/O | 小さいファイルが多いとランダム I/O が増え、シークの遅い HDD では不利 |
ReFS は内部的に B+ ツリーでメタデータを管理しており、大量のエントリを扱うこと自体は得意ですが、最終的には物理ディスクへのランダム I/O が増えることに変わりはありません。HDD パリティティアにメタデータが偏ってしまうと、SSD に大きなファイルを置いていても「フォルダを開く」「一覧を取得する」といった操作は遅く感じてしまいます。
オンプレで実際に取れる具体策
残念ながら「メタデータだけを SSD に固定する」ことはできませんが、逆に言えば、メタデータとデータをまとめて速いところへ寄せる、あるいは メタデータの負荷そのものを減らす方向でチューニングする余地があります。
ここからは、オンプレ環境で現実的に取り得る対策を整理します。
対策 1:SSD ミラーの容量を増やす/全 SSD 化を検討する
最もシンプルで効果が大きいのが、「そもそも SSD 側の比率を増やす」ことです。ラフな比較を表にまとめると次のようになります。
| 構成案 | 概要 | メリット | デメリット |
|---|---|---|---|
| 現状構成 SSD×2 ミラー + HDD×3 パリティ | 小容量の SSD ティアに「ホットデータ」を載せ、コールドデータは HDD パリティに逃がす構成 | コスト効率が良く、容量単価が安い | メタデータが HDD に残る可能性が高く、小さいファイル大量環境では FS 操作が遅い |
| SSD 側容量を拡大 SSD×4 ミラー or SSD×3 ミラーなど | SSD ティアの容量を 2 倍以上に増やし、ホットセット全体を載せることを目指す | メタデータを含む多くの I/O が SSD で処理される確率が上がる | SSD のコスト増、消費電力・スロット数の制約 |
| 全 SSD 化 HDD を廃止し SSD のみ | プール全体を SSD で構成し、ミラーまたはパリティで冗長化 | メタデータもデータもすべて SSD I/O になるため、FS 操作のレイテンシが大幅に改善 | 容量単価が最も高い、TB クラスになると初期投資が大きい |
特に「10 億件規模の小さいファイル」という極端なケースでは、最終的には全 SSD 化を検討した方がトータルコスト(運用時間・サポート工数を含めて)で安上がり、という判断になることも珍しくありません。
対策 2:ホットなファイル/ディレクトリを SSD 階層へピン留めする
記憶域スペースには、特定のファイルを明示的にティアへ割り当てる Set-FileStorageTier という PowerShell コマンドレットが用意されています。
内部的には「このファイルのデータブロックは SSD ティア側に置いておく」という「ピン留め(Pinning)」の指定です。
重要な注意点:これはあくまで“ファイルデータ” の配置に効く仕組みであり、メタデータそのものが必ず SSD に置かれることを保証するものではありません。それでも、ホットデータを SSD にまとめることで、結果的にメタデータ I/O に対するキャッシュヒット率が上がるケースは多く、実効性能の改善につながることがあります。
よくアクセスされるディレクトリ配下を SSD ティアへピン留めする例
# SSD ティアの取得(FriendlyName は環境に合わせて変更)
$ssdTier = Get-StorageTier -FriendlyName "Pool1_SSDTier"
# 対象ディレクトリ配下のファイルを列挙して SSD ティアへピン留め
Get-ChildItem "E:\HotData" -Recurse -File |
ForEach-Object {
Set-FileStorageTier -FilePath $_.FullName -DesiredStorageTier $ssdTier
}
# ピン留めされたファイルの状況確認
Get-FileStorageTier -VolumePath "E:\"
ピン留めを行ったファイルは、次回の階層最適化処理(自動または手動)で SSD ティアへ移動します。急いで反映したい場合は、以下のように手動で最適化を走らせます。
# ボリューム単位で階層最適化を実行
Optimize-Volume E: -TierOptimize
ただし、ベンダーのベストプラクティスでも「ピン留めは本当に重要なファイルに限定し、多用しすぎないこと」が推奨されています。
対策 3:パリティ側の「書き戻しキャッシュ(Write‑back Cache)」を拡大
パリティ構成は、書き込み時にパリティ計算が入るため、そもそもランダム書き込みに弱いという宿命があります。これを緩和するために活用したいのが、仮想ディスク側で設定できる「書き戻しキャッシュ(Write-back Cache, WBC)」です。
- WBC は、小さなランダム書き込みを一時的に連結し、後段の HDD に対して大きなシーケンシャル書き込みとして吐き出すバッファの役割を持ちます。
- メタデータ更新も実体としては小さなランダム書き込みが多いため、WBC 容量をある程度確保することでバースト時の待ち時間を抑制できます。
WBC の最適値はワークロードとメモリ構成に依存するため一概には言えませんが、「ほとんど書き込みがないアーカイブ用途」以外では、デフォルト値からの増量を検討する価値があります。
対策 4:ディレクトリ設計を見直す(1 つのフォルダに詰め込みすぎない)
「1 つのディレクトリに数百万〜数千万ファイルを詰め込む」という構成は、どのファイルシステムでも苦手です。ReFS も内部的には大規模ディレクトリをさばけますが、列挙や検索のたびに大量のメタデータを読み込む必要があることには変わりません。
可能であれば、次のようなルールでディレクトリ階層を細かく分割しましょう。
- 1 ディレクトリあたりのファイル数の目安を決める(例:1 万件以下)
- 日付、ハッシュ、ID などを用いて階層を切る
\root\YYYY\MM\DD\のような日付ベース- ファイル名のハッシュ先頭 2 桁を使って
\root\ab\cd\のように分散
イメージとしては次のようなイメージです。
悪い例:
E:\data\files\ (この直下に数千万ファイル)
良い例:
E:\data\files\2025\01\01\
E:\data\files\2025\01\02\
E:\data\files\2025\01\03\
...
ディレクトリ分割はすぐには効きませんが、今後増えていくファイルについては必ず効いてくる基本設計なので、アプリ改修が可能なら早い段階で取り組む価値があります。
対策 5:小さいファイルを「束ねる」(アーカイブ/コンテナ化)
ReFS 自体には、小さいファイルを自動でまとめるための専用コマンドや機能はありません。そこで現実的なアプローチとしては、ユーザー空間側でファイルをまとめてしまい、基盤側から見ると「大きめの連続したファイル」にしてしまう方法が有効です。
代表的な手段を比較してみます。
| 方法 | 概要 | メリット | 注意点 |
|---|---|---|---|
| ZIP/TAR などへのアーカイブ | 複数ファイルを 1 つのアーカイブにまとめる | 簡単に導入でき、ツールも豊富 | ファイルを個別に頻繁に更新する用途には不向き |
| WIM / VHDX などのコンテナファイル | 仮想ディスクイメージとしてマウントし、その中に格納 | NTFS 等で内部を管理でき、柔軟な権限設定も可能 | バックアップや障害時に単一ファイルが大きな単位になる |
| SQLite / RocksDB などの単一ファイル DB | アプリ側からキー・バリューや構造化データとして格納 | 読み書きパターンをアプリ側で最適化しやすい | アプリケーション改修が大きくなる可能性がある |
PowerShell を使った簡単なアーカイブ例
更新頻度が低めの静的コンテンツ(ログのローテーション済みファイルや古いデータなど)は、まずアーカイブ化から着手するのが安全です。
# ディレクトリごとに ZIP にまとめる例
Get-ChildItem "E:\data\logs" -Directory | ForEach-Object {
$src = $_.FullName
$dest = "E:\archive\logs\$($_.Name).zip"
Compress-Archive -Path "$src\*" -DestinationPath $dest
}
VHDX への格納例(ざっくりイメージ)
# 500GB の動的 VHDX を作成
New-VHD -Path "E:\container\data1.vhdx" -SizeBytes 500GB -Dynamic
# マウントしてドライブ文字を割り当て
Mount-VHD "E:\container\data1.vhdx" -PassThru | Initialize-Disk -PartitionStyle GPT
New-Partition -DiskNumber <DiskNumber> -UseMaximumSize -DriveLetter X |
Format-Volume -FileSystem NTFS -NewFileSystemLabel "DataContainer"
# 元データを VHDX 内へ移動
Robocopy "E:\data\smallfiles" "X:\smallfiles" /E /COPYALL /MOVE
このように束ねてしまえば、記憶域スペース側から見ると「少数の大きなファイル」になり、階層化やキャッシュの効きが良くなる場合があります。ただし、コンテナ化すると単一ファイル破損時の影響範囲が広がるため、バックアップやチェックサム検証などの運用設計もセットで考える必要があります。
対策 6:運用上の定期最適化と OS 側のチューニング
最後に、ストレージ構成そのものを変えずにできる、運用・OS レベルのチューニングです。
- 階層最適化(Tier Optimize)の定期実行
Optimize-Volume -TierOptimizeをタスクスケジューラなどで定期実行し、ヒートマップにもとづくデータ再配置を促す。- バックアップや大規模なバッチ処理の後など、アクセスパターンが大きく変わったタイミングで実行すると効果的。
- メモリ(システムファイルキャッシュ)の強化
- ファイルキャッシュに十分なメモリがないと、せっかく SSD 側にデータがあってもキャッシュヒット率が上がりません。
- 物理メモリ増設や、仮想化環境であれば VM へのメモリ割り当て増を検討。
- ウイルス対策ソフトのリアルタイムスキャン除外の見直し
- 10 億件規模の小さいファイルに対してリアルタイムスキャンをかけると、ストレージ I/O とは別に CPU/ディスク負荷が跳ね上がることがあります。
- 安全性要件を満たす範囲で、バックアップディレクトリやキャッシュディレクトリなどを除外対象にすることを検討。
クラウド代替案:Azure Files Premium のメタデータ最適化(参考)
もしクラウド利用が許容されるのであれば、Azure Files Premium SSD に用意されている メタデータキャッシュ機能 も選択肢のひとつです。
- Azure Files Premium のメタデータキャッシュは、メタデータレイテンシを低減し、メタデータ多発ワークロードのスループット向上を狙った機能として公式に説明されています。
- Microsoft Q&A でも、「メタデータ多めのワークロードなら Azure Files Premium SSD+メタデータキャッシュを検討してほしい」という案内が出ています。
とはいえ、次のような点には注意が必要です。
| 観点 | メリット | 注意点 |
|---|---|---|
| 性能 | オンプレ HDD パリティ構成と比べると、メタデータ中心のワークロードでレイテンシが改善しやすい | WAN 越しの SMB はレイテンシに敏感で、ネットワーク品質が悪いと期待した性能が出ない |
| 運用 | Azure ポータル/API から容量・性能を柔軟に調整可能 | オンプレとのハイブリッド運用(VPN/ExpressRoute、権限管理など)の設計が必要 |
| コスト | 容量と IOPS/スループットをスケールさせやすい | 長期的な容量増加を見込むと、オンプレとのコスト比較が必要 |
また、これはあくまでAzure Files 側の機能であり、ローカルの記憶域スペースにそのまま適用できるわけではありません。オンプレ前提であれば、前述した SSD ティアの拡大や小ファイル束ねなどを優先的に検討することになります。
改善の進め方チェックリスト
最後に、「どこから手を付ければよいか分からない」というときのために、段階的なチェックリストをまとめます。
- ボトルネックの計測
- PerfMon や Windows Performance Recorder(WPR)などを使い、ディスクキュー長、平均ディスク秒/読み書き、プロセス別 I/O を計測。
- ディレクトリ列挙に時間がかかっているのか、書き込み時に止まるのかなどを切り分け。
- SSD 容量比率の見直し
- ホットセット(よくアクセスされるデータ+メタデータ)がどれくらいの容量かを推定し、それをカバーできるだけの SSD ティア容量を確保できるか検討。
- WBC(書き戻しキャッシュ)の適正化
- 小さなランダム書き込みやメタデータ更新が多い場合、WBC 容量を増やすことでスパイク時のレイテンシを緩和できるか検証。
- ホットデータのピン留め+階層最適化
Set-FileStorageTierで重要なファイルやディレクトリ配下を SSD ティアへピン留め。Optimize-Volume -TierOptimizeを定期実行し、ヒートマップにもとづく自動再配置とピン留めの反映を促進。
- ディレクトリ分割+小ファイルの束ね
- 新規データについては、1 ディレクトリあたりのファイル数を抑えるディレクトリ設計へ徐々に移行。
- 古い静的データから順に、ZIP や VHDX、DB などを使って束ねる。
- それでも改善が乏しければアーキテクチャを見直す
- 全 SSD 化や NVMe の導入、あるいはそもそもファイルベースではなく DB/オブジェクトストレージなど別のストレージ設計に切り替える。
フォーラムや問い合わせ時に使えるタグの例
同様の相談を Microsoft Q&A や各種フォーラムに投げる場合、次のようなタグを付けると適切な回答者の目に触れやすくなります。
windows-serverstorage-spacesrefsfile-systemperformancesmall-files
オンプレ前提の話であれば、Windows Server 側のカテゴリに投稿するのが確実です。
まとめ
- ReFS+記憶域スペースには、「ファイルシステムのメタデータだけを SSD ティアに固定する」ための公開機能は存在しません。
- 記憶域スペースの階層化は、基本的にデータブロックのヒートマップにもとづく自動移動であり、メタデータだけを狙い撃ちする設計にはなっていません。
- 小さいファイルが 10 億件規模で存在する場合、FS 操作のレイテンシを大きく改善したければ、SSD 側に全体を寄せる(SSD ティア増強・全 SSD 化)か、そもそもストレージ設計・アプリ設計を見直す必要があります。
- その中間解として、ホットデータのピン留め、WBC の見直し、ディレクトリ分割、小ファイルの束ね(アーカイブ/コンテナ化)などを組み合わせることで、段階的な改善を狙うことができます。
- クラウド移行が選択肢に入るなら、Azure Files Premium のメタデータキャッシュのように、メタデータ多発ワークロード向けに最適化されたサービスも検討に値します。
「メタデータだけ SSD に置きたい」という発想はまさに本質を突いていますが、現状の ReFS+記憶域スペースではそのニーズに直接応えるスイッチは用意されていません。その代わりに、「メタデータも含めて“速い場所”に寄せる」「メタデータの数を減らす」という二方向から地道に対策していくことが、最も現実的なアプローチになります。

コメント