[Virtualization][Hardware] CPU性能不足に直面するのは辛い

タイムシェアリングシステム

VMwareは「タイムシェアリングシステム」として動いていることはご存じだろうか。
1台の物理マシン上であたかも複数のマシンが動くかのように見せる、しかもそのオーバーヘッドが最も少ない方法としてだいぶ昔に「ハイパーバイザー」というものが誕生し、現在は様々なプロダクトでこの仕組みが動いていたりする。

タイムシェアリングシステムそれ自体はさらに昔からずーっとあるもので、CPUを使用する時間をもの凄く細かく分割して、複数の動作するプログラムに対して必要に応じて割り当てるというものだったりする。実際には、CPUを「利用できる/できない」と言うことしか出来ないので、時間割を作って例えば

  • A君は8時から20分間だけ使ってね
  • B君は8時20分から10分間だけ使ってね
  • C君は8時30分から30分間だけ使ってね
  • A君はその後9時から20分間使って良いよ
  • C君はその後9時20分から20分使って良いよ

みたいな感じでCPUリソースが使われていきますよと。これがタイムシェアリングシステム。
私は大学時代にこのことについて学び、それを採用したシステムの一つとしてUNIXが挙げられていた。こうやって細かく時間を区切って各プロセスに処理をさせることで、あたかも複数のプロセスが並列動作しているように見えたわけだ。

10年ちょっと前ぐらいの仮想基盤サイジングの肝と言えばメモリ

ちょっと話題を変えることに。
昔VMwareを使ってたころはとにかくメモリ容量が重視されていて、というのもバルーニングドライバが動き出すと使われないメモリのスキャンや解放処理がVMware側で勝手に行われるようになる。特にOracleとかSQL Serverとかでこれが発生すると、OSやミドルウェア側でアサインしたはずのメモリがもぎ取られるのだからまともに動かなくなったりする。

だが、ここ最近はメモリ容量にかけてはどんどん単価が安価になったこともあり、極端に大容量化するようになった。それこそ私が仮想基盤を手がけた際にサーバに搭載してた単一サーバ辺りのメモリ量なんて24GBあったら「超スゲー!」とか言うような時代だった。それを10台も並べれば立派な大規模仮想基盤ができあがった訳なんだけど、今やノード辺りのメモリ量なんて下手すればTB級のノードが爆誕することだってある。

我が家の環境も、ハイパーバイザーをちゃんと触りだしたのが2007年頃、Microsoft Hyper-V 1.0が最初だったのだけど、このころに搭載してたノード単位のメモリはわずか8GB。現在はVMwareにすっかり統一されたが、最大のメモリを搭載したノードで168GB載ってる。良い時代になったもんだ。

ところが、ここで別のボトルネックに遭遇して悶絶したりする。それがCPU負荷だったりする。

CPUwaitがデカいとダウンするサーバが増えた

このことに気づく発端はEMCが提供しているUnity VSA Community Editionを使ってiSCSIをやろうとしたとき。何故かiSCSIを動かすとパニックリブートが発生するわけでして。ディスク待ち時間もそんなにないし、CPU使用率も高くない。何故こんなに落ちるのかと調べて分かったのが「CPU準備完了」というパラメータだった。

ストレージはCPU処理が凄く敏感

ストレージがなんであんなに高いかって、CPU処理中の遅延を最小に抑えながらそれに特化した処理を多数のディスクに対して並行実行するからと言うのがここ最近分かるようになってきた。例えばどんなにメモリを搭載してSSDぶっ込んで立派なストレージを作っても、CPUがAtomとかだと限界は意外とすぐに訪れる。流れるブロックデータを迅速に処理する必要があるからなんだけど、そこが遅延するとディスク応答はホストに到達するころには膨大なものになっている可能性が高い。

UnityVSAに関しては、CPU準備完了時間が100msecを超えるとダウンすることが分かった。
以前はXeon E55xx系やE56xx系でも十分処理できるものばっかりだったのだけど、仮想アプライアンスなんかはその厳格なCPU管理をハード時代と同じぐらいにそのまま持ってきて提供してくださるというまぁまぁなかなか笑えない製品をぽろぽろ出しているなぁと。

例えば以下のようにストレージ待ち時間が100msecを切ってるにもかかわらずにOSがパニックリブートを起こすんだから本当に笑えない。

とある仮想ストレージが悲鳴を上げた時のストレージ待ち時間状況

CPU待機時間を削りたければシェア率を上げる

CPU待機時間を削るには、2つの方法がある。

  • CPUコアを占有させる
  • CPUシェア率を引き上げる

CPUコアを占有させるとぶっちゃけCPU独占状態で動くわけだから、他のVMを気遣ってCPUを使ってイイ時間を待つ必要なんてないという考え方が前者。だけど、VMwareだと特にこのコア占有設定が何気に難しい。しかも、設定ミスをして他のVMが紛れ込んだらボチューンギャー!ε=ε=(*ノ>Д<)ノ!てなるので、実はこれを使うのはしんどい。

もう一つの方法であるCPUシェア率の引き上げ。これは設定が簡単。
何をするかというと、先に述べたタイムシェアリングシステムとして稼働するハイパーバイザー様というか、CPUスケジューラ様にたっぷり時間を用意して貰うと言うこと。シェア率が高ければCPU使用時間を多めに占有できるし、低ければCPU使用時間が少なく、隙間を縫って「こそっ!こそっ!」とせせこましく処理しなければならなくなる。多ければCPU準備完了時間は減り、少なければCPU準備完了時間は減少する。

設定は以下のような感じ。

設定箇所

値は[低・標準・高]と[カスタム]があり、カスタムにすると最小1,000から最大1,000,000まで設定できる。仮想ストレージアプライアンスを動かす際は、どうもこの値を最大値まで持って行かないと色々厳しい。現在Isilon SD Edgeを動かしているので、それを例にすると、

CPU準備完了グラフ

上記グラフでは、15:50まではシェア値200,000で定義しており、その後600,000に増やし、16:15頃に業を煮やして最大値に設定した内容となっていて、最初は恒常的に合計値として数千msec単位で遅延していたCPU処理が右端だとうりうりっと下がっている。多分右端の時点では数百msecまで下がっていると思われる。

これは、そのESXiホストの中でどの程度のVMがどの程度CPUを使用しているか、その頻度に依存しており、ストレージで例えると「スループットじゃなくてIO数」という所か、それによって大きく変わる。例えば以下のグラフはシェア率は200,000のままなんだけど、動いてるVM数が2vCPU×3台でコア数がぴったり一致している場合の仮想ストレージの動作状況。グラフの形状は激しそうに見えるけど、実際全てのvCPUのCPU待機時間は100msecを割り込んでいる。

自宅環境で構築するならもうサーバよりPCがいいのかも。

自宅で検証用途にエンタープライズ機器を配置する人は増えてきたと思う。そのハードウェア自体の勉強をしたいのであれば別に構わないのだけど、「サーバは速いから」という単純な理由で無理してラックマウントサーバを買う必要はないのかなぁと正直感じている。

理由としては以下を挙げている

  • CPUの速度は「世代」で格段に変わる。古い世代のハイエンドXeonは、現行のハイエンドCoreシリーズよりずっと遅い
  • PC用プロセッサは1世代先を走っており、既に世代間の速度差が顕著に出る
  • Xeonはバックグラウンド処理に特化、Coreシリーズはフォアグラウンド処理に特化

何て言うか、Xeonってスゲーという人が結構な数いらっしゃるんだけど、マルチプロセッサで組むと間違いなく電気食うし、当然熱量も半端ない。で、その割に速くないし、ぶっちゃけ10年前のプロセッサ辺りは本当にアプライアンス系を動かすのはかなり苦しい。ファンノイズもデカいので、そこを割り切れるかどうかで購入を決めた方が良いのかなと正直感じている。

ただ、拡張性は段違いに上なので、たくさんストレージを積みたい、PCでは組み込めなさそうなインタフェース(10GbpsなNICとか)を組み込んでEnterprise構成を模擬したいとか、メモリをバカ積みして(´∀`*)ウフフしたい!とか、そういう目的なのであれば良いんじゃないかなと思う。やっぱり実際に企業で使われてる業務用コンピュータってなんぞ?というのは触ってみないと分からない。

我が家はさすがにNehalem-EP/Westmere-EPに限界を感じ、長年嫁様に怒られながらも、機器のグレードを落としながらも(特にネットワーク機器)、こないだついにSandy Bridge-EP/EN系に統一することがかなった訳で。
だが、この機種がもう既にVMware ESXi 7.0が動かないことが判明しており、唯一の解決策がNestedでノードを作ることだそうで・・・いやはや、自前で検証環境をこさえるのは今の財政状況だとそろそろ限界なのかもしれない。

No tags for this post.