やっぱり Sun がスキ! : Weblog やっぱり Sun がスキ!

やっぱり Sun がスキ!

http://blogs.sun.com/yappri/date/20090326 2009年 3月 26日 木曜日

Atom + OpenSolaris で低消費電力ミニサーバを自作しよう♪ ~へっぽこ SE 奮闘記~

今話題のインテル Atom プロセッサーと OpenSolaris 2008.11 を組み合わせて
消費電力がとっても低い "エコな" ミニサーバを自作しましたのでご紹介。

一家に一台 常時稼働の My Solaris サーバがあると色々できて便利ですし
会社にいなくとも新しい OS の機能テストなどで活用できそうですよね!
でも、自宅でサーバを動かすとなると、気になるのは電気代というランニングコスト。
サーバ用途となると常時電源 ON にしておく事になるので、消費電力を抑えて
なるべくエコに行きたいですよね!

そんな中、着目したのはインテルの Atom プロセッサー搭載ベアボーンキット。
ネットブックに採用されるような消費電力や発熱が低いインテル Atom プロセッサー
であれば電気代を抑えることが出来ます。 最近ではデュアルコアモデルも登場して
いるので、サーバとしての処理能力不足の心配もありません。
また純な IA 系のプロセッサーなので、そのまま一般の Solaris が動作できる環境で
あるのも大きなメリットです。

ということで早速コレは作らねば!っと、ベアボーンキットと PC パーツを購入しました!(^o^)

パーツ構成内容は以下の通りです。

 ・Shuttle X27D (DualCore Atom 330 ベアボーンキット)
 ・DDR2 2GB DIMM x1枚 (240pin Type)
 ・DVD Drive (SlimType SATA)
 ・SSD 60GB (SATA)

# HDD ではなく SSD を採用したのはミニサーバの静音性とパフォーマンスを
# 高める目的と消費電力の低さを期待してのチョイスです。


購入してからハッと気がついたのですが・・・オンボードで搭載されたネットワークやビデオ
オーディオのチップが OpenSolaris で問題なく認識されて動作するかということ・・(^o^;;

X27D のマザーボードにオンボードで搭載されている各種チップは以下のものが
使われているのですが・・


・NIC: Realtek 8111C
・ビデオ: Intel 945GC (Intel GMA 950)
・サウンド: ICH7

事前にあまり考慮せずに購入してしまっていたのでドキドキしながら
OpenSolaris 2008.11 Live CD 起動での Device Driver Utillity でチェック!
無事に認識されてほっと一安心 (^o^) で早速インストール!


  【マウスクリックで大きな画像が表示されます】

Atom 330 は物理デュアルコアと Hyper-Threading で Solaris OS からは
4 スレッドの CPU リソースとして認識されます。
( もちろん perfbar を表示させれば 4 本のバーが立ちます。)
これなら Solaris が得意なマルチスレッドプログラムの開発の
簡単な動作テスト環境としても、使えるかもしれませんね!

さてさて肝心のシステム全体での消費電力チェックですが、使用したのは
自前のワットチェッカー。 # "自前の"というのがポイントです(笑)
このワットチェッカーを電源ケーブルとコンセントの間にはさんで計測!


   【通常時は 27W~34W で稼動】


   【瞬間最大でも 38W 以下】

なんと起動時 32W 前後で通常稼働時 27〜34W と予想以上に低消費電力な結果が!
色々と負荷をかけてみた結果、CPUのみの高負荷であれば消費電力への影響は
さほどでもなく、DVD ドライブを動かして且つ高負荷時状態の一瞬に 38W の表示を見ましたが
これは DVD ドライブの物理的に稼働するモーター部分が影響したものと思われます。
常時稼働のサーバ用途を考えるとおそらく普段は平均 30W 前後の消費電力でしょう。
地球に優しい省エネサーバです♪

と言うことで、Atom プロセッサーと OpenSolaris を組み合わせる事で
とうとう電気料金にビクビクせずに常時稼働の Solaris サーバ環境を
自宅にもお気楽に導入出来る時代がやって参りました!(^o^)/
さーて、どんなサービスをこのサーバの上で動かしましょうか?
夢は広がります!(^o^)

http://blogs.sun.com/yappri/date/20090325 2009年 3月 25日 水曜日

fstyp コマンドの紹介

今回は、fstyp コマンドの使い方を紹介します。

fstyp は、物理ディスクに対してどのようなファイルシステムが構築 されているか簡単に確認できるコマンドで、マウントされていないディスクの ファイルシステムを確認するときに便利です。
最近では、ZFS でファイルシステムを作成する機会も増えていると思います。 いざ、新しいファイルシステムを構成する際、古いディスクの内容が UFS か ZFS か マウントする前に確認できます。

では早速 fstyp コマンドを実行してみましょう。今回は、 ufs と zfs の パターンを試してみます。

# fstyp /dev/rdsk/c2t0d0s0
zfs

# fstyp /dev/rdsk/c1d0s0
ufs
このように、ファイルシステムの種類が確認できます。

また、fstyp に -v オプションを付与して実行すると、ファイルシステムの 詳細な情報が出力されます。

# fstyp -v /dev/rdsk/c2t0d0s0
zfs
    version=10
    name='test-pool'
    state=0
    txg=4
    pool_guid=6270673848113803569
    hostid=732000556
    hostname='pana'
    top_guid=7931163825645079126
    guid=7931163825645079126
    vdev_tree
        type='disk'
        id=0
        guid=7931163825645079126
        path='/dev/dsk/c2t0d0s0'
        phys_path='/pci@0,0/pci10f7,8338@1d,7/storage@2/disk@0,0:a'
        whole_disk=0
        metaslab_array=14
        metaslab_shift=22
        ashift=9
        asize=504889344
        is_log=0
                
# fstyp -v /dev/rdsk/c1d0s0
ufs
magic   11954   format  dynamic time    Tue Mar 24 16:18:53 2009
sblkno  16      cblkno  24      iblkno  32      dblkno  760
sbsize  2048    cgsize  8192    cgoffset 64     cgmask  0xffffffc0
ncg     417     size    20480544        blocks  20170273
bsize   8192    shift   13      mask    0xffffe000
fsize   1024    shift   10      mask    0xfffffc00
frag    8       shift   3       fsbtodb 1
minfree 1%      maxbpg  2048    optim   time
maxcontig 7     rotdelay 0ms    rps     60
csaddr  760     cssize  7168    shift   9       mask    0xfffffe00
ntrak   48      nsect   128     spc     6144    ncyl    6667
cpg     16      bpg     6144    fpg     49152   ipg     5824
nindir  2048    inopb   64      nspf    2
nbfree  1483254 ndir    41078   nifree  2177920 nffree  247827
cgrotor 269     fmod    0       ronly   0       logbno  1568
version 2
fs_reclaim is not set
ファイルシステム状態は有効です。fsclean の値は -3 です。
どの回転配置でもブロックを利用できます。
     シリンダ数 0:
       位置 0:      0    8   16   24   32   40   48   56   64   72   80   88
                   96  104  112  120  128  136  144  152  160  168  176  184
                  192  200  208  216  224  232  240  248  256  264  272  280
                  288  296  304  312  320  328  336  344  352  360  368  376
....
....
(以下省略)


fstyp の -v オプションは、ZFS のバーション確認をしたい場合や、UFS の 状態を確認したい時に便利ですね。

http://blogs.sun.com/yappri/date/20090324 2009年 3月 24日 火曜日

vmstat コマンドの読み方

はじめに

今回は vmstat コマンドの出力について解説したいと思います。vmstat は性能解析や障害解析を行う際に最も基本的なコマンドです。vmstat を使用すると、サーバのリソースとして不足しがちな CPU とメモリの使用状況を俯瞰する事が出来ます。システムの解析を行う際はまず vmstat から始め、症状に応じて別のツールを試して行って下さい。

vmstat のお勧めのオプション

インターバルのみ

 % vmstat 1

vmstat コマンドの最も一般的な使い方はインターバルのみを付けて実行する事です。インターバルは 1 秒を指定します。より正確な負荷状況を見る為、長期間の性能監視の場合でもインターバルは 1 秒にする事をお勧めします。

"-p" オプション

 % vmstat -p 1

vmstat コマンドに -p オプションを付けると仮想メモリのページングに関する統計情報を取得する事が出来ます。ファイルシステムの仮想メモリ操作については fsstat -v で見る事も可能です。インターバルは 1 にして下さい。

vmstat の出力

インターバルのみの場合の出力

 % vmstat 1
  kthr      memory            page            disk          faults      cpu
  r b w   swap  free  re  mf pi po fr de sr cd -- -- --   in   sy   cs us sy id
  0 0 0 1496704 529544 7   7 19  0  0  0  2  3  0  0  0  259  559  296  1  1 97
  0 0 0 1430068 455792 6  25  0  0  0  0  0  0  0  0  0  314 1175  458  2  2 96
  0 0 0 1430068 455816 0   0  0  0  0  0  0  0  0  0  0  313 1133  440  1  2 97
  0 0 0 1430068 455816 0   0  0  0  0  0  0  5  0  0  0  377 1340  511  1  2 97

"-p" を付けた場合の出力

 % vmstat -p 1
      memory           page          executable      anonymous      filesystem
    swap  free  re  mf  fr  de  sr  epi  epo  epf  api  apo  apf  fpi  fpo  fpf
  1496676 529516 7   7   0   0   2    1    0    0    0    0    0   18    0    0
  1430020 455744 7  26   0   0   0    0    0    0    0    0    0    0    0    0
  1430020 455768 0   0   0   0   0    0    0    0    0    0    0    0    0    0
  1430020 455768 0   0   0   0   0    0    0    0    0    0    0    0    0    0

vmstat のカラムの意味

kstat

vmstat の各カラムの値は Solaris の kstat という仕組みを利用して取得しています。kstat にはカーネルやドライバから統計情報が逐一報告されており、OS がブートして以降の様々なデータが保存されています。kstat に保存されている統計情報は kstat コマンドを引数無しで実行する事でダンプする事が可能です。また、C や Perl から libkstat というライブラリを使用する事でも kstat のデータにアクセスする事が出来ます。vmstat は libkstat ライブラリを使用しています。

vmstat の出力の殆どは /usr/src/cmd/stat/vmstat/vmstat.c の dovmstats() 関数の中で行われています。一部 I/O の統計情報は show_disk() 関数の中で出力しています。いずれも libkstat の関数を呼び出す事で kstat の情報を取得し、それを加工して出力しています。

数値が幾つなら問題なのか

vmstat の数値はシステムの異常を報せてくれますが、数値が幾つなら問題なのかは常に状況次第です。free の値が 0 ならば明らかにメモリを増強すべきです。しかし sy の値が 10 万を越えていたらどうでしょうか。システムの規模によっては多すぎるかもしれませんが、システムコールに大きく依存したアプリケーションを動かしているのかもしれません。id が 0 である事は問題でしょうか。もし必要なだけトランザクションを捌けているのであれば、vmstat の値が幾つであろうと問題は無いと言う事も可能です。この様に、vmstat の値に閾値を設定して異常かどうかを一律判断するのは困難です。他のコマンドと合わせて、こまめに統計情報を集めて、比較をする中で異常が発生しているかどうか判断して下さい。

r

r は run queue です。CPU の割り当てを待っているカーネルスレッドの数を表しています。この値が 10 以上又は CPU 数の倍以上の場合は CPU への負荷が高い状態になっていると言われています。CPU 負荷は mpstat や prstat 等、他にも様々な方法で確かめる事が出来ます。run queue は情報の一つとしてご覧下さい。

r の値は kstat の unix:0:sysinfo:runque という名前で保存されています。この値は "kstat -p 'unix:0:sysinfo:runque' 1" というコマンドを実行する事で取得する事が可能です。kstat コマンドの結果は累積値で出ますので、差分を取って下さい。

kstat の unix:0:sysinfo:runque は /usr/src/uts/common/disp/disp.c の disp_nrunnable を /usr/src/uts/common/os/clock.c の clock() 関数の中で集計した値です。それぞれの変数がどこで更新されているかは http://src.opensolaris.org/source/index.jsp から検索する事が可能です。

b

b は I/O で待たされているカーネルスレッドの数です。b の値が多い場合は iostat や fsstat, DTrace 等を使用して更に分析して下さい。I/O 待ちをしているスレッドの数が多い場合は I/O の対象となっているディスクを分散したり、ストレージを増強する等の対策が有効です。

b の値は kstat の unix:0:sysinfo:waiting から取られています。"kstat -p 'unix:0:sysinfo:waiting' 1" を実行すると同じ値を取得する事が可能です。kstat コマンドの結果は累積値で出ますので、差分を取って下さい。

kstat の unix:0:sysinfo:waiting は /usr/src/uts/common/os/clock.c の w_io の値から計算されています。w_io は /usr/src/uts/common/os/bio.c の biowait() 関数の中の atomic_add_64(&cpup->cpu_stats.sys.iowait, 1); で加算されている iowait の値を取っています。

w

w は メモリ不足により swap out されたカーネルスレッドの数です。スワップが発生している場合は、メモリを追加してあげるなどの対策が必要です。

w の値は kstat の unix:0:sysinfo:swpque から取られています。"kstat -p 'unix:0:sysinfo:swque' 1" を実行すると同じ値を取得する事が可能です。kstat コマンドの結果は累積値で出ますので、差分を取って下さい。

kstat の unix:0:sysinfo:swque の値は /usr/src/uts/common/os/clock.c の sysinfo.swpque += nswapped; で加算されています。nswapped 変数は /usr/src/uts/common/os/sched.c の swapin() 関数でデクリメントされ、swapout() 関数と process_swap_queue() 関数の中でインクリメントされています。

swap

swap は現在使用可能なスワップ領域のサイズ (Kilo-Bytes) です。ディスク上のスワップ領域とメモリ上のスワップ領域を合わせた大きさになります。

swap の値は kstat の unix:0:vminfo:swap_avail をページ数単位から KB 単位に直した物です。"kstat -p 'unix:0:vminfo:swap_avail' 1" を実行すると同じ値を取得する事が可能です。kstat コマンドの結果は累積値で出ますので差分を取り、ページサイズを掛けて 1024 で割って下さい。ページサイズは pagesize コマンドで取得出来ます。

kstat の unix:0:vminfo:swap_avail は /usr/src/uts/common/os/clock.c 内で計算されています。計算式は k_anoninfo.ani_max - k_anoninfo.ani_phys_resv + MAX((spgcnt_t)(availrmem - swapfs_minfree), 0) で、これは /usr/src/uts/common/vm/anon.h にも CURRENT_TOTAL_AVAILABLE_SWAP として定義されています。この計算式は、ディスクスワップ領域からリザーブ済み領域のサイズを引き、利用可能なメモリ量から swapfs_minfree の値を引いた結果が正数だった場合はその値を足して、使用可能なスワップ領域のサイズとしています。

k_anoninfo は /usr/include/vm/anon.h に定義されており、ani_max や ani_phys_resv を含んでいます。

k_anoninfo.ani_max は ディスクスワップ領域を表しており /usr/src/uts/common/vm/vm_swap.c の swapadd() 関数で加算され、swapdel() 関数で減算されています。

k_anoninfo.ani_phys_resv はディスクスワップの内、リザーブ済みの領域を表しており、 /usr/src/uts/common/vm/vm_swap.c/usr/src/uts/common/vm/vm_anon.c の中で更新されています。

availrmem(available real memory) は利用可能なメモリの量を表しています。/usr/src/uts/common/vm/vm_page.c 等で更新されています。現在の availrmem の値は "kstat 'unix:0:system_pages:availrmem' 1" で取得する事が出来ます。

swapfs_minfree は swapfs の上限を決める為の変数です。swapfs は availrmem - swapfs_minfree 以上大きくはなりません。swapfs_minfree の値は /usr/src/uts/common/fs/swapfs/swap_subr.c の swapfs_recalc() 関数で更新されています。現在の swapfs_minfree の値は "echo swapfs_minfree/D | mdb -k" を実行する事で確認する事が出来ます。

free

free は空きメモリのサイズ (Kilo-Bytes) です。この値が小さくなったらメモリが圧迫されている状態です。UFS のキャッシュは free から取られますが、その場合は free の値は減りません。一方、ZFS のキャッシュは free の値を減らすので、使用しているファイルシステムによって注意して読む必要があります。メモリの統計情報は "echo '::memstat' | mdb -k" でも取得する事が可能です。

free の値は kstat の unix:0:vminfo:freemem をページサイズ単位から KB 単位に直した数値です。"kstat -p 'unix:0:vminfo:freemem' 1" を実行すると同じ値を取得する事が可能です。kstat コマンドの結果は累積値で出ますので差分を取って、その値にページサイズを掛けて 1024 で割って下さい。ページサイズは pagesize コマンドで取得出来ます。

kstat の unix:0:vminfo:freemem は /usr/src/uts/common/os/clock.c 内で freemem の値が代入されています。freemem は /usr/src/uts/common/vm/vm_page.c 等で更新されています。

re

re(page reclaims) は一旦 free list に入れられた後に、そのページ上のデータが再び必要になって復帰したページ数です。

re の値は kstat の cpu::vm:pgrec から取られています。"kstat -p 'cpu::vm:pgrec' 1" を実行すると CPU 毎の値を取得する事が出来ます。free list からの reclaim のみをカウントする場合は kstat の cpu:0:vm:pgfrec を参照して下さい。

kstat の cpu::vm:pgrec は /usr/src/uts/common/vm/vm_page.c の page_reclaim() 関数の中の CPU_STATS_ADDQ(cpup, vm, pgrec, 1); と /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の中の CPU_STATS_ADDQ(cpup, vm, pgrec, pgrec); で計算されています。pvn_write_done() 関数は仮想メモリのページアウト終了時に呼び出される関数です。

mf

mf は minor fault です。minor fault は本来 I/O が発生しない fault の事ですが、HAT fault と Address Space fault を足した数値をカウントしています。

mf の値は kstat の cpu::vm:hat_fault + cpu::vm:as_fault から取られています。"kstat -p 'cpu::vm:hat_fault' 1" と "kstat -p 'cpu::vm:as_fault' 1" を実行し、両者の値を足し合わせる事で mf の値を取得する事が出来ます。ただし hat_fault は現在は全く更新されていない様です。また、kstat の値は累積値が出ますので、差分を取る必要があります。

kstat の cpu::vm:as_fault は /usr/src/uts/common/vm/vm_as.c の as_fault() 関数で計算されています。

pi

pi はページインされたメモリサイズ (Kilo-Bytes) です。

pi の値は kstat の cpu::vm:pgpgin から取られています。"kstat -p 'cpu::vm:pgpgin' 1" を実行する事で pi 同じ値を取得する事が出来ます。kstat の値は累積値なので差分を取って下さい。

kstat の cpu::vm:pgpgin の値は /usr/src/uts/common/os/bio.c の pageio_setup() 関数の中の CPU_STATS_ADDQ(cpup, vm, pgpgin, btopr(len)); で加算されています。pageio_setup() 関数はメモリページング用にバッファを用意する関数です。

po

po はページアウトされたメモリサイズ (Kilo-Bytes) です。

po の値は kstat の cpu::vm:pgpgout から取られています。"kstat -p 'cpu::vm:pgpgout' 1" を実行すると同じ値を取得する事が可能です。なお、kstat の値は累積値ですので、差分を取ってあげる必要があります。

kstat の cpu::vm:pgpgout の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の CPU_STATS_ADDQ(cpup, vm, pgpgout, pgpgout); で加算されています。

fr

fr は free されたメモリサイズ (Kilo-Bytes) です。

fr の値は kstat の cpu::vm:dfree から取られています。"kstat -p 'cpu::vm:dfree' 1" を実行する事で同じ値を取得する事が可能です。

kstat の cpu::vm:dfree の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の CPU_STATS_ADDQ(cpup, vm, dfree, dfree); や /usr/src/uts/common/os/vm_pageout.c の checkpage() 関数の CPU_STATS_ADD_K(vm, dfree, 1); で加算されています。

de

de(deficit) は沢山のメモリ要求が予想される様な状況で、Solaris の仮想メモリが予備として確保するバッファのサイズです。de の値が増えている場合はメモリ不足が疑われます。

de の値は kstat の unix:0:system_misc:deficit から取られています。"kstat -p 'unix:0:system_misc:deficit' 1" を実行すると同じ値を取得する事が可能です。

kstat の unix:0:system_misc:deficit の値は /usr/src/uts/common/os/exec.c, /usr/src/uts/common/os/vm_meter.c, /usr/src/uts/common/os/sched.c, /usr/src/uts/common/os/mmapobj.c の中で計算されています。

sr

sr はページアウトスキャナによってスキャンされたメモリページ数です。ページスキャンが頻発している場合はメモリ不足の可能性があります。ページスキャンは CPU を消費しますので、sr は発生しない事が望ましいです。

sr の値は kstat の cpu::vm:scan から取られています。"kstat -p 'cpu::vm:scan' 1" を実行する事で CPU 毎の sr の値を取得する事が出来ます。kstat の値は累積値なので数秒実行して差分を取って下さい。

kstat の cpu::vm:scan の値は /usr/src/uts/common/os/vm_pageout.c の pageout_scanner() 関数中の CPU_STATS_ADDQ(CPU, vm, scan, 1); で加算されています。

disk

disk はディスクを読み書きした回数です。ディスクの I/O を調べたい場合は iostat コマンドを使用して下さい。

disk の値は kstat のディスクの reads と writes を足した物です。"kstat -p ':::reads' 1" と "kstat -p ':::writes' 1" の出力のうち、ディスクに関する物 (sd など) を集計する事で同じ値を求める事が出来ます。

in

in はインタラプトの回数です。

in の値は kstat の cpu::sys:intr から取られています。"kstat -p 'cpu::sys:intr' 1" を実行する事で CPU 毎のインタラプト回数を取得する事が可能です。インタラプトを調べる場合は mpstat や intrstat コマンドを使用して下さい。

kstat の cpu::sys:intr の値は /usr/src/uts/i86pc/os/intr.c の cpu_stats.sys.intr (x86) や /usr/src/uts/sun4/ml/interrupt.s の SERVE_INTR (SPARC) で計算されている様です。

sy

faults の下にある sy はシステムコールの回数です。

sy の値は kstat の cpu::sys:syscall から取られています。"kstat -p 'cpu::sys:syscall' 1" を実行する事で CPU 毎のシステムコールの回数を取得する事が可能です。kstat の値は累積値ですので、差分を取って下さい。

kstat の cpu::sys:syscall の値は /usr/src/uts/sparc/v9/ml/syscall_trap.s の CPU_STATS_SYS_SYSCALL (SPARC) や /usr/src/uts/intel/ia32/os/syscall.c の dosyscall() 関数の中の CPU_STATS_ADDQ(CPU, sys, syscall, 1); (x86), /usr/src/uts/i86pc/ml/syscall_asm.s の CPU_STATS_SYS_SYSCALL_INC (x86) と CPU_STATS_SYS_SYSCALL (x86), /usr/src/uts/i86pc/ml/syscall_asm_amd64.s の CPU_STATS_SYS_SYSCALL (x86) 等で計算されています。

cs

cs(CPU context switches) はコンテクストスイッチが発生した回数です。多すぎるコンテクストスイッチは CPU を無駄に消費します。スレッド数を減らしたり、プロセッサセットを作って対処して下さい。

cs の値は kstat の cpu::sys:pswitch から取られています。"kstat -p 'cpu::sys:pswitch' 1" を実行すると CPU 毎のコンテクストスイッチの回数を取得する事が可能です。kstat の値は累積値です。

kstat の cpu::sys:pswitch の値は /usr/src/uts/common/disp/disp.c の swtch() 関数や swtch_to() 関数の中の CPU_STATS_ADDQ(cp, sys, pswitch, 1); や swtch_from_zombie() 関数の中の CPU_STATS_ADDQ(CPU, sys, pswitch, 1); で更新されています。

us

us はユーザモードで使用した CPU 時間の割合です。

us の値は kstat の cpu::sys:cpu_ticks_user から取られています。"kstat -p 'cpu::sys:cpu_ticks_user' 1" で CPU 毎の us の値を取得出来ます。kstat の値は累積です。

kstat の cpu::sys:cpu_ticks_user は /usr/src/uts/common/os/cpu.c の cpu_sys_stats_ks_update() 関数の中で cpu::sys:nsec_user の値から計算されています。cpu::sys:nsec_user の値は /usr/src/uts/i86pc/os/machdep.c (x86) や /usr/src/uts/sun4/os/machdep.c (SPARC) の中の get_cpu_mstate() 関数の中で計算されています。

sy

cpu の下に表示される sy はカーネルサービスやシステムコールなど、システムモードで使用した CPU 時間の割合です。

sy の値は kstat の cpu::sys:cpu_ticks_kernel から取られています。"kstat -p 'cpu::sys:cpu_ticks_kernel' 1" を実行すると CPU 毎の sy の値を取得する事が可能です。kstat の値は累積です。

kstat の cpu::sys:cpu_ticks_kernel は /usr/src/uts/common/os/cpu.c の cpu_sys_stats_ks_update() 関数の中で cpu::sys:cpu_nsec_kernel から計算されています。cpu::sys:cpu_nsec_kernel の値は /usr/src/uts/i86pc/os/machdep.c (x86) や /usr/src/uts/sun4/os/machdep.c (SPARC) の中の get_cpu_mstate() 関数の中で計算されています。

id

id は CPU が使用されていなかった時間の割合です。

id の値は kstat の cpu::sys:cpu_ticks_idle から取られています。"kstat -p 'cpu::sys:cpu_ticks_idle' 1" を実行する事で CPU 毎の id の値を取得する事が可能です。kstat の値は累積です。

kstat の cpu::sys:cpu_ticks_idle は /usr/src/uts/common/os/cpu.c の cpu_sys_stats_ks_update() 関数の中で cpu::sys:cpu_nsec_idle から計算されています。cpu::sys:cpu_nsec_idle の値は /usr/src/uts/i86pc/os/machdep.c (x86) や /usr/src/uts/sun4/os/machdep.c (SPARC) の中の get_cpu_mstate() 関数の中で計算されています。

epi

epi(executable page-ins) は実行ファイルかライブラリであると思われるデータがページインしたページ数です。具体的には VVMEXEC フラグが立っているページをカウントしています。

epi の値は kstat の cpu::vm:execpgin から取られています。"kstat -p 'cpu::vm:execpgin' 1" を実行する事で CPU 毎の epi の値を取得する事が可能です。kstat の値は累積値です。

kstat の cpu::vm:execpgin の値は /src/uts/common/os/bio.c の pageio_setup() 関数の CPU_STATS_ADDQ(cpup, vm, execpgin, btopr(len)); で加算されています。

epo

epo(executable page-outs) は VVMEXEC フラグが立っているメモリがページアウトしたページ数です。

epo の値は kstat の cpu::vm:execpgout から取られています。"kstat -p 'cpu::vm:execpgout' 1" を実行する事で CPU 毎の epo を取得する事が可能です。kstat の値は累積です。

kstat の cpu::vm:execpgout の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の中の CPU_STATS_ADDQ(cpup, vm, execpgout, execpgout); で加算されています。

epf

epf(executable page-frees) は VVMEXEC フラグが立っているページが解放されたページ数です。

epf の値は kstat の cpu::vm:execfree から取られています。"kstat -p 'cpu::vm:execfree' 1" を実行する事で CPU 毎の epf の値を取得する事が可能です。kstat の値は累積値です。

kstat の cpu::vm:execfree の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数中の CPU_STATS_ADDQ(cpup, vm, execfree, execfree); や /usr/src/uts/common/os/vm_pageout.c の checkpage() 関数の中の CPU_STATS_ADD_K(vm, execfree, 1); で加算されています。

api

api(anonymous page-ins) は anonymous メモリのページインしたページ数です。

api の値は kstat の cpu::vm:anonpgin から取られています。"kstat -p 'cpu::vm:anonpgin' 1" を実行すると CPU 毎の anonpgin の値を取得する事が可能です。kstat の値は累積値です。

kstat の cpu::vm:anonpgin は /usr/src/uts/common/os/bio.c の pageio_setup() 関数の中で B_READ フラグと VISSWAPFS フラグが立っている場合に CPU_STATS_ADDQ(cpup, vm, anonpgin, btopr(len)); で加算されています。

apo

apo は anonymous メモリがページアウトされたページ数です。

apo の値は kstat の cpu::vm:anonpgout から取られています。"kstat -p 'cpu::vm:anonpgout' 1" を実行すると CPU 毎の apo の値を取得する事が可能です。kstat の値は累積値です。

kstat の cpu::vm:anonpgout の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の中で VISSWAPFS フラグが立っている場合に CPU_STATS_ADDQ(cpup, vm, anonpgout, anonpgout); で加算されています。

apf

apf は anonymous メモリが解放されたページ数です。

apf の値は kstat の cpu::vm:anonfree から取られています。"kstat -p 'cpu::vm:anonfree' 1" を実行すると CPU 毎の apf の値が取得出来ます。kstat の値は累積値です。

kstat の cpu::vm:anonfree の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の中で VISSWAPFS フラグが立っている場合に CPU_STATS_ADDQ(cpup, vm, anonfree, anonfree); で加算されています。また /usr/src/uts/common/os/vm_pageout.c の checkpage() 関数の中の CPU_STATS_ADD_K(vm, anonfree, 1); でも加算されています。

fpi

fpi はファイルシステムページのページインしたページ数です。

fpi の値は kstat の cpu::vm:fspgin から取られています。"kstat -p 'cpu::vm:fspgin' 1" を実行すると CPU 毎の fpi の値を取得する事が可能です。

  • kstat の cpu::vm:fspgin の値は /usr/src/uts/common/os/bio.c の pageio_setup() 関数の中の CPU_STATS_ADDQ(cpup, vm, fspgin, btopr(len)); で加算されています。

fpo

fpo はファイルシステムページのページアウトしたページ数です。

fpo の値は kstat の cpu::vm:fspgout から取られています。"kstat -p 'cpu::vm:fspgout' 1" を実行すると CPU 毎の fpo の値を取得する事が可能です。kstat の値は累積値です。

kstat の cpu::vm:fspgout の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の CPU_STATS_ADDQ(cpup, vm, fspgout, fspgout); で加算されています。

fpf

fpf はファイルシステムページの解放されたページ数です。

fpf の値は kstat の cpu::vm:fsfree から取られています。"kstat -p 'cpu::vm:fsfree' 1" を実行すると CPU 毎の fpf の値を取得する事が出来ます。kstat の値は累積値です。

kstat の cpu::vm:fsfree の値は /usr/src/uts/common/vm/vm_pvn.c の pvn_write_done() 関数の中の CPU_STATS_ADDQ(cpup, vm, fsfree, fsfree); や /usr/src/uts/common/os/vm_pageout.c の checkpage() 関数の中の CPU_STATS_ADD_K(vm, fsfree, 1); で加算されています。

vmstat のソースコード

/usr/src/cmd/stat/vmstat/vmstat.c

vmstat のソースコードは 500 行程度と非常に短く、簡単に読む事が出来ます。何故これほど短いかというと、vmstat コマンドが行っているのはカーネル内に蓄積された統計情報を取得して整形しているだけだからです。カーネルから情報を取得する部分はライブラリ化されており、幾つかの関数を呼び出すだけで簡単に必要なデータを入手する事が出来ます。このライブラリは libkstat という名前で、どんなプログラムからも使用する事が可能です。libkstat を使えば vmstat に限らず、カーネルの統計情報を処理するプログラムを簡単に作成出来ます。libkstat の使い方は http://blogs.sun.com/solairo/entry/libkstat にまとめてありますので、宜しければご参照下さい。NIC の統計情報を読み出すコマンドを作る例を元に解説しています。

終わりに

vmstat の各カラムの意味を解説しました。vmstat は Solaris の性能解析やトラブルシュートを行う際に最も基本的なコマンドです。是非使いこなして下さい。また、vmstat が kstat の情報を使用している事をご紹介しました。kstat は vmstat に限らず、mpstat や iostat でも使用されています。kstat コマンドも libkstat も使用方法は非常に簡単です。こちらも是非お試し下さい。

参考文献

http://blogs.sun.com/yappri/date/20090311 2009年 3月 11日 水曜日

なぜ URL がやっぷり(yappri)なのか?

先日、「やっぱり Sun がスキ!」ブログ創設3周年を祝ってメンバで飲み会を 行いました。そこにはきみまささん(きみまさブログ - kimimasa's blog)もゲスト参加して頂き、みんなで 盛り上がりました。

勢い余って"やっぱり"焼酎を 2 升飲み干し、 時間制で無いことを良いことに"やっぱり"5時間同じ店に居座り続けて、 エンジニアが集まれば"やっぱり"技術の話で盛り上がり  (今回の例: bash/zsh/tcsh/ksh 結局どれにどんな利点が?)、 案の定"やっぱり"幹事は酔いどれとなり会計を放棄してしまい、 それでも"やっぱり"先輩方にはお金を多く出して頂き、 その日の飲み会は無事にお開きになりました。

次の日、きみまさブログを読んでいるとこんな無茶ぶりが。。。 無茶ぶりされたら答えねば!!

TIPS ということで、なぜこの「やっぱり Sun がスキ!」のブログの URL が「やっぱり(yappari)」 ではなく、「やっぷり(yappri)」と なっているか、今まで謎のベールに 包まれていた 「やっぷり(yappri)」な秘密! 裏話をお聞かせしましょう。

そもそもの始まりは、初期メンバーの一人が「やっぱり Sun がスキ!」という "素敵なネーミング"を提案し、ブログ初期設定時に URL を「やっぷり(yappri)」で 作成したのです。 ブログを作った方が、石橋を叩いてチェックする様な、普段の仕事は いろいろ深くまで考えて作るタイプの方だったので、 自分を含め周りも「ちょっと綴りが違う気がするけど、この人がこう書いているのだから 意味があるに違いない。つっこまないでおこう・・・」とそのまま公開。 ・・・・

後日 その方に「どうして "やっぷり(yappri)" にしたのですか?」 と 尋ねてみたら なんと理由は
タ・イ・ポでした!

しかし、この"タイポ"。思わぬ利点がありまして、 自分たちのブログがどこからリンクされているかを探す場合に 検索結果が絞れるので非常に便利!!

  • yappri の検索結果 約 2,380 件
  • yappari の検索結果 約 95,100 件

おおー、「やっぷり(yappri)」にすると結果が 2.5% にまで減りました。 少量の方が探しやすいので重宝してます。まさに瓢箪から駒。

以上、気になる裏話でした。