Hyper-Vの使い勝手を格段にアップする「Dynamic Memory」を試す
Windows Server 2008 R2 SP1(以下、R2 SP1)で追加されるDynamic Memory機能は、Hyper-Vの機能を強化するものだ。Windows Server 2008 R2で追加されたライブマイグレーションなどと比べれば地味な機能だが、仮想化においては利用頻度の高い機能になる。
Windows Server 2008のベータ版には、仮想化におけるメモリ関連機能として、Dynamic Memoryとよく似た機能が搭載されていたが、Windows Server 2008がリリースされた時には、メモリ管理機能はサポートされていなかった。Windows Server 2008 R2では、ライブマイグレーションの機能追加に注力されたため、メモリ管理機能は後回しになった。
こういった意味では、Windows Server 2008 R2 SP1のリリースより、やっとHyper-Vが当初予定した姿になったといえる。
■Dynamic Memoryとは?
Dynamic Memoryは、ほかのハイパーバイザーでいえば、メモリのバルーニング、Hot Addといったオーバーコミット機能により、メモリを効率よく利用する仕組みのことだ。
現在のHyper-Vでは、仮想マシンに設定したメモリ容量を起動時に取得してしまう。つまり、ある仮想マシンが、実際には1GBしかメモリを使う必要がなくても、4GB割り当てられていれば起動時に4GBロックしてしまう。このため、複数の仮想マシンを動かした時に、効率のいいメモリ管理ができない。
サーバーOSを数個だけ動かしているような状況だと、必要なだけのメモリを搭載しておけばいいが、VDI環境などを構築する場合、数十個、百数十個もの仮想マシンを起動しなければならない。大量のメモリを使用するワークロードが動いている仮想マシンもあれば、ほとんど何もしていない仮想マシンもある。すべての仮想マシンが満足するだけのメモリを割り当てていては、ある意味メモリの無駄遣いといえる。
そこでDynamic Memoryでは、各仮想マシンが使用できるメモリの最小値と最大値を決めておき、最小値で仮想マシンを起動し、必要に応じてメモリ容量を増やしていくという仕組みを採用している。また、仮想マシンのワークロードをチェックして、拡張したメモリが必要なくなればハイパーバイザーに返し、常に適切なメモリ容量でOSを動かすことができる。
現在のWindows Server 2008 R2のHyper-Vは、固定的にメモリを割り当てる。このため、使っていないメモリを仮想マシン上で無駄にしてしまう(TechED2010のセッションスライドより)。 | Dynamic Memoryでは、メモリが必要な仮想マシンにメモリを追加して、いらなくなったらメモリを回収する |
Dynamic Memoryでは、仮想マシンの機能に必要な最低量のメモリ領域を設定しておき、起動し、ワークロードが高まれば、設定した最大値まで、自動的に拡張していく。この部分は、他社のハイパーバイザーでサポートされているメモリのHot Addでも同様のことが行える。
しかし他社のハイパーバイザーの場合、仮想マシンが使うメモリ領域は拡張されると拡張されっぱなしで、自動的にメモリ容量を削減することはしない(手動では可能)。
一方Dynamic Memoryでは、メモリのバルーニングとHot Addを連動しているため、メモリ領域がいらなくなったら、仮想マシンが使用していないメモリ領域をバルーニングで回収し、ほかの仮想マシンに提供したり、ハイパーバイザーに空きメモリとしておいておいたり、といったことができる。
このように、動的にメモリの容量を変化させられるのが、文字通り、Dynamic Memoryの特徴になる。
Dynamic Memoryと他社のハイパーバイザーのメモリのオーバーコミット機能の差。Dynamic Memoryは、仮想マシンから実装しているメモリがダイナミックに変化する。他社のオーバーコミットは、名目上メモリが割り当てられているが、実際に使用時にメモリが割り当てられる |
■ページ共有やホストページングはあえて実装せず
他社のハイパーバイザーでは、メモリのバルーニング、Hot Add、ページ共有、ホストページングなどの仕組みでメモリ管理を行っている。しかし、Dynamic Memoryでは、メモリのバルーニングとHot Addしかサポートしていない。
これは、マイクロソフトのメモリオーバーコミット技術が劣っているから、というわけではない。ページ共有やホストページング技術は、今後の仮想環境においてはメリットがほとんどなく、デメリットの方が多いと考えて、あえてインプリメントしなかったという。
ページ共有は、今までの4KBのページなら同一データになる可能性が高いため、共有しやすい。しかし、ラージページを使用したWindows OSは、2MBのページに拡張されているため、同一データに可能性が少ないため、ページ共有が利用できるシーンは少ない |
このうち、ページ共有は、ハイパーバイザーがメモリのページを定期的に監視して、ハッシュ値を付け、このハッシュ値が同じ数字になれば、同一内容のページとして、そのページを複数の仮想マシンで共有する技術。同じ種類のOSを多数動かす時は、OSのシステム部分がほとんど同じになる。こうした時にページ共有を用いて、メモリを節約する。
しかしここで問題になってくるのが、ページの大きさだ。Windows Vista/7、Windows Server 2008/2008 R2、Hyper-Vなどは、2MBを1つの単位としたラージページを使用しているということだ。以前の、4KBを1つのページ単位とした状況では、ページの内容がマッチすることが多かったものの、2MBという大きなページにおいては、内容が完全にマッチするというのはまれになってきている。
つまり、2MBをページ単位としているラージページでは、ほとんどページ共有をするチャンスがないため、ハッシュ値などを生成することに無駄なCPUパワーが必要になってしまうのだ。
もう1つのホストページングは、仮想マシン上でメモリが足りなくなった時に、仮想ディスクにページファイルを作成して、スワップを行う技術。こういった状況がほかの仮想マシンでも起こるようになれば、ハイパーバイザーレベルでもディスクにページファイルを作成することになる。
しかしディスク上に作成されるのだから、ページファイルは、CPUの動作クロックから考えれば、信じられないほど遅い。もし、仮想マシンで頻繁にスワップが起こるようなら、ディスクアクセスが頻発して、仮想マシンのCPUパワーはディスクアクセスにかかりきりになり、ほとんど意味のある動作ができなくなる。
さらに、仮想OSでは重要なページでも、ハイパーバイザー上では単なる普通のページとしてしか認識しない。このため、ハイパーバイザーでは、仮想OSで必要なページさえもスワップしてしまう。もしこのような状況になれば、仮想マシンの動作は急激に遅くなり、仮想マシンを使っているユーザーから見れば、ハングアップしたように感じるだろう。
ホストページングには、ディスクを一時的なメモリとして使用し、メモリ不足を補えるといったメリットもあるが、これはメモリが非常に高価で、容量が少なかった時代のテクノロジーだ。現在のように、大容量のメモリが安価に手に入る時代では、ホストページングしないように十分なメモリを仮想化するサーバーに搭載すべきだろう。
ホストページングは、メモリが足りない時にディスク上にページファイルを作ってスワップする | もし、メモリに余裕がない場合、仮想マシンがページングにかかりっきりになるスラッシングが起こる。スラッシングが起こると、システムがデッドロックになったように、止まってしまう |
Hyper-Vでは、仮想マシンのメモリをロックして、スワップしないようにできる |
さらに、Dynamic Memoryでは、仮想マシンが使用しているメモリをハイパーバイザーが勝手にスワップしないように、ロックする機能が用意されている。ロックするだけの物理メモリが必要になるが、スワップを頻発して、システム全体がデッドロックに入るよりもいい。もし、これで、仮想マシンが必要な数起動できないなら、必要なだけメモリを増やせばいい。
それよりも、メモリのバルーニングとHot Addの機能をうまく使うことで、仮想マシンの動作に必要なメモリを、必要な時に、必要な分だけ、ダイナミックに用意する方が便利だ。
このように、こういった考え方のもとで、Dynamic Memoryでは、メモリのバルーニングとHot Addの機能だけを追加したのだ。
■Dynamic Memoryの使い方は?
Dynamic Memoryを使用するには、Windows Server 2008 R2にSP1をインストールすればホスト側はOKだ。ゲストOS側は、SP1に対応した最新の統合サービスをインストールする必要がある。また、Dynamic MemoryがサポートされるゲストOSとしては、Windows Server 2003/2008/2008 R2、Windows Vista/7となっている。Linux OSに関しては、現状ではサポートは表明されていない。
実際にDynamic Memoryを使用するには、Hyper-Vマネージャーでそれぞれの仮想マシンの設定→メモリ設定を開く。デフォルトでは、メモリ設定は「静的」に設定されている。これを「動的」に変更して、「スタートアップRAM」、「最大RAM」、「バッファー」、「メモリの優先度」を設定すればOK。
「スタートアップRAM」は、仮想マシンを起動するのに必要な最低限のメモリ容量。ここで指定した容量が、起動時に必ず確保される。つまり、ここで指定するメモリ容量は、起動時に必要な最低限のメモリ容量を指定しておき、後は仮想マシンが必要とするメモリをダイナミックに追加していくのが、一番いい方法だ。
「最大RAM」は、この仮想マシンが使用する最大メモリ容量だ。
「バッファー」は、仮想マシンの空きメモリ(バッファー)を指定したパーセンテージ分だけ残すように指定する。Windows OSは、空きメモリをOSのキャッシュとして動作をアップする。例えば、SuperFetchなどは、空きメモリを積極的に使用する。つまり、1GBを仮想OSで使用している場合、バッファーを20%に設定していれば、その仮想マシンは合計1.2GB(仮想OSの1GB+バッファーで指定したメモリ200MB)のメモリを使用することになる。
「メモリの優先度」は、Hyper-V上での仮想マシンのメモリ優先度だ。つまり、個々の仮想マシンにメモリの優先度を付けることで、もしHyper-V上のメモリがなくなった場合、優先的にどの仮想マシンに追加するのかを設定することができる。
もし、空きメモリが少なくなった場合、優先度の高い仮想マシンにメモリを優先的に割り当てる。優先度の低い仮想マシンは、メモリがHot Addできない場合、最悪のケースではこの仮想マシンが動かない場合もある。
Dynamic Memoryでスタートアップ時1024MB、最大3072MBという設定にしてみた | 複数の仮想マシンを起動してみた。もっとも優先度が高いのが、RemoteFX。RemoteFXは、すでに2266MBにまで、メモリが拡張されている。サーバーには、4GBしかメモリがないため、優先度の低いVDIは起動さえしなかった |
Dynamic Memoryは、ライブマイグレーションに比べると地味な機能だが、常にHyper-Vで利用される機能だろう。また、メモリのオーバーコミット機能は、必要な時に、必要なだけのメモリを仮想マシンに提供する。便利なのは、メモリを追加しっぱなしではなく、必要がなくなればメモリを仮想マシンから回収してくる。これにより、Hyper-V上で効率的なメモリ管理が行える。
ただし、無理な設定は禁物だ。やはり、Hyper-Vを動かすサーバーに必要なだけのメモリを用意しておく必要がある。例えば、4GBしかメインメモリがないサーバーで、4GBのメモリ容量を必要とするWindows 7を複数台動かすことはできない。
Dynamic Memoryといえども、魔法のように、何もないところから必要なメモリを生み出すことはできない。やはり、適切な容量のメモリをきちんと用意しておく必要がある。