KSM

pfSenseルータ(メモリ2GB)×2とSSHサーバー(メモリ1.2GB)×3+仮想化モニタでfreeコマンドで8GBほどメモリを占有していると表示される。
KVM+QEMUは起動時に必要なメモリページは確保してしまい、そのあと実際に使っていなければスワップされるという戦略で動いているらしい。
VirtualBoxは逆に必要になったらホストOS上でメモリを確保する戦略で動いているように見える。


仮想化サーバーNUCはメモリ16GBに加え、メモリオーバーコミットに備えた16GBのスワップ領域を用意してあるので特に問題なく動くとは思うが、仮想マシン上では未確保(=ALL 0?)のメモリをわざわざスワップアウトするのも何となくバカらしい気がしたので、KSM(Kernel Samepage Merging)を使ってみることにした。
例によってIBMのサイトに詳細な解説があった。


Linux カーネル共有メモリーの徹底調査


専用のデーモン(ksmd)がメモリページをスキャンし、"あまり更新されない(読み出しデータ/プログラムや0領域)"かつ"内容が同じ"ページを同一のメモリアドレスにまとめることでメモリ使用量を節約する仕組みらしい。
まとめられたページはCoW(Copy on Write)フラグがつけられ、書き込みがない間はそのまま保持され、書き込みが起きると再び分離される。
試すだけならSysfsにechoで1を書き込めば動き出す。


8GBほど使用していたのが、デフォルトパラメータでKSMを有効にすると3.5GBぐらいまで減った。
全ての仮想マシンで同じディストリビューション/カーネルを使っているとKSMの効果が出やすいらしいが、SSH側は多様性のために異なるマシンを使っているので空き容量ぐらいしか効いていない様子。
ルーターの方はまとめられているっぽい。


効果があったので、systemdのksmサービスを使って自動起動するようにする。
とは言っても、上記のecho書き込みを自動化するだけのワンショットサービス。


似たようなシステムはXenvmwareも備えているメジャーな機能らしい。
パフォーマンスへの影響も特になさそうなので、しばらく使ってみる。