Mentha Spicata

自分がやったお仕事原稿のフォローアップなどを掲載していきます。

Fusion Driveに関する考察

SSDの速度に慣れすぎるとHDDでのシステム起動時間の正常範囲内の判断が鈍くなるのが恐い氷川です。

Mac Fan 2013年1月号2月号iMac (Late 2012)の特集記事をFusion Driveを中心に原稿をお手伝いさせていただきましたが、紙面ではページ数の制約も多かったため技術的な側面にはあまり触れませんでしたのでこちらで追記します。

Fusion Driveとは何なのか

アップルの公式サポート記事には「Fusion Driveは、フラッシュストレージのパフォーマンスとハードディスクの容量を組み合わせた、Mac mini (Late 2012) および iMac (Late 2012) コンピュータ向けの新しいストレージオプションです」とあります。

物理的にはフラッシュストレージ(SSD)とハードディスク(HDD)が1基ずつ接続されていますが、システム上では1つのボリュームとして表示されているため、使用しているユーザはあまり意識することはないでしょう。

動作の仕組みとしては「アクセスを高速化するため、頻繁に使うファイルが自動的かつダイナミックにフラッシュストレージに移動され、あまり使わないファイルはハードディスクに保存されます。その結果、コンピュータ本体の起動時間が短縮されると同時に、システムがユーザの作業スタイルを学習していくにつれてアプリケーションの起動やファイルへのアクセスが速くなっていきます。Fusion Driveはこれらをすべてバックグラウンドで自動的に処理します」とありますが、要するに容量が多く可能な限り高速なストレージをソフトウェア的に実装する仕組みだと考えれば良いと思います。

大容量のSSDはHDDに比べて高価ですし、数TBクラスのものも存在しますが、個人で気軽に買えるレベルではまだない現状です。そこで前述の「頻繁にアクセスする」データを高速なフラッシュドライブ側に乗せるというアイディアは以前からありました。代表的なものは1つのドライブにNANDフラッシュとハードディスクを組み込んだSeagateLaptop SSHDやMomentus XTシリーズがありますが、これらはSSD側の容量が8GBということもあり、起動ディスクを高速化しようとするとほとんどシステム領域だけで使い切ってしまうため、他のファイルのための領域はあまり多くありません。

他にもIntel Smart Response Technology (ISRT)という機能もありますが、これは特定のチップセットを積んだマザーボードでのみ利用可能なこと、キャッシュの割当が最大64GBなこと、また、あくまでキャッシュなためディスク使用可能領域が減ってしまうことなどがあり費用対効果がよくありません。というか今日日SSDでも120〜500GBあるので一部だけパーティションが区切られて頻繁に読み書きすることによって、寿命が縮むような使い方をするのも疑問が残ります。

この辺りを考えてもFusion Driveは使用するSSDの容量に制限がないこと、実装をソフトウェアで行なうことで、特定のハードウェアに限定されないことなどから後発としてよく考えられた仕組みになっているのではないでしょうか。

HFS+の拡張ではない

日本語のFusion Drive関連の記事を読むと「Fusion DriveはHFS+の発展系で云々」みたいな残念なものばかりを見かけますが、みなさんどうもHFS+が持っているHot File Adaptive Clusteringが先入観にあるようで、そこで考察が完結してしまっているようです。

Mac Fan 2013年2月号でも解説しましたが、HDDは構造上、外周部のほうが読み込みが速く、内周部に近づくにつれて読み込み速度が遅くなります。この仕組みを利用して、HFS+は頻繁にアクセスされるファイルを監視して定期的にデータをディスク外周部へと再配置を行なっています。HFS+ のファイルシステムにsyncがかかったとき、つまりバックグラウンドで利用状況が計算され、結果は/.hotfiles.btreeに格納されます。これがHot File Adaptive Clusteringの仕様です(この実装のソースコード公開されていますので、興味のある方は一読されることをお勧めします)。

ところが、このHot File Adaptive Clusteringという仕組みはSSDには行なわれません。外周、内周という概念のないSSDには必要ない(というかむしろ均等に使うことが望ましいとされる)ので、ディスクのマウント時にHDDかSSDかのチェックが実行されます。SSDタイプのMacを使われている方は /.hotfiles.btreeが無いことに気付くはずです。

これはFusion Driveも同様で 、ディスクのどこを探しても.hotfiles.btreeは作成されていません。発想は確かに独創的なものではなく、Hot File Adaptive Clusteringから発展させたものかもしれませんが、実装に関してはまったく別の次元から行なわれているのです。

Fusion Driveの実際の動きを監視してみる

Fusion Driveはまず優先的にSSD側のデータ領域を使い潰します。データが溢れると自動的にHDD側にスイッチされて書き込まれるため、書き込み速度が遅くなる以外とくにつつがなく進行していきます。ターミナルでiostatコマンドを使ってチェックしましたが、この動作自体はJBOD的であり、たぶんそういった類いのものと大きな違いはないと言っていいと思います。

     disk0(SSD)          disk1(HDD) 
   KB/t tps  MB/s      KB/t tps  MB/s
 915.91 141 125.98     0.00   0  0.00
1016.09 129 127.88     0.00   0  0.00
1014.97 113 111.93     0.00   0  0.00
1011.56  82 80.92      0.00   0  0.00
1016.03 128 126.84     0.00   0  0.00
1016.09 129 127.84     0.00   0  0.00
1013.48  97 95.88      0.00   0  0.00
1024.00  96 95.96      0.00   0  0.00
 958.58  48 44.91   1007.30  57 56.04
   4.00   1  0.00   1010.16  74 72.92
   8.00  24  0.19   1024.00  66 65.92
   4.00   2  0.01   1010.53  76 74.95
  15.43   7  0.11    974.74  70 66.59
   4.00   1  0.00    912.00  82 72.95
   4.00   1  0.00    931.33  96 87.21

特徴的なのはこの後で、読み出されたファイルには頻度を評価するメタデータが付与されます。その回数に応じてファイルシステムSSDやHDDへの再配置をバックグラウンドで行なうようになります。今度はfs_usageコマンドを使って眺めていると、下記のような「RdChunkCS」「WrChunkCS」「RdBgMigrCS」「WrBgMigCS」 など末尾にCSの付いたカーネルタスクのコールが見えるはずです。この「CS」はCore Storageの略でFusion DriveでのHot File Adaptive Clusteringの役割を担っています。

15:33:27.189432     RdChunkCS      D=0x00debd00  B=0x20000      /dev/disk0s2
0.000328 W kernel_task.17601

15:33:27.189468    RdBgMigrCS      D=0x0033d8a0  B=0x20000      /dev/CS
0.000367 W kernel_task.17601

15:33:27.190136     WrChunkCS      D=0x0aeac500  B=0x20000      /dev/disk1s2
0.000629 W kernel_task.17601

15:33:27.190172    WrBgMigrCS      D=0x0033d8a0  B=0x20000      /dev/CS
0.000670 W kernel_task.17601

15:33:27.190531     RdChunkCS      D=0x00debe00  B=0x20000      /dev/disk0s2
0.000328 W kernel_task.17601

15:33:27.190568    RdBgMigrCS      D=0x0033d8c0  B=0x20000      /dev/CS
0.000369 W kernel_task.17601

15:33:27.191233     WrChunkCS      D=0x0aeac600  B=0x20000      /dev/disk1s2
0.000627 W kernel_task.17601

15:33:27.191269    WrBgMigrCS      D=0x0033d8c0  B=0x20000      /dev/CS
0.000667 W kernel_task.17601

15:33:27.191638     RdChunkCS      D=0x00debf00  B=0x20000      /dev/disk0s2
0.000336 W kernel_task.17601

15:33:27.191673    RdBgMigrCS      D=0x0033d8e0  B=0x20000      /dev/CS
0.000376 W kernel_task.17601    

そもそもHFS+のファイルの再配置は20MB以下のサイズのみに限定されているため、それよりも大きなファイル(たとえば頻繁にアクセスするビデオファイルがあったら?)の配置が行なえなくなる可能性があります。再配置に関してもエクステント(連続記録領域)の数に関係なく評価を行い、128KB (0x20000 bytes) 単位で頻繁に入れ替えを行なっています。また、書き込み速度を稼ぐために定期的にSSD側に空き領域を確保し、約4GBの「ランディングゾーン」を作成しているのも特徴的です(この実装のソースコードも同様に公開されています)。

縁の下の力持ち「Core Storage」

OS Xで「Core」が付くものといえばCore DataやCore Audio、Core Animationなど現在のAPIの柱となる重要なクラスばかりです。10.7から登場したCore Storageはあまり大きな紹介もなくひっそりとFile Vault 2の暗号化のために使われていました。ターミナルからdiskutilコマンド経由でこのCore Storageを呼び出しても実装されているんだかされていないんだかよくわらない引数が多く、現在も企みが見えない部分もあります。

コマンドライン経由でFusion Driveの作成を実行するとわかるのですが、Fusion Driveが書き込むディスクの優先順位は、diskutil cs createを実行した際に指定したディスクの順番でインデックスが決まっており、HFS+が持っているディスクの種別判定は利用されていません。静的に決めている理由はよくわかりませんが、セカンダリのディスクにSSDが利用できるということは「高速なSSD(e.g. SLC的なもの)+低速なSSD(e.g, MLC的なもの)」みたいな組み合わせも想定できるわけで、意外に息の長い技術になるかも知れません。

余談。

10.7の時点から既に今回のFusion Driveで使われているcreateVolumeなどのオプションは見えていましたが、まさかこんな使い方をすると想像できた人は、中の人以外いなかったんじゃないでしょうか。

実はこのFusion Driveの記事以前に、氷川はこのCore StorageのFileValut 2の機能と、createVolumeなどの引数から「アップルはストレージ系で何か新しいことをやろうとしている」という原稿を書いていましたが、 「ちょっと未来過ぎて読者がついて来れない」という理由で没になっていました(苦笑)。あの時そのまま採用されていれば「日本一早くFusion Driveの核心に迫っていた記事」になっていたかも知れませんね?

参考文献

Achieving fusion—with a service training doc, Ars tears open Apple’s Fusion Drive
英文記事ですが、Fusion Driveをきちんと解析した記事としてはこれが一番まっとうでした。ほぼこれの追試をしていたといっても過言でないほどテスト内容も充実しています。

Undocumented Mac OS X:第11回 HFS Plus独自の機能【後編】
古い記事ですが、いまだに重宝するのがこのシリーズ。白山さんまたこの続き書きませんかねえ…。また、本誌原稿作成の際にhfs_hotfiles.cのソースコードリーディングによる解説という多大なご協力をいただいたことをここで改めてお礼申し上げます。ありがとうございました。