2009年 10月 28日 水曜日
やっぱり Sun がスキ!
Calendar Server 7 を iPhone から使ってみよう
サンは今年9月末にCommunications Suite 7 を新しく発表しました。
今回は、その Communications Suite 7 に含まれる新しい CalDAV 対応カレンダサーバである Calendar Server 7 をインストール・設定し、iPhone, Thunderbird Lightining から利用してみましょう。
Calendar Server 7 のインストールシナリオを確認すると、カレンダサーバのインストールには下記の手順が必要になります。
- Directory Server のインストール
- GlassFish Enterprise Server 2.1 のインストール
- Calendar Server と MySQL のインストール
- MySQL の設定
- Calendar Server の設定
また、Calendar Server のユーザ管理には Delegated Administrator が使えます。
Delegated Administrator では、Access Manager を利用する Schema 2 を利用する構成方法と、Access Manager を使わず Directory Server だけで利用できる Schema 1 を利用する構成方法があります。
今回は単純に Calendar Server のみ使えれば良いので、Scheme 1 を利用する設定にて Delegated Administrator をインストールしましょう。
- ソフトウェアの入手
- Directory Server のインストール
- GlassFish Enterprise Server 2.1 のインストール
- Delegated Administrator のインストール
- Calendar Server と MySQL のインストール
- MySQL の設定
- Calendar Server の設定
- カレンダユーザの作成
- iPhone からの設定
- Thunderbird Lightning からの設定
1. ソフトウェアの入手
まずは、入手先より Communications Suite 7, GlassFish Enterprise Server 2.1 Patch 02, Directory Server 6.3.1 をダウンロードします。
sw-79# pwd /var/tmp/Comm7 sw-79# ls 126748-05.zip ci-7.0-0.02-SunOS_sparc.zip DSEE.6.3.Solaris-Sparc-full.tar.gz sges_ee-2_1-p02-solaris-sparc.bin sw-79#
2. Directory Server のインストール
Direcotry Server は、Communications Suite 7 Installation Scenario - Directory Server に沿って、インストールします。
3. GlassFish Enterprise Server 2.1 のインストール
GlassFish も同様に、Communications Suite 7 Installation Scenario - GlassFish Enterprise Server に沿って、インストールします。
JDK6 がインストールされていない場合は、入手先よりパッケージをダウンロードしてドキュメントを参考にインストールしてください。
4. Delegated Administrator のインストール・設定
Delegated Administrator は、Direct LDAP モードで設定するので、下記のログを参考にインストールしてください。
インストール・設定が完了したら http://hostname:8080/da にて管理画面にログインできます。
5. Calendar Server と MySQL のインストール
6. MySQL の設定
7. Calendar Server の設定
8. カレンダユーザの作成
DAの管理画面(http://hostname:8080/da)より、サービスパッケージを割り当ててユーザを作成しましょう。
まず、組織にサービスパッケージを割り当てます。
次に、サービスパッケージを割り当てたユーザを作成します。
9. iPhone からの設定
※ クライアント設定はこのドキュメントが参考になります。
設定 -> メール -> アカウントを追加を選びます。

その他を選びます。

CalDAV アカウントを追加を選びます。

サーバ欄にアカウント URL を設定・ユーザ名とパスワードを設定します。
※ 今回のテストではアカウント URL は、http://sw-79.japan.sun.com:8080/davserver/dav/principals/japan.sun.com/test1/ になります。


サーバ欄には、URL では無く、サーバ名が表示されます。

詳細設定を確認すると、ポート番号と URL が入力されている事を確認できます。

カレンダアプリを起動するとサーバが追加されていることが確認できます。

テストの予定を追加してみましょう。


10. Thunderbird Lightning からの設定
※ クライアント設定はこのドキュメントが参考になります。
Lightning から新しいカレンダを登録します。
CalDAV を選んで、URL を入力します。
※ 今回のテストではアカウント URL は、http://sw-79.japan.sun.com:8080/davserver/dav/home/test1@japan.sun.com/calendar になります。
設定を終えると、ユーザ名とパスワードを入力するウィンドウが開きます。
ただしく、ログインできると iPhone から入力したテストの予定が確認できます。
まとめ
以上で設定は終了です。
このように、新しいカレンダサーバは標準規格である CalDAV をサポートしているため、今回設定した iPhone, Lightning のほかにも Apple の iCal など多様なクライアントから利用可能です。
ぜひ新しい、カレンダサーバをお試し下さい!
Posted at 05:00午後 10 28, 2009 by Masayuki Imai in Sun | 投稿されたコメント[0]
User/Group単位で ZFS の quota を設定する方法
今回は、前回に引き続き Solaris 10 10/09(Update 8) でサポートされた ZFS 新機能の関連記事で、ZFS の quota 管理がユーザ/グループ単位で設定できる ようになりましたので紹介します。
今まで ZFS のファイルシステムに対する quota による容量制限は、 プール内のファイルシステム単位という制約があり、 管理者がユーザ/グループ単位で容量制限を行うには、ユーザ/グループ毎に それぞれファイルシステムを作成するしか方法がありませんでした。
しかし、この方法では多くのユーザがいる場合、ファイルシステムの数が多く なってしまい、管理の面であまり実現的ではありませんでした。
今までの quota 設定方法(ファイルシステム単位)
# zfs set quota=10g tank/home
今回、ユーザ/グループ単位で ZFS ファイルシステムの quota を設定できるように なりましたので、その手順を紹介します。
ユーザによる quota 設定方法
# zfs set userquota@user01=100m tank/home # zfs get userquota@user01 NAME PROPERTY VALUE SOURCE tank userquota@user01 none local tank/home userquota@user01 100M local
グループによる quota 設定方法
# zfs set groupquota@staff=500m tank/home # zfs get groupquota@staff NAME PROPERTY VALUE SOURCE tank groupquota@staff none local tank/home groupquota@staff 500M local
最後に、 quota 動作の確認として、ユーザ単位で quota 制限がかかって いるか mkfile を使って確認してみます。
今回は、上記で設定で user01 に 100MB の quota 制限を設定しましたので、 user01 で 150MB のファイルを作成してみます。
% /usr/ucb/whoami user01 % mkfile 150m /tank/home/aaa aaa: initialized 111108096 of 157286400 bytes: Disc quota exceeded
「ユーザ単位の quota 制限が発生しました」 とメッセージが出てこないのは 残念ですが、きちんとユーザ単位で quota 制限が設定されている事が確認できました。
(参考情報)
過去の 「やっぱり Sun がスキ!」blog 記事一覧はこちらを参照下さい。 http://wikis.sun.com/display/yappri/Home
Posted at 05:13午後 10 27, 2009 by Naoyuki Yamada in Sun | 投稿されたコメント[0]
Solaris 10 で ZFS の Hybrid Storage Pool を作る方法
今回は、今月リリースした Solaris 10 10/09(Update 8) でサポートされた ZFS の L2ARC(Level 2 Adaptive Replacement Cache) 設定方法を紹介します。
L2ARC とは、ZFS Hybrid Storage Pool の Read 用二次キャッシュとして機能 し、通常 SSD が使用され Read 速度の向上を促します。
今まで Solaris 10 で ZFS のプールをする場合、Write 速度の向上させる ZIL(ZFS Intent Log)は作成できましたが、L2ARC を作成する事ができませんでした。
(L2ARC を使用したい場合は OpenSolaris を選択するしかありませんでした。)
Solaris 10 が 10/09 になり、L2ARC がサポートされました ので、これで Solaris 10 上で完全な Hybrid Storage Pool を作成できるように なりました。
それでは早速 Hybrid Storage Pool を作ってみましょう。とっても簡単です。
作成方法は、ZFS pool 作成時のオプションに ZIL を log で指定、L2ARC を cache で指定するだけです。
(通常、log と cache のデバイスは SSD を使用します。)
# zpool create tank raidz c2t0d0 c2t1d0 c2t2d0 c2t3d0 log c2t4d0 cache c2t5d0
# zpool status
プール: tank
状態: ONLINE
スクラブ: 何も要求されませんでした
構成:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz1 ONLINE 0 0 0
c2t0d0 ONLINE 0 0 0
c2t1d0 ONLINE 0 0 0
c2t2d0 ONLINE 0 0 0
c2t3d0 ONLINE 0 0 0
logs
c2t4d0 ONLINE 0 0 0
cache
c2t5d0 ONLINE 0 0 0
エラー: 既知のデータエラーはありません
はい、これで Hybrid Storage Pool が作成できました。logs(ZIL) と cache(L2ARC) にデバイスが 割り当てられております。
ちなみに、ZIL をミラーしたい場合は以下のように指定します。
# zpool create tank raidz c2t0d0 c2t1d0 c2t2d0 c2t3d0 log mirror c2t4d0 c2t5d0
# zpool status
プール: tank
状態: ONLINE
スクラブ: 何も要求されませんでした
構成:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz1 ONLINE 0 0 0
c2t0d0 ONLINE 0 0 0
c2t1d0 ONLINE 0 0 0
c2t2d0 ONLINE 0 0 0
c2t3d0 ONLINE 0 0 0
logs
mirror ONLINE 0 0 0
c2t4d0 ONLINE 0 0 0
c2t5d0 ONLINE 0 0 0
エラー: 既知のデータエラーはありません
L2ARC に SSD を使用する事により、 DRAM だけでキャッシュを構築する場合と比較して 大容量で低価格な構成を提案できるようになります。
Read が多い NFS サーバには最適ですね。
(参考情報)
過去の 「やっぱり Sun がスキ!」blog 記事一覧はこちらを参照下さい。 http://wikis.sun.com/display/yappri/Home
Posted at 05:12午後 10 26, 2009 by Naoyuki Yamada in Sun | 投稿されたコメント[1]
OpenSolaris 2009.06 で Zone を作成する
今回は、OpenSolaris 2009.06 で Solarisコンテナを作成する手順を纏めてみましたので 紹介します。
今まで、「やっぱり Sun がスキ!」ブログでは、Solaris 10 ベースの Solarisコンテナに 関する TIPS をいろいろ紹介して来ましたが、OpenSolaris 2009.06 では Solaris 10 と 少し変わっていますので、Solaris 10 との違いを中心に説明していきます。
ステップ1 zonepath 用のディレクトリを作成する
Zone 作成時に一番重要なプロパティは zonepath ですが、Solaris 10 の ように適当なディレクトリを mkdir で作成して zonepath に設定してはいけません。OpenSolaris 2009.06 では、zonepath に ZFS のデータセット名を指定する 必要があります。例えば、zonepath に /rpool/zones/test-zone と指定したい 場合は、あらかじめ下記の設定が必要になります。
# zfs create rpool/zones # zfs create rpool/zones/test-zone # chmod 700 /rpool/zones/test-zone
ステップ2 Zone の作成を行う
次に zonecfg で Zone名 test-zone の作成を行います。# zonecfg -z test-zone test-zone: No such zone configured Use 'create' to begin configuring a new zone. zonecfg:test-zone> create zonecfg:test-zone> set zonepath=/rpool/zones/test-zone
ここで設定値を確認してみます。
zonecfg:test-zone> info zonename: test-zone zonepath: /rpool/zones/test-zone brand: ipkg autoboot: false bootargs: pool: limitpriv: scheduling-class: ip-type: shared hostid:
info の出力結果で注目する箇所は、Solaris 10 と違いブランド名が native でなく ipkg 形式に なっている事です。従いまして、inherit-pkg-dir のプロパティも無くなっています。
zonecfg の設定を保存した後、zone の状態を確認してみます。
# zoneadm list -cv ID NAME STATUS PATH BRAND IP 0 global running / native shared - test-zone configured /rpool/zones/test-zone ipkg sharedtest-zone のブランドが native でなく ipkg になっています。
ステップ3 Zone のインストールを行う
Zone の作成が完了しましたので、インストールを行います。
# zoneadm -z test-zone install
Publisher: Using opensolaris.org (http://pkg.opensolaris.org/release/).
Image: Preparing at /rpool/zones/test-zone/root.
Sanity Check: Looking for 'entire' incorporation.
Installing: Core System (output follows)
DOWNLOAD PKGS FILES XFER (MB)
Completed 20/20 3021/3021 42.55/42.55
PHASE ACTIONS
Install Phase 5747/5747
Installing: Additional Packages (output follows)
DOWNLOAD PKGS FILES XFER (MB)
Completed 37/37 5598/5598 32.52/32.52
PHASE ACTIONS
Install Phase 7329/7329
Note: Man pages can be obtained by installing SUNWman
Postinstall: Copying SMF seed repository ... done.
Postinstall: Applying workarounds.
Done: Installation completed in 1075.241 seconds.
Next Steps: Boot the zone, then log into the zone console
(zlogin -C) to complete the configuration process
Zone のインストールを実行すると、パッケージのリポジトリからパッケージのダウンロードが開始されます。そして、ログにはインストールにかかった時間が表示されるようになりました。
インストールが完了すれば、後は Solaris 10 と同様に Zone をブートして使用可能になります。
# zoneadm -z test-zone boot # zlogin -C test-zone
おまけ Zone のクローンを作成する
せっかく zonepath が ZFS ベースなので、Solarisコンテナのクローン機能が ZFS のクローンと 連携出来ているか確認してみました。# zoneadm -z test-zone halt # zonecfg -z test-zone export -f /var/tmp/clone-zone.cfgexport したファイル内の zonepath を /rpool/zones/test-zone から /rpool/zones/clone-zone に 変更します。
# zonecfg -z clone-zone -f /var/tmp/clone-zone.cfg # zoneadm -z clone-zone clone test-zone sys-unconfig started 2009年09月27日 01時29分53秒 rm: cannot remove `/rpool/zones/clone-zone/root/etc/vfstab.sys-u': No such file or directory grep: /rpool/zones/clone-zone/root/etc/dumpadm.conf: No such file or directory sys-unconfig completed Sun Sep 27 01:29:53 2009Zone のクローン作成は、即時に作成できましたので ZFS のクローンときちんと連携できているようです。
ZFS の状態を確認してみます。
# zfs list -t snapshot NAME USED AVAIL REFER MOUNTPOINT rpool/ROOT/opensolaris@install 146M - 2.82G - rpool/zones/test-zone/ROOT/zbe@clone-zone_snap 0 - 341M - # zfs get origin | grep clone rpool/zones/clone-zone origin - - rpool/zones/clone-zone/ROOT origin - - rpool/zones/clone-zone/ROOT/zbe origin rpool/zones/test-zone/ROOT/zbe@clone-zone_snap - rpool/zones/test-zone/ROOT/zbe@clone-zone_snap origin -
Zone と ZFS の連携って素敵です!
Posted at 09:51午後 9 28, 2009 by Naoyuki Yamada in Sun | 投稿されたコメント[0]
DTrace を使ってロックの競合を調査する
はじめに
今回は DTrace を使用してロックの競合を調査する初歩的な手順をご紹介したいと思います。DTrace には豊富なプローブが用意されていますので、アイデアさえあれば無限にスクリプトを作成することが可能です。その全てを解説することは難しいですが、DTrace を使ってマルチスレッドプログラムの動きを調べる際の基礎となるスクリプトを幾つかご紹介したいと思います。
plockstat コマンドの実装から
先日ご紹介した plockstat コマンド はその機能の殆どを DTrace を利用して実装しています。OpenSolaris.org にある plockstat コマンドの ソースコード を見てみると、1000 行ほどのコードの内の 300 行ほどが DTrace スクリプトの定義で、残りはヘルパー関数になっています。実は、この plockstat コマンドに含まれている DTrace スクリプトは plockstat コマンドと独立して使用することも可能です。まず始めに、その使い方から見ていきましょう。
mutex ロックの競合を調査する DTrace スクリプト
plockstat コマンドのソースコードから mutex ロックの競合を検知している部分を抜き出して、単独で実行できる様に修正したのが下記のスクリプトです。plockstat$target::: で始まるプローブが並んでいますが、plockstat コマンドに含まれるスクリプトは DTrace の plockstat プロバイダの機能を利用しています。plockstat プロバイダは mutex ロックと reader/writer ロックを監視する為の DTrace のプロバイダです。plockstat コマンドは plockstat プロバイダの機能を全面的に使用しているため、plockstat コマンドは plockstat プロバイダのラッパーと言って良いかもしれません。続いて個々のプローブを見ていきましょう。plockstat$target:::mutex-block はスレッドが mutex ロックでブロックされる直前に呼び出されるプローブです。一方 plockstat$target:::mutex-blocked はブロックから解放された直後に呼び出されますので、mutex-block と mutex-blocked で timestamp の差分を取ると mutex ロックでブロックされていた時間を割り出す事が出来ます。なお、plockstat$target:::mutex-blocked の arg1 が 0 の場合は何らかのエラーで mutex ロックが取得できなかったことを意味するため、ブロックされていた時間には加算されていません。
#!/usr/sbin/dtrace -s
plockstat$target:::mutex-block
{
self->mtxblock[arg0] = timestamp;
}
plockstat$target:::mutex-blocked
/self->mtxblock[arg0] && arg1 != 0/ /* arg1 is not 0 => lock is acquired */
{
@mtx_block[arg0, ustack(5)] =
sum(timestamp - self->mtxblock[arg0]);
@mtx_block_count[arg0, ustack(5)] = count();
self->mtxblock[arg0] = 0;
mtx_block_found = 1;
}
plockstat$target:::mutex-blocked
/self->mtxblock[arg0]/ /* arg1 is 0 => error */
{
self->mtxblock[arg0] = 0;
}
END
/mtx_block_found/
{
trace("Mutex block");
printa(@mtx_block, @mtx_block_count);
}
実際に動かしてみる
このスクリプトを先日の plockstat の記事 で使用したテストプログラムに対して実行してみた結果が以下の出力です。上から、"134614312" が plockstat コマンドの "Lock" のカラムに相当する mutex ロックのアドレス、次のスタックフレームが "Caller" のカラムを作成する為のデータです。"30002403544" は mutex ロックでブロックされていた総時間です。最後の "3" は plockstat コマンドの "Count" のカラムに相当するブロックされた回数です。先ほどの総時間をブロックされた回数で割ると、ブロックされた平均時間となり plockstat コマンドの "nsec" のカラムが求まります (30002403544 nsec / 3 Count = 10000801181 nsec)。きちんと plockstat コマンドに相当する情報が得られている事が分かります。
# ./plockstat_mb.d -c ./mutex_test <-- トレース対象のプログラムは -c オプションで指定します
dtrace: script './plockstat_mb.d' matched 7 probes
done
done
done
dtrace: pid 9964 has exited
CPU ID FUNCTION:NAME
1 2 :END Mutex block
134614312 <-- "Lock"
libc.so.1`mutex_lock_queue+0x24a
libc.so.1`mutex_lock_impl+0x102
libc.so.1`mutex_lock+0x1a
mutex_test`func+0x13 <-- "Caller"
libc.so.1`_thr_setup+0x4e
30002403544 3 <-- "Count"
~~~~~~~~~~~ total time blocked
スレッドの毎に統計情報をまとめるスクリプト
先ほどのスクリプトを少しだけ書き換えて、ブロックされていた時間をスレッド毎に集計するスクリプトを作ってみました。下記のスクリプトを実行すると、プロセスを 10 秒間監視し、ブロックが発生した回数とブロックされていた時間をスレッド単位で出力します。先ほどのスクリプトからの変更点は、@mtx_block, @mtx_block_count 集積体のキーに tid を使用して、スレッド ID 毎に情報を集計しています。また、ブロックされた時間を保持していた self->mtxblock はスレッド毎に一つの値だけを保持すれば良いので、単純なスレッド固有変数にしてあります。tick-1sec は DTrace の profile プロバイダのプローブで、1 秒毎に呼び出されます。ここでは 10 秒間を数えるのに使用しています。
#!/usr/sbin/dtrace -qs
int ntick;
BEGIN
{
ntick = 0;
}
plockstat$target:::mutex-block
{
self->mtxblock = timestamp;
}
plockstat$target:::mutex-blocked
/self->mtxblock && arg1 != 0/ /* arg1 is not 0 => lock is acquired */
{
@mtx_block[tid]= sum(timestamp - self->mtxblock);
@mtx_block_count[tid] = count();
self->mtxblock = 0;
}
plockstat$target:::mutex-blocked
/self->mtxblock/ /* arg1 is 0 => error */
{
self->mtxblock = 0;
}
tick-1sec
{
ntick += 1;
}
tick-1sec
/ntick == 10/
{
trace("Count");
printa(@mtx_block_count);
trace("nsec");
printa(@mtx_block);
exit(0);
}
DTrace スクリプトの実行結果
書き換えたスクリプトを plockstat コマンドの解説で使用した general.c で試してみます。Count 以下がブロックされた回数を表しており、nsec 以下がブロックされた時間を表しています。いずれも測定時間 10 秒辺りの結果です。Count の結果は、左側のカラムがスレッド ID、右側のカラムがブロックされた回数です。スレッド ID が 8 番のスレッドは 10 秒の間に 15197 回ブロックされていた事が分かります。nsec の結果も左のカラムはスレッド ID です。右側のカラムはナノ秒単位でブロックされていた総時間が出力されます。ここではスレッド ID 5 番のスレッドが 10 秒間のうち 5.8 秒間ブロックされていたことが見て取れます。
# ./plockstat_mbt.d -c ./general
Count
8 15197
2 15395
3 15397
7 15418
6 15480
4 15604
9 15633
5 16011
nsec
5 5849251426
6 5891593031
9 5904264724
4 5912264400
3 5953877535
2 5983468423
7 6004800234
8 6067032588
plockstat プロバイダでトレースできないケースへの対応
plockstat プロバイダはその名の通り mutex ロックと reader/writer ロックを監視対象としており、条件変数でブロックされている場合は監視する事が出来ません。マルチスレッドプログラムでは条件変数も良く利用されていますので、mutex ロックや reader/writer ロックと同様に監視できると便利です。
条件変数のテストプログラム
以下のテストプログラムでは、各スレッドは main() 関数の中で res がインクリメントされるまで条件変数でブロックされます。
/*
* cv_test.c : a test program for cv tracing.
* compile : cc cv_test.c -o cv_test
*/
#include <stdio.h>
#include <unistd.h>
#include <atomic.h>
#include <pthread.h>
void *func();
volatile uint_t res = 0;
pthread_mutex_t mp;
pthread_cond_t cv;
int main() {
pthread_t tid1, tid2;
pthread_mutex_init(&mp, NULL);
pthread_cond_init(&cv, NULL);
pthread_create(&tid1, NULL, func, NULL);
pthread_create(&tid2, NULL, func, NULL);
sleep(10);
atomic_inc_uint(&res);
pthread_mutex_lock(&mp);
pthread_cond_broadcast(&cv);
pthread_mutex_unlock(&mp);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_mutex_destroy(&mp);
pthread_cond_destroy(&cv);
exit(0);
}
void *func() {
pthread_mutex_lock(&mp);
while(res == 0) {
pthread_cond_wait(&cv, &mp);
}
puts("done");
pthread_mutex_unlock(&mp);
pthread_exit(0);
}
コンパイル
上記のテストプログラムを cv_test.c という名前で保存し、以下の様にコンパイルして下さい。
# gcc cv_test.c -o cv_test
prstat で調査する
prstat で見てみると LWPID 1 のスレッドがスリープ ("SLP") し、LWPID 2 と 3 のスレッドがロック待ち ("LCK") しているのが分かります。
# ./cv_test&; prstat -mL -p $!
PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID
10189 root 0.0 0.0 0.0 0.0 0.0 100 0.0 0.0 0 0 0 0 cv_test/3
10189 root 0.0 0.0 0.0 0.0 0.0 100 0.0 0.0 0 0 0 0 cv_test/2
10189 root 0.0 0.0 0.0 0.0 0.0 0.0 100 0.0 0 0 0 0 cv_test/1
plockstat で調査する
cv_test プログラムを plockstat コマンドと共に実行した結果が以下です。prstat コマンドではロック待ちをしていることが明らかに見て取れましたが、plockstat コマンドではロックの競合についての情報は一切出力されていません。
# plockstat -Cv ./cv_test plockstat: tracing enabled for pid 19839 done done plockstat: pid 19839 has exited
条件変数を調査する DTrace スクリプト
plockstat コマンドの代わりに以下の様な DTrace スクリプトを作成すれば条件変数を捕捉することが可能です。DTrace の pid プロバイダを使用して pthread_cond_wait() 関数の出入りを監視しています。同様に pthread_cond_timedwait() や pthread_cond_reltimedwait_np() についてスクリプトを作成すれば、汎用的に条件変数を監視することが可能です。
#!/usr/sbin/dtrace -s
pid$target::pthread_cond_wait:entry
{
self->start = timestamp;
self->addr = arg0;
}
pid$target::pthread_cond_wait:return
/self->start/
{
@time[tid,self->addr] = sum(timestamp - self->start);
@cnt[tid,self->addr] = count();
self->start = 0;
}
END
{
printf("¥n");
printf("¥n");
printf("tid¥tcv address¥ttime(nsec)¥n");
printa("%d¥t%p¥t¥t%@u¥n", @time);
printf("¥n");
printf("tid¥tcv address¥tcount¥n");
printa("%d¥t%p¥t¥t%@u¥n", @cnt);
}
DTrace スクリプトの実行結果
上記スクリプトを cv.d という名前で保存し、実行権限を付けて、以下の様に実行して下さい。結果を見ると、tid 2 のスレッドの time(nsec) が 10000060220 (=> 10 sec)、tid 3 のスレッドの time(nsec) が 10000693754 (=> 10 sec) なので、各スレッドがそれぞれ 10 秒程ずつ待たされている事が分かります。また、tid 2, tid 3 のスレッドの count が 1 なので、両スレッドとも 1 回ずつ pthread_cond_wait() で待たされていたことになります。
# chmod +x ./cv.d # ./cv.d -c ./cv_test <-- トレース対象のプログラムは -c オプションで指定します dtrace: script './cv.d' matched 3 probes done done dtrace: pid 19939 has exited CPU ID FUNCTION:NAME 6 2 :END tid cv address time(nsec) <-- pthread_cond_wait() で待った時間を条件変数とスレッド毎に集計 2 8060fb8 10000060220 3 8060fb8 10000693754 tid cv address count <-- pthread_cond_wait() で待った回数を条件変数とスレッド毎に集計 2 8060fb8 1 3 8060fb8 1
おわりに
以上、DTrace を使用してロックの競合を監視する基本的な方法をご紹介しました。ご覧頂きました通り、plockstat コマンドは DTrace の plockstat プロバイダを全面的に使用して実装されています。また、plockstat コマンドに含まれる DTrace スクリプトは DTrace のスクリプトとして単独でも使用可能であることも見て頂きました。更に、plockstat プロバイダでは捕捉できない条件変数のブロックを DTrace の pid プロバイダを使用したスクリプトで監視する方法もご紹介しました。DTrace にはここで紹介した以外にも proc プロバイダの lwp-create, lwp-start, lwp-exit と言ったプローブや、mutex_owned(), rw_write_held() 等のサブルーチンが備わっており、マルチスレッドプログラムの解析には非常に有用なツールです。是非ご活用下さい。
関連文書
マニュアル
plockstat プロバイダのマニュアル
- http://docs.sun.com/app/docs/doc/819-0395/chp-plockstat
- http://docs.sun.com/app/docs/doc/817-6223/chp-plockstat
『マルチスレッドのプログラミング』
ソースコード
plockstat コマンドのソースコード
- http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/plockstat/plockstat.c
- 61-351 行目が DTrace のスクリプトになっています
plockstat プロバイダのソースコード
- http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/threads/plockstat.d
- http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/threads/synch.c
- "DTRACE_PROBE1(plockstat, mutex__block, mp)" と "DTRACE_PROBE2(plockstat, mutex__blocked, mp, X)" が mutex ロックの競合をトレースしている箇所です
DTrace の解説
Posted at 11:45午前 9 18, 2009 by Daisuke Homma in Sun | 投稿されたコメント[0]
plockstat コマンドでロックの競合を調べる
はじめに
今回は Solaris の plockstat(1M) コマンドを使ってユーザプロセスのロックの競合を解析する方法をご紹介したいと思います。大規模 SMP マシンや CMT マシンで長く運用されて来た歴史柄、Solaris は CPU スケーラビリティに非常に気を使っている OS です。カーネルサービスがスケールするだけでなく、ユーザプロセスの処理の並列度が十分に上がらない場合の分析ツールも揃っています。今回紹介する plockstat もそういったツールの一つで、プロセス内のロックを解析する為のコマンドです。plockstat コマンドを使うことで、プロセス内のロックの取得と競合の回数や原因を調査する事が可能です。
plockstat の 'p' はプロセスの 'p' なので私は「ぴーろっくすたっと」と読んでいますが、'p' が付かない lockstat というコマンドもあり、こちらはカーネル内のロックを観測するコマンドです。どちらもベンチマークやトラブルシューティングでは非常に良く使用するコマンドですので、是非ご活用頂ければと思います。
plockstat コマンドについて
plockstat コマンドを使用すると、プロセス内のロックの『取得』と『競合』の発生を監視できます。ロックの取得では、1) 取得されたロックのアドレス、2) プログラムのどの部分からロックが取得されたか、3) そのロックが取得された回数、4) そのロックが解放されるまでの平均時間、を見る事が出来ます。一方ロックの競合は、1) 競合が発生しているロックのアドレス、2) プログラムのどの部分がロックの競合を発生させているか、3) そのロックで何回競合が発生したか、4) そのロックでブロックされていた平均時間、を見る事が出来ます。特にロックの競合(あるスレッドが保持しているロックを別のスレッドが取得しようとすること)はプログラムの実行性能に直結する、とても重要な要素です。その為、今回の記事ではロックの競合に重点を置いて見て行きたいと思います。
なお、plockstat コマンドで観察できるロックの種類は mutex ロックと reader/writer ロックです。ロックの競合は『コンテンション』と呼ばれる場合もあります。ロックの競合が発生して待たされている状態を『ロック待ち』と呼んだり、『(スレッドがロックで)ブロックされている』と表現する事があります。
plockstat コマンドの使い方
plockstat コマンドを使用する前に
plockstat はプロセス内のロックを観察するコマンドです。plockstat コマンドを使用する前にどのプロセスでロックの競合が発生しているかを確認しておく必要があります。ロックの競合が発生しているプロセスは prstat(1M) コマンドで探す事が出来ます。prstat コマンドには "-mL 1" オプションを付けて実行して下さい。"-m" オプションがロック待ちを検出する為のオプションです。prstat コマンドの出力の "LCK" のカラムがロックの競合で待たされている時間で、単位は % です。スレッド数やアプリケーションの実装にもよりますが、この値が定常的に高い値を示していたらロックの競合を気にした方が良いかもしれません。LCK が高くなっているプロセスを見つけたら、プロセス名とプロセス ID を調べてください。LCK の値が高くなっている行の "PROCESS" が該当プロセスのプロセス名、"PID" がプロセス ID、"LWPID" がスレッド ID です。
以下は prstat コマンドを実行した例です。ここでは "general" というプロセスのスレッド ID 2 番から 9 番のスレッドで約 50% のロック待ちが発生しています。
# prstat -mL 1
PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID
20904 root 48 4.0 0.0 0.0 0.0 47 0.0 1.1 3K 6 7K 0 general/6
20904 root 45 3.8 0.0 0.0 0.0 50 0.0 1.1 3K 20 7K 0 general/5
20904 root 45 3.9 0.0 0.0 0.0 50 0.0 1.2 3K 28 7K 0 general/3
20904 root 45 3.8 0.0 0.0 0.0 50 0.0 1.2 3K 32 7K 0 general/7
20904 root 45 3.8 0.0 0.0 0.0 51 0.0 1.2 3K 18 7K 0 general/2
20904 root 44 3.8 0.0 0.0 0.0 51 0.0 1.2 3K 12 6K 0 general/8
20904 root 44 3.7 0.0 0.0 0.0 51 0.0 1.2 3K 11 7K 0 general/4
20904 root 44 3.8 0.0 0.0 0.0 51 0.0 1.2 3K 12 7K 0 general/9
20903 root 0.1 0.2 0.0 0.0 0.0 0.0 100 0.0 52 0 365 0 prstat/1
prstat コマンドを実行しても "LCK" が出ていない場合はプロセスのロックの競合は問題ない可能性があります。他に問題が無いか検討してみてください。例えばカーネル内のロックが問題である場合は lockstat コマンドを試してみて下さい。また、"LCK" が出ていてもロックが最優先の課題では無い場合もあります。例えば vmstat コマンドで CPU の id が 0 の場合はたとえロックの競合を解消できたとしてもこれ以上は性能が上がらないかもしれません。その場合は CPU を追加する等の処置が必要です。どんな症状の時にロックが問題であるかの判別手順は、別の機会に改めてご紹介したいと思います。
一般的な使い方
plockstat コマンドの基本的な使い方は "plockstat -Cve 5 -x bufsize=10k -x aggsize=2m -p <PID>" です。-C オプションはロックの競合の発生を調べる為の基本オプションです。-v オプションは verbose オプションで、トレースの開始を出力する為に付けています。-e <SEC> で plockstat コマンドを実行する時間を指定します。"-e 5" と指定すると 5 秒間計測します。計測が終わると plockstat コマンドは終了しますが、測定対象のプロセスはそのまま稼働を続けます。-e オプションを付け無い場合は、プログラムが終了するまでトレースを続けます。-x bufsize=<SIZE> -x aggsize=<SIZE> でコマンドの内部バッファを増やしています。このオプションが無くても問題の無いことが多いですが、取得する統計情報の量が大き過ぎて溢れてしまうことを予防する為に付けています。-p <PID> で解析対象のプロセスを指定します。<PID> には解析したいプロセスのプロセス ID を指定します。
# plockstat -Cve 5 -x bufsize=10k -x aggsize=2m -p <PID> ... -C は競合を調査 ... -v は冗長出力 ... -e <SEC> は plockstat コマンドの実行時間 ... -x bufsize=<SIZE> -x aggsize=<SIZE> は内部バッファの拡大 ... -p <PID> は調査対象のプロセスを指定
ロック発生時のスタックフレームを記録する
plockstat コマンドではロックが発生した際のスタックフレームを記録する事も出来ます。ロックに至るまでの関数コールの履歴を見ることで、ロックの発生原因を詳細に特定することが可能になります。スタックフレームの保存には -s <DEPTH> オプションを付けます。
plockstat -Cvs 5 -p <PID> ... -s <DEPTH> で保存するスタックの深さを指定
出力行数を制限したい場合は
出力行数が多すぎてログが見にくい場合は -n オプションを付けてください。
# plockstat -Cve 5 -n 10 -p <PID> ... -n オプションで出力する行数を制限
プログラム実行時に plockstat コマンドを使用する
plockstat コマンドの引数にプログラムを指定する事も出来ます。実行時間が短いプログラムや、プログラム開始時のロックを観測したい場合に便利です。<COMMAND> には調査したいコマンドを指定します。
# plockstat -Cv -x bufsize=10k -x aggsize=2m <COMMAND> ... コマンドの最後にプログラム名を指定すると、そのプログラムを実行
ロックの取得を観測する
ロックの競合ではなくロックの取得を監視したい場合は -H オプションを付けます。ロックの取得は競合に比べて発生頻度が高いため、plockstat コマンドの実行負荷が高くなる事があり、それがプログラムの実行に影響を与えてしまう事があります。注意して使用してください。
# plockstat -Hve 5 -p <PID> ... -H オプションでロックの『取得』を観測
全ての情報を一度に取得したい場合は…
ロックの競合と取得の両方を監視したい場合は -A オプションを付けます。-A オプションは -H オプション以上に実行負荷が高いので注意して使用してください。
# plockstat -Ave 5 -p <PID> ... -A オプションでロックの『取得』と『競合』の両方を観測
plockstat コマンドの使用例 その1
実際に plockstat コマンドを使用する例をテスト用のプログラムを使ってご覧頂きます。
mutex ロックのテストプログラム
以下のテストプログラムでは main() 関数を実行しているスレッドが mutex ロックを保持した状態で 10 秒間休眠し、それ以外のスレッドはその間ブロックされます。これが競合が発生している状態です。ロックの競合は main() のスレッドが停止している間 10 秒ほど続きます。main() のスレッドが mutex ロックを解放すると、ロックの競合は解消され、その他のスレッドがロックを取得します。各スレッドは "done" というメッセージを出力してプログラムは終了します。mutex を保持しながら sleep() したり、エラー処理を省いたりしておりますが、plockstat コマンドのテスト用に分かり易さを優先しました。ご了承下さい。
/*
* mutex_test.c : a test program for plockstat.
* compile : # cc mutex_test.c -o mutex_test
*/
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void *func();
pthread_mutex_t mp;
int main() {
pthread_t tid1, tid2, tid3;
pthread_mutex_init(&mp, NULL);
pthread_mutex_lock(&mp);
pthread_create(&tid1, NULL, func, NULL);
pthread_create(&tid2, NULL, func, NULL);
pthread_create(&tid3, NULL, func, NULL);
sleep(10); /* you should not do this. */
pthread_mutex_unlock(&mp);
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
pthread_join(tid3, NULL);
pthread_mutex_destroy(&mp);
exit(0);
}
void *func() {
pthread_mutex_lock(&mp);
puts("done");
pthread_mutex_unlock(&mp);
pthread_exit(0);
}
コンパイル
上記のテストプログラムを mutex_test.c というファイル名で保存し、以下の様にコンパイルして下さい。
# gcc mutex_test.c -o mutex_test
plockstat コマンドの実行
次の様に plockstat コマンドにテストプログラムを渡してください。
# plockstat -Cv ./mutex_test
実行結果とその見方
plockstat コマンドの実行結果は以下の様になります。一番最後の行が一番重要な行です。左から、ロックの競合が発生した回数 (Count)、競合が発生した時間の平均 (nsec)、競合したロックの名前またはアドレス (Lock)、ロックの競合が発生した関数 (Caller) を示しています。下記の例では mutex_test の実行中にロックの競合は 3 回発生しています。競合が発生してから解消されるまでの時間は平均 10 秒 (10000255945 nsec) で、競合が発生したロックは mutex_test プログラムの "mp" という変数、競合を発生させた関数は mutex_test プログラムの func() です。最後の +0x13 は func() 関数のエントリポイントから mutex_lock() までのオフセットです。以上、プログラムに記述した通りの出力が出ている事が分かります。
# plockstat -Cv ./mutex_test
plockstat: tracing enabled for pid 19830 <-- 冗長出力オプションによる出力
done <-- mutex_test プログラムによる出力
done <-- mutex_test プログラムによる出力
done <-- mutex_test プログラムによる出力
plockstat: pid 19830 has exited
Mutex block
Count nsec Lock Caller
-------------------------------------------------------------------------------
3 10000255945 mutex_test`mp mutex_test`func+0x13
plockstat コマンドの使用例 その2
次にプログラムの並列度に関する古典的な問題のひとつである、メモリ割り当ての並列実行について見てみたいと思います。これはヒープコンテンションとも呼ばれている問題で、Solaris では後述の mtmalloc ライブラリによって既に解決されています。
テストプログラム
メモリ割り当てのテストに使用するプログラムは OpenSolaris の配布物から流用します。general.c はマルチスレッドプログラムで並列に malloc() を呼び出すマイクロベンチマークです。まずは以下の様にコンパイルしてください。
# mkdir /var/tmp/malloc # cd /var/tmp/malloc # wget http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libmtmalloc/tests/general.c # gcc general.c -o general
prstat コマンドで調査する
まずは general プログラムの挙動を調べる為に prstat コマンドを使用します。prstat コマンドの -p オプションにプロセス ID を渡すと、そのプロセスだけの統計情報を見る事が出来ます。ここでは general プログラムのプロセス ID を渡しています。general プログラムは 8 つのスレッドを新たに作成し、それぞれのスレッドが 50% 前後の時間をロック待ちに費やしている事が分かります。
# ./general&; prstat -mLp $! 1
PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID
9838 root 48 4.1 0.0 0.0 0.0 47 0.0 1.1 3K 13 7K 0 general/9
9838 root 46 3.9 0.0 0.0 0.0 49 0.0 1.1 3K 3 7K 0 general/7
9838 root 45 3.9 0.0 0.0 0.0 50 0.0 1.2 3K 17 7K 0 general/2
9838 root 45 3.9 0.0 0.0 0.0 50 0.0 1.2 3K 9 7K 0 general/8
9838 root 45 3.9 0.0 0.0 0.0 50 0.0 1.2 3K 8 7K 0 general/6
9838 root 45 3.8 0.0 0.0 0.0 50 0.0 1.1 3K 6 7K 0 general/4
9838 root 43 3.7 0.0 0.0 0.0 52 0.0 1.2 3K 6 7K 0 general/5
9838 root 42 3.7 0.0 0.0 0.0 54 0.0 1.2 3K 9 6K 0 general/3
9838 root 0.0 0.0 0.0 0.0 0.0 0.0 100 0.0 0 0 0 0 general/1
なお、このプログラムを実行したマシンの CPU 数は 8 つで、general プログラム実行中も CPU リソースに空き (CPU の空き = vmstat コマンドの id) がある状態です。
# psrinfo 0 on-line since 09/03/2009 17:11:43 1 on-line since 09/03/2009 17:11:54 2 on-line since 09/03/2009 17:11:54 3 on-line since 09/03/2009 17:11:56 4 on-line since 09/08/2009 11:20:06 5 on-line since 09/08/2009 11:20:06 6 on-line since 09/08/2009 11:20:06 7 on-line since 09/08/2009 11:20:06 # vmstat 1 kthr memory page disk faults cpu r b w swap free re mf pi po fr de sr s0 s1 s2 s3 in sy cs us sy id 0 0 0 32014452 31721476 7 53 0 1 1 0 1 -0 0 -0 -0 468 568 577 0 0 100 0 0 0 31950536 31614640 20 6030 0 0 0 0 0 0 0 0 0 671 56769 51060 45 5 50 0 0 0 31926584 31590736 0 5955 0 0 0 0 0 0 0 0 0 561 56962 51203 45 5 50 0 0 0 31902764 31566916 0 5977 0 0 0 0 0 0 0 0 0 550 57824 52201 45 5 50 0 0 0 31878908 31543060 0 5943 0 0 0 0 0 0 0 0 0 606 57476 51873 45 5 50
plockstat コマンドで調査する
次に、prstat コマンドで見られたロック待ちの原因を plockstat コマンドで調べてみます。plockstat コマンドの出力から Lock のカラムを見てみると libc.so.1 の libc_malloc_lock で競合が発生している事が分かります。中段に "Mutex block" と書かれている様に、これは mutex ロックの競合です。また、 nsec と Count のカラムを見ると、平均 0.001 秒 (1033533 nsec) のロック待ちが約 6 千回発生していることが分かります。これはプロセス全体で 60 秒 (57903 count * 1033533 nsec = 59844661299 nsec => 60 sec) ほど待たされている計算になります。plockstat コマンドで測定していたのは 10 秒間ですが、スレッドが 9 つありますので、このプロセスの論理的な演算可能時間は 90 秒間です(CPU 数や他のプログラムの処理のことを考えると実質的な演算可能時間はもう少し少なくなります)。この演算可能な 90 秒のうち 60 秒は mutex のロックで待たされていると言うことになります。このプログラムはかなりの時間をロック待ちに費やしていると言って良いでしょう。
# plockstat -Cve 10 ./general
plockstat: tracing enabled for pid 9849
0
Mutex block
Count nsec Lock Caller
-------------------------------------------------------------------------------
57903 1033533 libc.so.1`libc_malloc_lock general`be_thread+0x70
スタックフレームを観察する
ロックの原因をもう少し特定するため、plockstat コマンドに -s オプションも付けてスタックフレームを見てみます。右下の "Stack" のカラムを見ると、general の be_thread() 関数のオフセット 0x70 から libc.so.1 の malloc() 関数が呼び出されており、malloc() から mutex_lock() が呼び出されている事が分かります。このロック待ちは malloc() 関数が原因であることが分かります。これがヒープコンテンションが発生している状態です。
# plockstat -Cve 10 -s 5 ./general
plockstat: tracing enabled for pid 9862
0
Mutex block
-------------------------------------------------------------------------------
Count nsec Lock Caller
60065 1434766 libc.so.1`libc_malloc_lock general`be_thread+0x70
nsec ---- Time Distribution --- count Stack
2048 | | 836 libc.so.1`mutex_lock_impl+0x102
4096 |@@@ | 9909 libc.so.1`mutex_lock+0x1a
8192 | | 2316 libc.so.1`malloc+0x29 <-- これ
16384 |@@ | 7215 general`be_thread+0x70
32768 |@@@@@@ | 16034
65536 | | 1837
131072 | | 1223
262144 |@ | 2702
524288 |@ | 4505
1048576 |@ | 3721
2097152 | | 2269
4194304 | | 2193
8388608 |@ | 3411
16777216 | | 1671
33554432 | | 219
67108864 | | 4
mtmalloc ライブラリ
このヒープコンテンションへの対策として、Solaris にはマルチスレッドプログラム用の mtmalloc ライブラリが用意されており、既に様々なアプリケーションで使用されています。mtmalloc の使用方法は、コンパイル時にライブラリをリンクするか、プログラム実行時に LD_PRELOAD で読み込みます。これにより malloc() 関数がマルチスレッドに最適化された malloc() に置き換わります。
mtmalloc を使用して計測
先ほどの general プログラムで mtmalloc を使用してみた所、mutex でブロックされる回数が大幅に減少しました。ロック待ちをしていた時間は、34 count * 1401746 nsec + 1 count * 15222 nsec = 47674586 => 0.047 秒です。また、Caller のカラムを見ると、先ほどあった libc の malloc() のロックが消えている事が分かります。
# LD_PRELOAD_32=/usr/lib/libmtmalloc.so.1 plockstat -Cv ./general
plockstat: tracing enabled for pid 20828
plockstat: pid 20828 has exited
Mutex block
Count nsec Lock Caller
-------------------------------------------------------------------------------
34 1401746 libc.so.1`__sbrk_lock libmtmalloc.so.1`morecore+0x81
1 15222 0xfefa2138 libmtmalloc.so.1`setup_caches+0x21
mtmalloc で処理性能が大幅にアップ
mtmalloc を使ったテストでは、元の libc の malloc() をした場合と比べるとプログラムの実行時間も大幅に減少しています。ptime コマンドで計測した所、だいたい 1/10 程度の時間で処理が終了している事が分かります。plockstat コマンドで入手した情報を元にロックの競合を解消することでアプリケーションの高速化を行う事が出来ました。
# ptime ./general real 27.474 <-- libc の malloc() を使用した場合の処理時間 user 1:19.758 sys 4.740 # LD_PRELOAD_32=/usr/lib/libmtmalloc.so.1 ptime ./general real 3.195 <-- mtmalloc を使用した場合の処理時間 user 24.022 sys 1.019
おわりに
以上、plockstat コマンドを使用してロックの競合を解析する手順をご紹介しました。plockstat コマンドに prstat コマンドや vmstat コマンドを組み合わせて使うことで、ロックの競合の原因やそのロックの競合がプログラム全体の処理性能にどれだけ影響を与えているかを調べることが出来ます。また、テストプログラムや malloc() の実験を通して、plockstat コマンドの実際の使い方と競合が発生していた場合の対処方法の一例をご覧頂きました。メニーコア時代への対策として、今回ご紹介した手順を是非ご活用下さい。
なお、今回ご紹介した plockstat コマンドは DTrace の仕組みがあれば実装可能です。実際、Mac OS X にも plockstat コマンドがバンドルされています。FreeBSD でも使えるかもしれません。plockstat コマンドはとても便利なツールですし、こうしてプログラムが動いている舞台裏を覗いてみるのはコーディングやサーバ運用の役に立ちます。Solaris 以外の環境でも是非お試し下さい。 次回の記事 では更に進んで、plockstat コマンドの実装と DTrace を使ってロックを解析する方法に付いて書いてみたいと思います。
参考文献
mtmalloc ライブラリのソースコード
malloc() の並列実行ベンチマーク
Posted at 11:15午前 9 17, 2009 by Daisuke Homma in Sun | 投稿されたコメント[0]
Sun Desktop Access Client (Sun Ray Soft Client)
- Sun Ray 1 Ultra-Thin Client
Sun Ray は、1999 年 8 月に発表された製品となり、専用ハードウェアとソフトウェアの組み合わせで構成されるシンクライアントシステムとなります。
クライアントとなる Sun Ray 端末には何も情報を持たず、サーバ上に全てのデータが存在する仕組みとなっていますので、ネットワークケーブル 1 本を接続するだけでデスクトップ環境を利用することが可能となります。
詳細については、下記の製品紹介をご覧ください。http://jp.sun.com/products/desktop/sunray/
- ついに実現するソフトウェアクライアント
専用のハードウェアが必要となる Sun Ray 環境ですが、現在テスト中の Sun Ray Software 5 では、それ以外にソフトウェアでの利用を実現することが可能となる Sun Ray Soft Client が実装されることになりました。
Sun Ray Soft Client は、Windows 上で動作するソフトウェアとなりますが、Windows が動作しているマシンであれば、Sun Ray クライアントとなることが可能となります。 よくやった。ついにやってくれた。
今回は、この Sun Ray Soft Client を紹介したいと思います。 - Sun Ray Software 5 EA1 の入手
Sun Ray Soft Client を利用するには、現在、Early Access として公開(フィードバックを得るためのテストリリース)されている Sun Ray Software 5 EA1 と Solaris 10 SPARC/x86 が動作するシステム(あるいは、Linux) が必要となります。
また、Sun Ray Soft Client を利用するには、Sun Ray Software 5 EA1 の機能が必要になるため、既に稼働している Sun Ray サーバを利用することができない点にご注意下さい。
下記 URL からソフトウェアおよびドキュメント類をダウンロードすることが可能です。Sun Ray Software 5 Information Center Sun Ray Software 5 EA1 program ※ Sun Ray Software 5 EA1 は、下記のソフトウェアで構成されています。 srss_4.2_solaris.zip (Sun Ray Server Software 4.2) setup.exe (Sun Ray Soft Client 1.0) srwc_2.2_solaris.zip (Sun Ray Connector for Windows Operating Systems 2.2) ※ srwc_2.2_solaris.zip は、必須ではありません。
まずは、これらを入手しインストールをおこないます。 - Sun Ray Software 5 EA1 のインストール
まずは、アーカイブを展開し、管理用 Web インターフェースを利用するために必要な Tomcat をインストールします。ファイルを展開し、所定のディレクトリに配置するだけです。
# pwd /var/tmp/install # unzip -q srss_4.2_solaris.zip # cd srss_4.2/Supplemental/Apache_Tomcat/ # /usr/sfw/bin/gtar zxvf apache-tomcat-5.5.20.tar.gz -C /opt # cd /opt # ln -s apache-tomcat-5.5.20 apache-tomcat
また、Java SE 6 が必要になります。幸い Sun Ray Server Software 4.2 のアーカイブに同梱されていますので、インストールされていない場合は、別途、インストールをおこなってください。srss_4.2/Supplemental/Java_Runtime_Environment/Solaris jre-6u13-solaris-i586.sh jre-6u13-solaris-sparc.sh
続いて、Sun Ray Server Software 本体のインストールをおこないます。 いくつか質問される箇所がありますので、確認しつつ作業を進めてください。# cd /var/tmp/install/srss_4.2 # ./utinstall : : Sun Ray Server Software 4.2 not installed Sun Ray Data Store 3.1 not installed Do you want to install Sun Ray Server Software 4.2 French Admin GUI (Y/[N]): Do you want to install Sun Ray Server Software 4.2 Japanese Admin GUI (Y/[N]): Y Do you want to install Sun Ray Server Software 4.2 Simplified Chinese Admin GUI (Y/[N]): Kiosk Mode 4.2 not installed Enter Java v1.6 (or later) location [/usr/java]: About to carry out the following operations: Install [ Sun Ray Server Software 4.2 ] Install [ Sun Ray Data Store 3.1 ] Install [ Sun Ray Server Software 4.2 Japanese Admin GUI ] Install [ Sun Ray Server Software 4.2 ] Install [ Kiosk Mode 4.2 ] Install [ Kiosk Mode 4.2 localized files ] Install [ data for utslaunch ] Install [ Sun Ray Server Software 4.2 modules for utsunmc ] Continue? ([Y]/N): : : Installation of Sun Ray Server Software has completed. The system must be rebooted in order to complete this installation and before starting the Sun Ray Server Software. Please check for errors/warnings in /var/adm/log/utinstall.2009_08_26_17:57:17.log +++ Done.以上、ソフトウェアのインストールは完了となります。 - Sun Ray Server Software の設定
ここでは、Sun Ray サーバとなるマシンおよび Sun Ray Soft Client を動作させるマシンが、192.168.77.0/24 のネットワークに接続される事を前提とします。
また、LAN 共有型 (Shared network) と呼ばれる、専用インターターコネクトを利用しない方法で設定をおこないます。
今回は、Sun Ray Software を利用することを目的としているため、なるべく簡単にセットアップするための手順を記載しています。
192.168.77.0/24 のネットワークに Sun Ray サービスを提供するには、下記のように設定し、Sun Ray サーバとなるマシンに設定された IP アドレスは、192.168.77.51 となります。
utadm コマンドにて共有ネットワークを利用する設定をおこないます。
# /opt/SUNWut/sbin/utadm -A 192.168.77.0 ### Configuring /etc/nsswitch.conf ### Configuring Service information for Sun Ray Selected values for subnetwork "192.168.77.0" net mask: 255.255.255.0 no IP addresses offered auth server list: 192.168.77.51 firmware server: 192.168.77.51 Accept as is? ([Y]/N): ### Configuring firmware version for Sun Ray All the units served by "macbook" on the 192.168.77.0 network interface, running firmware other than version "4.2_17_2009.06.24.11.48" will be upgraded at their next power-on. ### Configuring Sun Ray Logging Functions ### Turning on Sun Ray LAN connection NOTE: utrestart must be run before LAN connections will be allowed DHCP is not currently running, should I start it? ([Y]/N): Y続いて、サービスを提供するための設定を行います。# /opt/SUNWut/sbin/utconfig Configuration of Sun Ray Core Services Software This script automates the configuration of the Sun Ray Core Services software and related software products. Before proceeding, you should have read the Sun Ray Core Services 4.2 Installation Guide and filled out the Configuration Worksheet. This script will prompt you for the values you filled out on the Worksheet. For your convenience, default values (where applicable) are shown in brackets. Continue ([y]/n)? y Enter Sun Ray admin password: Re-enter Sun Ray admin password: Configure Sun Ray Web Administration? ([y]/n)? Enter Apache Tomcat installation directory [/opt/apache-tomcat]: Enter HTTP port number [1660]: Enable secure connections? ([y]/n)? Enter HTTPS port number [1661]: Enter Tomcat process username [utwww]: Enable remote server administration? (y/[n])? y Configure Sun Ray Kiosk Mode? (y/[n])? Configure this server for a failover group? (y/[n])? About to configure the following software products: Sun Ray Data Store 3.1 Hostname: macbook Sun Ray root entry: o=utdata Sun Ray root name: utdata Sun Ray utdata admin password: (not shown) SRDS 'rootdn': cn=admin,o=utdata Sun Ray Web Administration Apache Tomcat installation directory: /opt/apache-tomcat HTTP port number: 1660 HTTPS port number: 1661 Tomcat process username: utwww Remote server administration: Enabled Sun Ray Core Services 4.2 Failover group: no Sun Ray Kiosk Mode: no Continue ([y]/n)? : : Creating Sun Ray Core Services Configuration ... Adding user account for 'utwww' (ut admin web server user) ...done Sun Ray Web Administration enabled to start at system boot. Unique "/etc/opt/SUNWut/gmSignature" has been generated. Restarting Sun Ray Data Store ... Stopping Sun Ray Data Store daemon .Sun Ray Data Store daemon stopped Starting Sun Ray Data Store daemon . Wed Aug 26 18:25 : utdsd starting Adding user admin ... User(s) added successfully! *********************************************************** The current policy has been modified. You must restart the authentication manager to activate the changes. *********************************************************** Configuration of Sun Ray Core Services has completed. Please check the log file, /var/adm/log/utconfig.2009_08_26_19:21:56.log, for errors.再起動することで、Sun Ray Server Software の設定は完了です。 - Sun Ray Soft Client を利用するための設定
Firefox などの Web ブラウザから下記の URL にアクセスし、管理 GUI を呼び出します。
http://SunRayServer_IPaddress:1660/
ログインのユーザ名は、admin となり、パスワードは utconfig 実行時に設定したものとなります。
ログイン後、ブラウザ内に表示される「詳細」タブ -> 「システムポリシー」タブをクリックします。
表示され項目の中に「非カードユーザー」に関する設定項目がありますが、その中にある「Software client Access」の「使用可能」チェックボックスをオンにし、ブラウザ内右上にある「保存」ボタンをクリックすることで設定はが反映されサービスの再起動を促されますので指示に従いサービス再起動を行います。
以上で、Sun Ray サーバのセットアップは完了となります。
- Sun Ray Soft Client のインストール
Sun Ray Server をインストールしたマシンと同じネットワークに接続した Windows マシン上で作業を行います。
Sun Ray Soft Client は、Windows 用プログラムとなりますので、Windows 環境下で setup.exe を実行する必要がありますが、特に設定など必要なく通常の Windows アプリケーションと同様の扱い方で問題ありません。
インストール後は、「スタート」-> プログラム -> Sun Ray から起動することが可能となります。アイコンが味気なく、まだ、開発中であるということを感じさせます。
Sun Ray Soft Client を起動すると接続設定用のダイアログが表示されます。
まずは、接続だけを目的とするので、下記の項目を設定してください。
Connection タブ -> Automatically find server のチェックを外し Connect to Server: に Sun Ray Software を インストールしたマシンの IP アドレスを入力 します。 Display タブ -> Full Screesn のチェックボックスを外す ※ Full Screen において接続を解除する方法 は別途記載します。
上記の設定が完了したら、Connect ボタンをクリックしてください。
Sun Ray Server の設定に問題がなければ、接続を開始し、Solaris のログイン画面が表示されます。
- Sun Ray Soft Client の利用方法
利用については特別な注意事項は特にありませんが、制限事項などについては、付属のユーザガイドを参照してください。
Solaris にログインすることで、Solaris 環境を利用可能な他、Sun Ray Windwos connnector を Sun Ray server にインストールしていれば Windows への RDP 接続も可能です。
このスクリーンショットでは、Solaris 上で、VirtualBox を利用した Windows 7 Guest の中で Sun Ray Soft Client を起動し、さらにその中で Sun Ray Windows Connector を利用し Windows 7 のリモートデスクトップを表示しています。
そして、この環境、実は 1 台の Note PC で実現していたりします。
そして、こんなことも可能です・・・
6 つの Sun Ray Soft Client が起動しており、それぞれが別々のセッションとして利用可能です。
- セッションの終了およびフルスクリーンの解除方法
Sun Ray Soft Client で Solaris にログインした状態は、セッションとして管理されます。
セッションを終了させる場合は、Solaris 環境からログアウトしてください。セッションを継続させたまま、Sun Ray Soft Client を終了させる場合は、ウィンドウの × ボタンを押してください。
Sun Ray の特徴となりますが、サーバ上にセッションを保持できるためクライアントを終了してもログアウトさえしなければ、Sun Ray Soft Client を再起動するだけで即座に前回利用していたセッションを呼び出すことができます。
フルスクリーンを解除するには、一度、Sun Ray Soft Client を終了���る必要があります。
終了するには、下記のショートカットを入力します。左 Shift + Alt + Control
画面に Disconnect ダイアログが出力されますので、Confirm をクリックすることでクライアントを終了することができます。
こちらもセッションは保持されたままとなります。 - Sun Ray server のアンインストール
# /opt/SUNWut/sbin/utinstall -u # rm -fr /opt/apache-tomcat # rm -fr /opt/apache-tomcat-5.5.20 # pkgrm
アンインストール処理完了後、システムを再起動することで Sun Ray Server をアンインストールすることが可能です。 - 最後に Sun Ray Soft Client を含む、Sun Ray Software 5 は、現在のところ フィードバックを求める Early Access 版となるため、製品としてリリースされ るまでは、もう少し時間を要するかと思いますが、ぜひ、この機会に Sun Ray を体験してみてください!
Posted at 11:20午前 8 28, 2009 by Naoyuki Yamada in Sun | 投稿されたコメント[3]
vdbench でディスクの性能を測定する
はじめに
今回は vdbench というツールをご紹介したいと思います。vdbench は Henk Vandenbergh さんが作ったストレージのベンチマークツールです。Java と JNI で書かれており Solaris(SPARC and x86) の他 Windows や Linux, VMware, Mac OS X 等の主要なプラットフォームで動作する様です。私は主に Solaris と Linux で使用しています。このツールは元々は Sun の社内用のテストツールでしたが、バージョン 5.00 からはオープンソースとして公開されており、自由にお使い頂くことが可能です。ストレージのベンチマークは他にも bonnie-64, bonnie++, Iometer, IOzone, FileBench, IOR 等がありますが、vdbench には以下の特徴があります。使い勝手が良く動作も安定しておりますので、是非お試し下さい。
- 複数のプラットフォームで同じテストを実行できます
- RAW デバイスとファイルシステムに対して I/O 負荷を掛ける事が出来ます
- マルチスレッド、マルチプロセスを使用して並列に I/O を発生させる事が出来ます
- Read / Write の比率を変更して I/O を発生させる事が出来ます
- I/O サイズを変更して I/O を発生させる事が出来ます
- IOPS を指定して負荷を発生させる事が出来ます
- シーケンシャルかランダムか、I/O の特性を変更して負荷を生成する事が出来ます
- 複数のディスクに股がって I/O を発生させる事が出来ます
- 複数のホストから I/O を発生させる事が出来ます
- Solaris と Linux では O_SYNC, O_DSYNC, O_RSYNC のフラグを設定してファイルを開く事が出来ます
- テスト時間やテスト回数、I/O 発生パターン等をシナリオとして定義し、テストを自動化する事が出来ます
vdbench は http://blogs.sun.com/henk/entry/vdbench_a_disk_and_tape や http://www.sun.com/storage/white-papers/storage_bottlenecks.pdf でも紹介されておりますので、併せてご覧下さい。
vdbench のダウンロード
vdbench のソースコードとバイナリは http://vdbench.sourceforge.net/ からダウンロードできます。2009 年 8 月現在の最新バージョンは 5.01 です。
vdbench のインストール
Solaris へのインストール
ダウンロードしたファイルを展開するだけです
# mkdir /var/tmp/vdbench # cp vdbench501.zip /var/tmp/vdbench # cd /var/tmp/vdbench # unzip vdbench501.zip
Linux にインストールする
CentOS(64bit) の場合は付属の OpenJDK で vdbench を動かす事が出来ます。お使いの Linux に JavaVM が入っていない場合は http://java.sun.com から最新の JDK の 64bit Linux 版をダウンロードしてインストールしてください。
# mkdir /var/tmp/vdbench # cp vdbench501.zip /var/tmp/vdbench # cd /var/tmp/vdbench # unzip vdbench501.zip
vdbench の使い方
ここでは vdbench の基本的な使用方法を解説します。より詳しい使い方を知りたい方は vdbench のアーカイブに含まれている vdbench.pdf をご覧下さい。
vdbench を動かしてみる
動作確認の意味も込めて、早速 vdbench を動かしてみましょう。./vdbench -t を実行して下さい。以下の様な出力が得られれば成功です。
# ./vdbench -t
Vdbench distribution: vdbench500
For documentation, see 'vdbench.pdf'.
01:07:59.273 input argument scanned: '-f/tmp/parmfile'
01:07:59.327 Starting slave: /var/tmp/vdbench/vdbench SlaveJvm -m 10.16.67.4 -n localhost-10- 090723-01.07.58.208 -l localhost-0 -p 5570
01:07:59.660 All slaves are now connected
01:08:00.763 Inserted 'rd=File_format_for_sd=sd1' to initialize new file for sd=sd1,lun=/tmp/quick_vdbench_test,size=10485760
01:08:02.003 Starting RD=File_format_for_sd=sd1; I/O rate: 5000; Elapsed=(none); For loops: threads=8
01:08:02.089 All sequential workloads on all slaves are done.
01:08:02.089 This triggers end of run inspite of possibly some non-sequential workloads that are still running.
Jul 23, 2009 interval i/o MB/sec bytes read resp resp resp cpu% cpu%
rate 1024**2 i/o pct time max stddev sys+usr sys
01:08:03.051 1 9.00 9.00 1048576 0.00 11.178 15.601 5.275 2.7 1.4
01:08:03.057 avg_2-1 0.00 0.00 0 0.00 0.000 0.000 0.000
01:08:04.003 Starting RD=rd1; I/O rate: 100; Elapsed=5; For loops: None
Jul 23, 2009 interval i/o MB/sec bytes read resp resp resp cpu% cpu%
rate 1024**2 i/o pct time max stddev sys+usr sys
01:08:05.009 1 84.00 0.33 4096 53.57 0.009 0.040 0.005 1.1 0.3
01:08:06.047 2 89.00 0.35 4096 50.56 0.008 0.018 0.003 0.1 0.0
01:08:07.048 3 99.00 0.39 4096 50.51 0.008 0.017 0.003 0.1 0.0
01:08:08.047 4 94.00 0.37 4096 51.06 0.008 0.017 0.003 0.1 0.0
01:08:09.047 5 111.00 0.43 4096 53.15 0.008 0.024 0.003 0.1 0.1
01:08:09.050 avg_2-5 98.25 0.38 4096 51.40 0.008 0.024 0.003 0.1 0.0
01:08:09.357 Slave localhost-0 terminated
01:08:09.409 Vdbench execution completed successfully. Output directory: /var/tmp/vdbench/output
- vdbench -t は /tmp に負荷を発生させます。テスト結果は output ディレクトリにも出力されます。ウェブブラウザで output/summary.html を開いてみてください。
vdbench コマンドのオプション
テストの実行時に付けるオプションは、殆どの場合 "./vdbench -f <CONFIG FILE> -o <OUTPUT DIR>+" で十分です。以下の様にコマンドを実行すると myconf.txt から設定を読み込み、測定を実施し、測定結果を /var/tmp/resultXXX ディレクトリに書き出します。結果が出力されるディレクトリは自動的に作成されます。resultXXX の XXX は最初は空文字、2 回目以降は 000 から 999 までの値が自動的にインクリメントされます。これで同じコマンドを繰り返し実行しても(当分の間は)結果が上書きされずに済みます。
# ./vdbench -f myconf.txt -o /var/tmp/result+
vdbench の実行時に以下のオプションを渡すことも可能です。詳細はマニュアルをご覧下さい。
usage: ./vdbench [compare][gui] [-f xxx] [-o xxx] [-e nn] [-i nn] [-j] [-jr] [-v] [-vq] [-s] [-k] [- "parmfile parameters"] '-f xxx': Workload parameter file name(s). Default 'parmfile' in current directory 'gui': Start Vdbench Graphical User Interface '-o xxx': Output directory for reporting. Default 'output' in current directory '-e nn': Override elapsed=seconds. '-i nn': Override interval=seconds. '-v': Activate Data validation. '-vq': Activate Data validation, validate lba and data key (saves cpu) '-j': Activate Data validation with Journaling. '-jr': Recover existing Journal, Validate data and run workload '-s': Simulate execution. Do everything but I/O. '-k': Solaris only: Report kstat statistics on console.
設定ファイルの書き方
I/O パターンやテスト時間等の負荷シナリオは設定ファイルに記述します。ここではその記述方法を解説します。
サンプル設定
vdbench の設定ファイルの中身は以下の様なテキストです。設定は行単位で記述し、* で始まる行はコメントです。これをファイル保存し、vdbench -f <ファイル名> で読み込ませて実行します。他にも vdbench の配布ファイル中にサンプル設定が幾つか含まれていますのでご参照下さい。設定ファイルは生成したい負荷のシナリオを書き下した物なので、負荷シナリオとも呼ばれます。
- Example 1
*Example 1: Single run, one raw disk *SD: Storage Definition *WD: Workload Definition *RD: Run Definition * sd=sd1,lun=/dev/rdsk/c0t0d0s0 wd=wd1,sd=sd1,xfersize=4096,rdpct=100 rd=run1,wd=wd1,iorate=100,elapsed=10,interval=1 *Single raw disk, 100% random read of 4k records at i/o rate of 100 for 10 seconds
- Example 2
*Example 2: Single run, two raw disk, two workloads. sd=sd1,lun=/dev/rdsk/c0t0d0s0 sd=sd2,lun=/dev/rdsk/c0t0d1s0 wd=wd1,sd=sd1,xfersize=4k,rdpct=80,skew=40 wd=wd2,sd=sd2,xfersize=8k,rdpct=0 rd=run1,wd=wd*,iorate=200,elapsed=10,interval=1 *Two raw disks: sd1 does 80 i/o's per second, read-to-write ratio 4:1, 4k records. sd2 does 120 i/o's per second, 100% write at 8k records.
- Example 3(Filesystem)
fsd=fsd1,anchor=/dir1,depth=2,width=2,files=2,size=128k fwd=fwd1,fsd=fsd1,operation=read,xfersize=4k,fileio=sequential,fileselect=random,threads=2 rd=rd1,fwd=fwd1,fwdrate=max,format=yes,elapsed=10,interval=1
Raw デバイスに負荷を掛ける場合の設定手順
vdbench は Raw デバイスにもファイルシステムにも I/O 負荷を掛ける事が出来ますが、まずは Raw デバイスに負荷を掛ける場合の設定ファイルの書き方を解説します。
- sd の設定
まずは負荷生成対象のディスクの定義を行います。ディスクは sd=<設定名> で始まる行で定義します。sd は Storage Definition の略で、この行がディスクの定義であることを示しています。設定名は後でこの定義を参照するために付けます。
sd=sd1 <-- sd=<設定名> でディスクの定義
sd=<設定名> に続いて、カンマで区切り、負荷を掛ける対象のディスクの名前を記述します。ディスクの名前は lun=<デバイス名> の様に記述します。lun は Logical Unit Number の略です。デバイス名は Solaris では /dev/rdsk/c0t0d0s0 や /dev/md/rdsk/d10 の様にキャラクタデバイスをフルパスで指定します。Linux では raw コマンドで /dev/raw/... を作成し、それを指定します。
sd=sd1,lun=/dev/rdsk/c0t0d0s0 <-- lun=<デバイス名> を追加
Linux の場合は更にカンマで繋げて size=<ディスクサイズ> を指定する必要があります。ディスクサイズは fdisk -l で確認できます。
sd=sd1,lun=/dev/raw/raw1,size=733468426240 <-- Linux では size=<サイズ> が必要
基本的には、一行で指定できるディスクは一つだけです。複数のディスクに同時に負荷を掛けたい場合は sd の設定をディスクの数だけ記述する様にしてください。
更にカンマで区切って threads=<スレッド数> を指定することで、そのディスクに対する同時アクセス数を設定する事も出来ます。
sd=sd1,lun=/dev/rdsk/c0t0d0s0,threads=32 <-- threads=<スレッド数> を追加
ここまでの説明で以下の様な設定が記述できます。ここでは sd1 と sd2 という二つの設定をしています。それぞれ c0t0d0s0 と c0t1d0s0 が負荷生成対象のディスクです。
sd=sd1,lun=/dev/rdsk/c0t0d0s0 sd=sd2,lun=/dev/rdsk/c0t1d0s0
- wd の設定
次にワークロード(どんな I/O を発行するか)の定義を記述します。I/O の定義は行を wd=<設定名> で始めます。wd は Workload Definition の略です。
wd=wd1 <-- wd=<設定名> でワークロードの定義
wd=<設定名> に続いて、カンマで区切って負荷生成対象のディスクを指定します。ディスクは先ほど設定した sd の設定名で指定します。具体的には sd=<sd の設定名> の様に記述します。複数の sd を指定する場合はカンマで区切って sd=(sd1,sd2) の様に指定することも可能です。また sd=(sd1-sd10) の様に範囲で指定する事も出来ます。
wd=wd1,sd=sd1 <-- sd=<sd の設定名> を追加
wd には I/O サイズ、Read / Write の比率、シーケンシャルかランダムか、キャッシュヒット率等の I/O パターンを指定する事が出来ます。I/O サイズは xfersize=<サイズ> の様に指定します。Read / Write 比は rdpct=<Read の割合>、シーケンシャルかランダムかは seekpct=<ランダムシークの割合>、キャッシュヒット率は rhpct=<Read のヒット率>、whpct=<Write のヒット率> の様に指定します。seekpct の値はランダムアクセス用のディスクシークをどれだけの割合で行うかです。この値が 0 または sequential の時にシーケンシャルアクセスに、100 または random の値の時にランダムアクセスになります。seekpct=0 でシーケンシャルになるというのは直感的ではないかもしれませんので注意してください。
wd=wd1,sd=sd1,xfersize=32k,rdpct=100,seekpct=100 <-- wd のパラメータを追加
複数の wd を同時に実行するシナリオを作成することも可能です。複数の wd を同時実行した場合にそれぞれの wd にどれだけの I/O を割り振るかを指定する skew というパラメータも用意されています。skew は skew=<この wd に割り当てる I/O の割合> の様に設定します。skew を設定せずに複数の wd を同時実行した場合は、I/O はそれぞれの wd に均等に割り当てられます。
ここまでの説明で以下の様な設定を記述する事が出来ます。この設定では c0t0d0s0 と c0t1d0s0 に対して 4KB のサイズでシーケンシャルに書き込みを行います。
sd=sd1,lun=/dev/rdsk/c0t0d0s0 sd=sd2,lun=/dev/rdsk/c0t1d0s0 wd=wd1,sd=(sd1,sd2),xfersize=4k,rdpct=0,seekpct=0
- rd の設定
最後にテストの実行に関する設定を行います。テストの実行に関する設定は rd=<設定名> で始まる行を記述します。rd は Run Definition の略です。
rd=rd1 <-- rd=<rd の設定名> でテストの実行に関する定義
rd=<設定名> の後にカンマを置いて wd の指定を行います。wd は wd=<wd の設定名> の様に指定します。複数の wd を同時に実行する場合は wd=(wd1, wd2) の様に括弧の中にカンマ区切りで指定します。wd=(wd1-wd10) の様に範囲で指定することも可能です。複数の wd を指定する場合は、wd の設定の中で skew を設定すると、それぞれの wd に割り当てる I/O 量を変更する事が出来ます。
rd=rd1,wd=wd1 <-- wd=<wd の設定名> を追加
rd には秒間の I/O 回数、テスト実施時間、テスト状況をレポートする間隔等を設定する事が出来ます。I/O 回数は iorate=<毎秒の I/O 回数> または iorate=max で指定します。max を指定すると無制限に I/O を発行します。テスト実施時間は elapsed=<秒>、レポート間隔は interval=<秒> で指定します。
rd=rd1,wd=wd1,iorate=max,elapsed=600,interval=30 <-- rd のパラメータを追加
また複数のテストパターンを一括して行うための forxfersize=<サイズ>、forthreads=<スレッド数>、forrdpct=<Read の割合>、forseekpct=<ランダムシークの割合> の様なパラメータもあります。forxferseize=(4k,8k,12k,16k) と指定すると、I/O サイズが 4KB, 8KB, 12KB, 16KB のテストを順番に実施します。これらのパラメータはテストを自動化したい場合に便利です。
ここまでの説明で以下の様な設定が完成します。I/O 回数は最大、テスト実行時間は 180 秒、レポートの間隔は 10 秒おきになります。なお、* で始まる行はコメント行です。
* Test Pattern 1 - Sequential Write, 4KB * 2009/07/31 sd=sd1,lun=/dev/rdsk/c0t0d0s0 sd=sd2,lun=/dev/rdsk/c0t1d0s0 wd=wd1,sd=(sd1,sd2),xfersize=4k,rdpct=0,seekpct=0 rd=rd1,wd=wd1,iorate=max,elapsed=180,interval=10
- まとめ
以上見てきました通り、vdbench の設定はテキストファイルの中に行単位で記述します。パラメータは sd, wd, rd のカテゴリに分かれており、設定ファイルの各行は設定カテゴリの指定と設定名の記述で始めます。設定名の記述に続いて、カンマ区切りでパラメータとその値を記述します。パラメータは パラメータ名=値 という形式で指定します。* で始まる行はコメントです。
* コメント 設定カテゴリ名=設定名,パラメータ名=値,パラメター名=値,...
ファイルシステムに負荷を掛ける場合の設定手順
ファイルシステムに負荷を掛ける場合は sd の代わりに fsd, wd の代わりに fwd のエントリを作成し、rd の記述内容も多少変わってきます。
- fsd の設定
fsd は Filesystem Definition の略で、負荷を生成する対象のファイルシステムの構成を指定するエントリです。ここに負荷を発生させるディレクトリ名、ファイルの個数、ファイルサイズ等を設定します。
fsd=fsd1 <-- fsd=<fsd の設定名> でファイルシステム構成の設定
fsd の行は fsd=<設定名> で記述を始めます。設定名は後で参照する為に付ける名前です。この後ろにカンマで区切ってパラメータを設定して行きます。ディレクトリ名は anchor パラメータを使用して anchor=<ディレクトリ名> という様に指定します。ファイルの個数は files=<個数> と指定します。ファイルサイズは sizes=<サイズ> です。サイズは複数指定することが可能です。sizes=(32k,30,2m,70) と指定した場合は 32KB のファイルが 30%, 2MB のファイルが 70% の割合で作成されます。
fsd=fsd1,anchor=/mnt/test,files=100,sizes=2m <-- マウントポイント、ファイル数、ファイルのサイズを定義
width=<ディレクトリ数>, depth=<ディレクトリの深さ> を設定するとディレクトリの階層を指定する事が出来ます。depth で指定した深さだけサブディレクトリが作成され、それぞれのサブディレクトリには width で指定した数だけサブディレクトリが作成され、一番下の階層のディレクトリに files で指定した個数のファイルが作成されます。最終的に作成されるファイル数は "width ^ depth * files" で求まります。width=2,depth=2,files=2 の場合は 4 つのディレクトリに 8 つのファイルが作成され、width=2, depth=3, files=4 の場合は 8 つのディレクトリに股がって 32 個のファイルが作成されます。
fsd=fsd1,anchor=/mnt/test,width=2,depth=3,files=4,sizes=10m <-- ディレクトリ階層に付いても追加で定義
ここまでの説明で以下の様な設定を記述する事が出来ます。この設定では /mnt/test01 以下に 1GB のファイルが 10 個作成されます。/mnt/test01/ ディレクトリはテスト実施前に作成しておく必要があります。
fsd=fsd1,anchor=/mnt/test01/,files=10,sizes=1g
- fwd の設定
fwd は Filesystem Workload Definition の略で、発生させる I/O の中身を細かく定義する為のエントリです。I/O がシーケンシャルかランダムか、一つのファイルを open() してから close() するまでに何回ずつ I/O を発行するか、I/O を掛けるファイルを順番に選ぶかランダムに選ぶか、I/O のサイズ、read / write 等の I/O 操作の種類、I/O の並列度等を指定する事が出来ます。
fwd=fwd1 <-- fwd=<fwd の設定名> でワークロードの定義
fwd の行は fwd=<設定名> で始めます。設定名はこの定義を後で参照する為の名前です。続いて、カンマで繋げて fsd=<設定名> で既に定義したファイルシステム構成を関連づけます。更にカンマで区切り、fileio=<I/O 特性> を指定します。I/O 特性は random または sequential を指定します。ここで random を設定するとランダム I/O に、sequential だとシーケンシャル I/O になります。close() するまでに何回 I/O を発行するかは stopafter=<回数> で指定します。ファイルの選択方法は fileselect=<選択方法> で指定します。選択方法は random または sequential のどちらかを指定します。I/O のサイズは xfersizes=<サイズ> で指定します。このサイズは複数指定することも可能です。xfersizes=(8k,30,128k,70) の様に指定した場合は 8KB 単位の I/O が 30% と 128KB 単位の I/O が 70% 発生します。I/O 操作の種類は operation=<操作> で指定します。指定できる操作は read / write / open / close / create / delete / mkdir / rmdir / setattr / getattr です。読み出し性能の試験を行うときは read を、書き込み性能の試験を行う場合は write を指定してください。最後に、I/O の並列度は threads=<スレッド数> で指定します。
ここまでの説明で以下の様な設定を作成する事が可能です。8KB のシーケンシャル書き込みを一つのファイルに対して 1000 回ずつ 8 並列で実行します。負荷生成対象のファイルの探索はシーケンシャルに行われます。
fsd=fsd1,anchor=/mnt/test01/,files=10,sizes=1g fwd=fwd1,fsd=fsd1,fileio=sequential,stopafter=1000,fileselect=sequential,xfersizes=8k,operation=write,threads=8
- rd の設定
一番最後に rd を設定します。rd は Run Definition の略です。Raw I/O の場合の rd と同じ位置付けですが、パラメータが異なります。rd には既に定義した fwd をどの様に実行するかを設定します。
rd=rd1 <-- rd=<rd の設定名> でテストの実行に関するパラメータの設定
rd の行は rd=<設定名> から始めます。続いて、カンマで区切り、fwd=<fwd の設定名> を記述して既定の fwd を rd に関連付けます。これに続けて、秒間にどれだけの I/O 操作を発生させるかを指定します。指定方法は fwdrate=<I/O を発生させる量> です。このパラメータに max を指定するとマシンの性能が許す限りの I/O 操作を実行します。format=yes を設定すると、テスト開始前にファイルとディレクトリを作成します。これを設定しない場合は自分でファイルとディレクトリを作成しておく必要があります。ファイル数やファイルサイズが増えるとファイルの作成に時間が掛かる様になるので、一回目のテストでファイルを生成して、以降はそれを使い回すと良いかもしれません。elapsed=<秒> を設定すると、テストの実行時間を指定する事が出来ます。デフォルトは 30 秒です。ファイルシステムはキャッシュの影響が大きいので、ある程度長い時間でテストを行ってください。interval=<秒> を設定すると、統計情報の出力間隔を指定する事が出来ます。Solaris と Linux では openflags=<フラグ> を設定すると open() に渡すフラグを指定する事が出来ます。設定できるフラグは o_sync, o_dsync, o_rsync です(ソースファイルの Vdb/OpenFlags.java で確認できます)。データベース等を模したテストをする場合は O_DSYNC を付けると実環境により近付くかもしれません。
forsizes=<ファイルサイズ> を設定すると複数のファイルサイズのテストを一つの設定で実行する事が出来ます。forsizes=(128k,2m,1g) の様に指定すると、まず 128KB でテストを行い、それが終了したら 2MB のファイルサイズで、最後に 1GB のファイルサイズでテストを行います。forfiles=<ファイル数> を設定すると異なるファイル数のテストを順番に実施する事が出来ます。forfiles=(300,500,1000) と指定すると 300 個のファイルのテスト、500 個のファイルのテスト、1000 個のファイルのテストを順番に実行します。
ここまでの説明で以下の様な負荷生成シナリオができました。これをファイルに保存し vdbench コマンドの -f オプションでそのファイル名を指定することでこの負荷シナリオを実行する事が出来ます。
fsd=fsd1,anchor=/mnt/test01/,files=10,sizes=1g fwd=fwd1,fsd=fsd1,fileio=sequential,stopafter=1000,fileselect=sequential,xfersizes=8k,operation=write,threads=8 rd=rd1,fwd=fwd1,fwdrate=max,elapsed=600,interval=10,format=yes
- 注意
繰り返しテストを実行する場合は、測定条件を合わせるため、なるべく一度ファイルシステムをアンマウントしてから次のテストを実行する様にしてください。
- まとめ
Raw の設定ファイルでは sd, wd, rd のパラメータを設定しましたが、ファイルシステムの設定ファイルでは fsd, fwd, rd のパラメータを設定します。ファイルシステムキャッシュ等の影響があるので、試験時間は長めに、データ量は実環境になるべく近く、テストする度にマウントし直す様にしてください。
vdbench のパラメータ
前項まででご覧頂いた通り、Raw デバイスに負荷を生成する場合は SD(Storage Definition), WD(Workload Definition), RD(Run Definition) を設定する必要があります。ファイルシステムの場合は FSD(Filesystem Storage Definition), FWD(Filesystem Workload Definition), RD(Run Definition) を定義する必要がありました。実際にはそれ以外に General Parameters と HD(Host Definition) というパラメータもあります。全てのパラメータはマニュアルに記載されていますので、ご確認下さい。
テスト結果の見方
Raw の場合
出力先に指定したディレクトリに summary.html ができます。これをウェブブラウザで開いてください。
14:55:08.000 Starting RD=rd1; I/O rate: Uncontrolled MAX; Elapsed=60; For loops: xfersize=32768 Aug 04, 2009 interval i/o MB/sec bytes read resp resp resp cpu% cpu% rate 1024**2 i/o pct time max stddev sys+usr sys 14:55:18.023 1 9978.40 311.82 32768 0.00 0.798 52.837 1.960 4.5 3.8 14:55:28.011 2 8517.60 266.18 32768 0.00 0.936 26.145 2.138 4.0 3.3 14:55:38.011 3 8661.60 270.68 32768 0.00 0.921 33.382 2.112 4.1 3.3 14:55:48.012 4 7870.60 245.96 32768 0.00 1.013 30.333 2.250 3.6 3.1 14:55:58.010 5 8523.80 266.37 32768 0.00 0.935 87.823 2.317 3.9 3.3 14:56:08.011 6 8365.10 261.41 32768 0.00 0.954 34.503 2.170 3.9 3.2 14:56:08.014 avg_2-6 8387.74 262.12 32768 0.00 0.951 87.823 2.198 3.9 3.2 14:56:09.296 Vdbench execution completed successfully
- interval の値は統計情報の出力回数です。連番になっており一行出力する度に値が一つずつ増えて行きます。
- i/o rate は I/O の回数 (IOPS) です。
- MB/sec は I/O スループット (megabytes per second) です。
- bytes i/o は I/O サイズ(の平均)です。上の例の場合は xfersize=32768 にしましたので、一回の I/O サイズも 32768 bytes になります。
- read pct は Read の割合です。Write Only の時は 0 になります。
- resp time はミリ秒単位の平均レスポンス時間です。
- resp max はもっとも時間が掛かった処理の処理時間(ミリ秒単位)です。
- resp stddev はレスポンス時間の標準偏差(ばらつき度合い)です。
- cpu% sys+usr は処理に費やした CPU 時間です。
- cpu% sys は OS 側の処理に消費した CPU 時間です。
- avg_2-6 は、この行が 2 回目の出力から 6 回目の出力の平均であることを示しています。この行の i/o rate と MB/sec をテスト結果として採用すると良いでしょう。
- ほぼ同じ内容が標準出力にも出力されます。そちらを見て頂いても構いません。
ファイルシステムテストの場合
出力先に指定したディレクトリに summary.html ができます。これをウェブブラウザで開いてください。以下は summary.html の一部を抜き出したものです。
... 15:15:15.001 Starting RD=rd1; Elapsed=60; fwdrate=max. For loops: None 15:15:25.025 Interval ....Ops..... ...cpu%... ....read.... ...write.... ..mb/sec.. .xfer. ... 15:15:25.025 rate resp total sys rate resp rate resp read write size ... 15:15:25.025 1 10228 0.5 4.6 4.1 0.0 0.0 10228 0.5 0.0 79.9 8192 ... 15:15:35.011 2 3443.1 2.8 1.2 1.0 0.0 0.0 3443.1 2.8 0.0 26.9 8192 ... 15:15:45.013 3 14297 0.6 3.8 3.2 0.0 0.0 14297 0.6 0.0 111.7 8192 ... 15:15:55.009 4 8678.4 0.9 3.5 3.1 0.0 0.0 8678.4 0.9 0.0 67.8 8192 ... 15:16:05.011 5 5030.4 1.0 2.2 2.0 0.0 0.0 5030.4 1.0 0.0 39.3 8192 ... 15:16:15.009 6 3532.8 3.0 1.8 1.6 0.0 0.0 3532.8 3.0 0.0 27.6 8192 ... 15:16:15.012 avg_2-6 6996.5 1.2 2.5 2.2 0.0 0.0 6996.5 1.2 0.0 54.7 8192 ... 15:16:17.044 Vdbench execution completed successfully
- Interval は出力行の番号です。出力される度にインクリメントされて行きます。
- Ops は I/O 操作に関する統計情報です。Ops の rate は秒間の操作回数、resp は平均レスポンス時間です。
- cpu% は CPU 使用率を表しています。total が CPU 使用率で sys はその内のシステム時間です。
- read は読み出しに関する統計情報です。rate は毎秒の read 回数、resp は平均レスポンス時間です。
- write は書き込みに関する統計情報です。rate は毎秒の write 回数、resp は平均レスポンス時間です。
- mb/sec は毎秒のデータ転送量 (megabytes per second) です。read は読み出しの転送量、write は書き込みの転送量です。
- xfer size は I/O のサイズです。単位は byte です。
- avg_2-6 は、この行が 2 回目の出力から 6 回目の出力の平均であることを示しています。この行の read rate, write rate と mb/sec をテスト結果として採用すると良いでしょう。
- ほぼ同じ内容が標準出力にも出力されます。そちらを見て頂いても構いません。
実際に使ってみる
Solaris の Raw デバイスのテスト
vdbench を使って Solaris の Raw デバイスの Sequential Write の性能を測定してみます。設定ファイルは以下の通りです。
# cat conf/test01.conf * START "test01.conf" : sequential write - 8KB, 16KB, 24KB, 32KB sd=sd1,lun=/dev/rdsk/c0t2d0s2,size=733468426240 wd=wd1,sd=sd1,rdpct=0,seekpct=0 rd=rd1,wd=wd1,iorate=max,elapsed=180,interval=10,forxfersize=(8k,16k,24k,32k) * END
実行ログは以下の通りです。出力が長くなるので、一部重要な部分だけ載せています。
# ./vdbench -f conf/test01 -o /var/tmp/output+
...
Aug 17, 2009 interval i/o MB/sec bytes read resp resp resp cpu% cpu%
rate 1024**2 i/o pct time max stddev sys+usr sys
...
16:43:16.030 avg_2-18 37145.06 290.20 8192 0.00 0.212 5.279 0.049 16.7 14.1
...
16:46:17.017 avg_2-18 16963.02 265.05 16384 0.00 0.468 85.172 1.356 7.7 6.5
...
16:49:18.013 avg_2-18 11330.82 265.57 24576 0.00 0.703 72.644 1.928 5.2 4.3
...
16:52:19.015 avg_2-18 8746.64 273.33 32768 0.00 0.911 102.431 2.199 4.1 3.5
今回は単純に MB/sec の avg を結果として採用しました。まとめると以下の様になります。
8KB write 16KB write 24KB write 32KB write ----------------------------------------------------------- 290MB/sec 265.05MB/sec 265.57MB/sec 273.33MB/sec
Linux の Raw デバイスのテスト
Solaris の場合と同じ様に Linux でも Sequential Write の性能を測定してみます。Linux では Solaris の /dev/rdsk/... に対応するデバイスファイルを手動で用意する必要があります。
# ls /dev/raw ls: /dev/raw: No such file or directory <-- raw デバイスはデフォルトでは存在しない # raw /dev/raw/raw1 /dev/sdc <-- raw コマンドで raw デバイスを作成します /dev/raw/raw1: bound to major 8, minor 32 # ls /dev/raw ./ ../ raw1 # ls -l /dev/raw total 0 crw------- 1 root root 162, 1 Aug 6 00:13 raw1 <-- c で始まるのでキャラクタデバイス # fdisk -l /dev/sdc Disk /dev/sdc: 733.4 GB, 733468426240 bytes <-- サイズは 733468426240 bytes 255 heads, 63 sectors/track, 89172 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk /dev/sdc doesn't contain a valid partition table
設定ファイルと実行ログはこの様になります。
# cat conf/test01.conf
* START "test01.conf" : sequential write - 8KB, 16KB, 24KB, 32KB
sd=sd1,lun=/dev/raw/raw1,size=733468426240
wd=wd1,sd=sd1,rdpct=0,seekpct=0
rd=rd1,wd=wd1,iorate=max,elapsed=180,interval=10,forxfersize=(8k,16k,24k,32k)
* END
# ./vdbench -f conf/test01.conf -o /var/tmp/output+
...
Aug 17, 2009 interval i/o MB/sec bytes read resp resp resp cpu% cpu%
rate 1024**2 i/o pct time max stddev sys+usr sys
...
20:15:50.051 avg_2-18 35854.75 280.12 8192 0.00 0.222 6.433 0.053 8.6 7.3
...
20:18:51.050 avg_2-18 17196.88 268.70 16384 0.00 0.464 76.286 1.312 4.2 3.6
...
20:21:52.049 avg_2-18 11455.23 268.48 24576 0.00 0.697 68.371 1.885 2.9 2.4
...
20:24:53.048 avg_2-18 8622.86 269.46 32768 0.00 0.927 80.978 2.256 2.3 2.0
結果をまとめると次の様になります。Sequential Write に関してはだいたい Solaris の場合と同程度の性能になっていることが分かります。
8KB write 16KB write 24KB write 32KB write ----------------------------------------------------------- 280.12MB/sec 268.70MB/sec 268.48MB/sec 269.46MB/sec
Solaris のファイルシステムのテスト
次に vdbench を使ってファイルシステムの性能を測定してみます。全部で 50GB のファイルを Sequential Read します。ファイルシステムは ZFS を使用しました。
# format
Searching for disks...done
c0t1d0: configured with capacity of 136.59GB
AVAILABLE DISK SELECTIONS:
0. c0t0d0 <DEFAULT cyl 17830 alt 2 hd 255 sec 63>
/pci@0,0/pci8086,25f8@4/pci108e,286@0/disk@0,0
1. c0t1d0 <Sun-STKRAIDINT-V1.0 cyl 17831 alt 2 hd 255 sec 63>
/pci@0,0/pci8086,25f8@4/pci108e,286@0/disk@1,0
2. c0t2d0 <DEFAULT cyl 44584 alt 2 hd 255 sec 126>
/pci@0,0/pci8086,25f8@4/pci108e,286@0/disk@2,0
Specify disk (enter its number): ^D
# zpool create storage c0t2d0
# mkdir /storage/test
# cat conf/test10.conf <-- 設定ファイル
fsd=fsd1,anchor=/storage/test/,files=50,sizes=1g
fwd=fwd1,fsd=fsd1,fileio=sequential,fileselect=sequential,xfersize=8k,operation=read,threads=8
rd=rd1,fwd=fwd1,fwdrate=max,elapsed=600,interval=10,format=yes
# ./vdbench -f conf/test10.conf -o /var/tmp/output+
...
18:56:26.013 Interval ....Ops..... ...cpu%... ....read.... ...write.... ..mb/sec.. .xfer. ...mkdir... ...
18:56:26.013 rate resp total sys rate resp rate resp read write size rate resp ...
...
19:06:16.014 avg_2-60 39757 0.2 13.9 12.6 39757 0.2 0.0 0.0 310 0.0 8192 0.0 0.0 ...
...
テスト結果は 310MB/sec でした。iostat で測定したスループットも同じくらいでしたので純粋なストレージの性能が出ていると思われます。
最後に
今回は vdbench の使い方を解説しました。vdbench は定義できるシナリオの自由度が高く、動作するプラットフォームも多いので、様々な状況で役に立ちます。便利なツールですので、是非ご活用下さい。
Posted at 11:16午前 8 24, 2009 by Daisuke Homma in Sun | 投稿されたコメント[0]
CrossbowのVirtual NICとQoS制御を試してみる
以前より前評判の高かった Project Crossbow ですが、OpenSolaris 2009.06 の目玉機能として晴れて標準機能となり、誰でも簡単に使えるようになりま した。簡単に説明しますと、Project Crossbow とはネットワークの仮想化、 つまり仮想インターフェースの作成やネットワーク帯域分割、優先制御と いった機能を、可能であれば NICデバイスのハードウェアアシストも利用 しながら高速かつ低負荷に実現するものです。これを使えば、例えばサーバー 仮想化とあわせて、10本の GbE ケーブルを、お互いの帯域に干渉すること なく1本の 10GbEケーブルに統合するなど、管理性を向上させかつ複雑性を 排除することが可能です。例えば次のようなシチュエーションにも絶大な 効果を発揮するはずです。
- ある金融サービス会社がオンラインで無料情報提供サービスを開始 した。人気は上々だが、有料会員のサービスがスローダウンし、お客が 離れていった。。。
- ホスティングサービス会社がCPUコア数やメモリ量による価格体系を 用意したが、どのコースでもネットワーク帯域は使い放題。。。
- バックアップデータ転送中のため、重要な処理がネットワークタイム アウトしてしまった。。。
Virtual NIC の作成
では早速試してみましょう。必要なものは、OpenSolaris の動作する PC1台とインターネット接続だけです。まず、まだ PC に OpenSolaris を入れてない方は今すぐインストールしましょう。OpenSolaris は Live CD 形式になっているので、とりあえず手持ちのPCで動作確認した 後にボタン一発でインストールできるので、とても手軽です。
Crossbow では図のように、仮想インターフェース (VNIC: Virtual NIC) を物理インターフェース経由で直接外部ネットワークに接続することも 出来ますし、etherstub という仮想 HUB / Switch を使ってプライベート な Virtual Network を作ることも可能です。
今回は、後者の構成でプライベート・ヴァーチャル・ネットワークを 作成し、NAT 経由でインターネットと通信できるようにしてみます。
手順としては、まず、Virtual Network の要となる etherstub を作成し、 その上に Virtual NIC (vnic0, 1, 2) を作成します。vnic0 は Private Address 192.168.10.10 で up させます。
# dladm create-etherstub etherstub0 … etherstub を作成 # # dladm show-link LINK CLASS MTU STATE OVER bfe0 phys 1500 down -- etherstub0 etherstub 9000 unknown -- # # dladm create-vnic -l etherstub0 vnic0 … etherstub0上にvnic0を作成 # dladm create-vnic -l etherstub0 vnic1 … etherstub0上にvnic1,2を作成 # dladm create-vnic -l etherstub0 vnic2 # # dladm show-link LINK CLASS MTU STATE OVER bfe0 phys 1500 down -- etherstub0 etherstub 9000 unknown -- vnic0 vnic 9000 up etherstub0 vnic1 vnic 9000 up etherstub0 vnic2 vnic 9000 up etherstub0 # # ifconfig vnic0 plumb ... VNIC の設定&リンクアップ # ifconfig vnic0 192.168.10.10 up
NAT のセットアップ
vnic1 と vnic2 が、この後作成するコンテナ(zone)に与えられるのですが、 zoneを作る前に、NAT サービスを起動しておきましょう。
# routeadm
Configuration Current Current
Option Configuration System State
---------------------------------------------------------------
IPv4 routing enabled enabled
IPv6 routing disabled disabled
IPv4 forwarding disabled disabled
IPv6 forwarding disabled disabled
Routing services "route:default ripng:default"
Routing daemons:
STATE FMRI
online svc:/network/routing/ndp:default
online svc:/network/routing/route:default
disabled svc:/network/routing/rdisc:default
disabled svc:/network/routing/legacy-routing:ipv4
disabled svc:/network/routing/legacy-routing:ipv6
disabled svc:/network/routing/ripng:default
#
#
# routeadm -u -e ipv4-forwarding … ipv4-fowardingを活性化
# routeadm -u -d ipv4-routing … ipv4-routingを非活性化
#
# routeadm
Configuration Current Current
Option Configuration System State
---------------------------------------------------------------
IPv4 routing disabled disabled
IPv6 routing disabled disabled
IPv4 forwarding enabled enabled
IPv6 forwarding disabled disabled
Routing services "route:default ripng:default"
Routing daemons:
STATE FMRI
online svc:/network/routing/ndp:default
disabled svc:/network/routing/route:default
disabled svc:/network/routing/rdisc:default
disabled svc:/network/routing/legacy-routing:ipv4
disabled svc:/network/routing/legacy-routing:ipv6
disabled svc:/network/routing/ripng:default
#
#
# cd /etc/ipf … ipfilter / ipnat の設定
#
# cat ipnat.conf
map bfe0 192.168.10.0/24 -> 0/32 portmap tcp/udp auto
map bfe0 192.168.10.0/24 -> 0/32
#
#
# svcadm enable network/ipfilter … ipfilterサービスの起動
# svcs network/ipfilter
STATE STIME FMRI
online 12:16:34 svc:/network/ipfilter:default
#
#
# ipnat -l
List of active MAP/Redirect filters:
map bfe0 192.168.10.0/24 -> 0.0.0.0/32 portmap tcp/udp auto
map bfe0 192.168.10.0/24 -> 0.0.0.0/32
List of active sessions:
#
これで 192.168.10.0/24 プライベートネットワークからインターネット へ出られるようになりました。
Zone と Virtual Network の作成
では zone を作りましょう。VNIC を占有するので ip-type は Exclusive IP Zone となります。
# zonecfg -z zone1 … zone1を作成 (vnic1をアタッチ)
zone1: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:zone1> create
zonecfg:zone1> set zonepath=/export/home/zone1
zonecfg:zone1> set autoboot=true
zonecfg:zone1> set ip-type=exclusive
zonecfg:zone1> add net
zonecfg:zone1:net> set physical=vnic1
zonecfg:zone1:net> end
zonecfg:zone1> verify
zonecfg:zone1> commit
zonecfg:zone1> exit
#
# zoneadm -z zone1 verify ... 作成した zone 構成の検証
WARNING: /export/home/zone1 does not exist, so it could not be verified.
When 'zoneadm install' is run, 'install' will try to create
/export/home/zone1, and 'verify' will be tried again,
but the 'verify' may fail if:
the parent directory of /export/home/zone1 is group- or other-writable
or
/export/home/zone1 overlaps with any other installed zones.
#
#
# zoneadm -z zone1 install ... zone1 のインストール
WARNING: skipping network interface 'vnic1' which is used in the global zone.
A ZFS file system has been created for this zone.
Publisher: Using opensolaris.org (http://pkg.opensolaris.org/release/).
Image: Preparing at /export/home/zone1/root.
Sanity Check: Looking for 'entire' incorporation.
Installing: Core System (output follows)
...
# zoneadm list -iv ... インストールの確認
ID NAME STATUS PATH BRAND IP
0 global running / native shared
- zone1 installed /export/home/zone1 ipkg excl
#
# zoneadm -z zone1 boot
#
# zlogin -C zone1 ... Zone の初期設定
Host name: zone1
IP address: 192.168.10.11
System part of a subnet: Yes
Netmask: 255.255.255.0
Enable IPv6: No
Default Route: Specify one
Router IP Address: 192.168.10.10
vnic1 を持った zone1 が完成しました。global zone の vnic0 とつな がっているか確認してみましょう。
zone1# ping 192.168.10.10 … global zoneの vnic0と通信できた 192.168.10.10 is alive
次に clone 機能を使ってもう1つの zone を作ります。先に zone1 を shutdown しておいてください。
# zoneadm list -iv ........ zone1 は停止している ID NAME STATUS PATH BRAND IP 0 global running / native shared - zone1 installed /export/home/zone1 ipkg excl # zonecfg -z zone2 ... zone2 を作成する zone2: No such zone configured Use 'create' to begin configuring a new zone. zonecfg:zone2> create zonecfg:zone2> set zonepath=/export/home/zone2 zonecfg:zone2> set autoboot=true zonecfg:zone2> set ip-type=exclusive zonecfg:zone2> add net zonecfg:zone2:net> set physical=vnic2 zonecfg:zone2:net> end zonecfg:zone2> verify zonecfg:zone2> commit zonecfg:zone2> exit # zoneadm -z zone2 clone zone1 ... zone1 を基に clone を実行 sys-unconfig started 2009年07月15日 15時52分03秒 rm: /export/home/zone2/root/etc/vfstab.sys-u: No such file or directory sys-unconfig completed Wed Jul 15 15:52:04 2009 # # zoneadm list -iv ID NAME STATUS PATH BRAND IP 0 global running / native shared - zone1 installed /export/home/zone1 ipkg excl - zone2 installed /export/home/zone2 ipkg excl
zone1 と zone2 をそれぞれ起動します。zone2 は初回起動なので、パラ メータを与えます。
# zoneadm -z zone1 boot
# zoneadm -z zone2 boot ... zone2 を起動
Host name: zone2
IP address: 192.168.10.12
System part of a subnet: Yes
Netmask: 255.255.255.0
Enable IPv6: No
Default Route: Specify one
Router IP Address: 192.168.10.10
これで Virtual Network が完成しました。 ネットワーク構成は次のようになっているはずです。それぞれお互いに 接続可能か ping コマンドなどで試してみましょう。
global zone vnic0 192.168.10.10 zone1 vnic1 192.168.10.11 zone2 vnic2 192.168.10.12
etherstub に対して snoop コマンドも使えます。
# snoop -d etherstub0
Flow Control (Network QoS) を設定する
Project Crossbow の Flow Control では帯域制御と優先制御が可能ですが、 今回は帯域制御により HTTP コンテンツダウンロードの速度を制限して みましょう。global zone 上で Apache2 Web Server を立ち上げ、zone1 のクライアントがコンテンツをリクエストします。
まず global zone に Apache2 をインストールします。パッケージ マネージャを使えば簡単です。
* Apache2 を global zone へインストールする - Package Manager GUI を利用し Apache2.2 をインストール - /etc/apache2/2.2/httpd.conf はデフォルトのまま # svcadm enable apache22 ... Apache2 を起動 # svcs apache22 STATE STIME FMRI online 11:15:27 svc:/network/http:apache22
DocumentRoot は /var/apache2/2.2/htdocs なので、ここに大きめのファイルを置くこととします。何でも良いのですが、手元にあった OpenSolaris 2009.06 の ISO イメージを使ってみました。
次に zone1 へログインし wget をインストールします。 パッケージマネージャが外部のサーバへアクセスするので DNS の設定をして置いてください。
zone1# pkg install SUNWwget … wgetのインストール DOWNLOAD PKGS FILES XFER (MB) Completed 1/1 41/41 0.60/0.60 PHASE ACTIONS Install Phase 132/132 zone1# which wget /usr/bin/wget
できました。とりあえずダウンロードしてみます。
zone1# wget http://192.168.10.10/osol-0906-x86.iso ... global zone からデータ取得
--11:33:42-- http://192.168.10.10/osol-0906-x86.iso
=> `osol-0906-x86.iso'
Connecting to 192.168.10.10:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 709,871,616 (677M) [application/octet-stream]
100%[====================================>] 709,871,616 76.01M/s ETA 00:00
11:33:51 (73.18 MB/s) - `osol-0906-x86.iso' saved [709871616/709871616]
73.18 MB/s ほどの転送速度がでています。ちなみにリアルタイムの I/O statistics を見るには、以下のように dladm コマンドを使います (global zone で実行してください)。
(global zone) # dladm show-link -s -i3 vnic0 ... トラフィック監視コマンド LINK IPACKETS RBYTES IERRORS OPACKETS OBYTES OERRORS vnic0 127454 7726611 0 182076 1469324223 0 vnic0 0 0 0 0 0 0 vnic0 0 0 0 0 0 0 vnic0 0 0 0 0 0 0 vnic0 8 816 0 16 1248 0 vnic0 5339 289972 0 9863 81142533 0 vnic0 15542 841460 0 29119 239992394 0 vnic0 15484 837928 0 29291 241410706 0 vnic0 9836 532824 0 18448 152009568 0 vnic0 0 0 0 0 0 0 vnic0 0 0 0 0 0 0
では、vnic0 に http port 番号で帯域制限をかけてみましょう。
(global zone) (vnic0_httpflow の作成) # flowadm add-flow -l vnic0 -a transport=tcp,local_port=80 vnic0_httpflow # flowadm show-flow FLOW LINK IPADDR PROTO PORT DSFLD vnic0_httpflow vnic0 -- tcp 80 -- (flow に帯域制限を設定) # flowadm set-flowprop -p maxbw=100 vnic0_httpflow # # flowadm show-flowprop FLOW PROPERTY VALUE DEFAULT POSSIBLE vnic0_httpflow maxbw 100 -- 100 vnic0_httpflow priority -- --
もう一度 wget でダウンロードしてみます。
(zone1)
zone1# wget http://192.168.10.10/osol-0906-x86.iso
--12:15:53-- http://192.168.10.10/osol-0906-x86.iso
=> `osol-0906-x86.iso.1'
Connecting to 192.168.10.10:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 709,871,616 (677M) [application/octet-stream]
100%[====================================>] 709,871,616 12.41M/s ETA 00:00
12:16:47 (12.47 MB/s) - `osol-0906-x86.iso.1' saved [709871616/709871616]
確かに 12.47 MB/s (100Mbps) に帯域制限されています。
ではもう一度、今度は remote_ip で帯域制限を掛けてみます。 zone1(192.168.10.11) からのパケットを flow として切り出し、この帯域を50Mbpsに制限します。
(global zone)
# flowadm add-flow -l vnic0 -a remote_ip=192.168.10.11 zone1flow
(zone1 の IP-address は 192.168.10.11)
# flowadm show-flow
FLOW LINK IPADDR PROTO PORT DSFLD
zone1flow vnic0 RMT:192.168.10.11/32 -- -- --
# flowadm set-flowprop -p maxbw=50 zone1flow
# flowadm show-flowprop
FLOW PROPERTY VALUE DEFAULT POSSIBLE
zone1flow maxbw 50 -- 50
zone1flow priority -- --
zone1 にて wget を実行します。
zone1# wget http://192.168.10.10/osol-0906-x86.iso
--12:42:32-- http://192.168.10.10/osol-0906-x86.iso
=> `osol-0906-x86.iso.3'
Connecting to 192.168.10.10:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 709,871,616 (677M) [application/octet-stream]
100%[====================================>] 709,871,616 5.96M/s ETA 00:00
12:44:50 (4.92 MB/s) - `osol-0906-x86.iso.3' saved [709871616/709871616]
4.92 MB/s (50Mbps) に帯域制限されています。この時の I/O statistics は次の通りです。
(global zone でtrafficを確認) # dladm show-link -s -i3 vnic0 LINK IPACKETS RBYTES IERRORS OPACKETS OBYTES OERRORS vnic0 315631 18038505 0 541417 4421741359 0 vnic0 0 0 0 0 0 0 vnic0 0 0 0 0 0 0 vnic0 0 0 0 0 0 0 vnic0 0 0 0 0 0 0 vnic0 0 0 0 0 0 0 vnic0 835 47092 0 1625 13252705 0 vnic0 1036 57864 0 2035 16657730 0 vnic0 935 52282 0 1821 14901278 0 vnic0 1012 56712 0 1969 16113494 0 vnic0 1064 59392 0 2075 16995762 0 vnic0 1004 56136 0 1958 16030980 0 vnic0 985 54982 0 1924 15742424 0 vnic0 899 50338 0 1751 14332250 0 vnic0 959 53450 0 1882 15404284 0 ....
以上、いかがだったでしょうか?Crossbow / Zone 共に高機能かつ軽量な 最強コンビです。仮想化統合の定番として是非ご活用ください。
Posted at 11:18午前 8 21, 2009 by masahiko in Sun | 投稿されたコメント[0]
Solaris Cryptographic Framework を GlassFish から利用する方法
今回のブログでは、GlassFish アプリケーションサーバの HTTP(SSL) リスナーにて、UltraSPARC T1/T2 Crypto Accelerator を利用する設定を まとめます。
今回使用するアプリケーションサーバは、Sun GlassFish Enterprise Server v2.1
利用するバイナリは、Sun GlassFish Enterprise Server v2.1 with HADB for Solaris SPARC, Multi-language
sges_ee-2_1-solaris-sparc-ml.bin になります。
まずは、GlassFish のインストールを行いましょう。
# ./sges_ee-2_1-solaris-sparc-ml.bin -console -savestate /var/tmp/sges_ee-savestate
インストールが終了したら GlassFish を起動します。
# /opt/SUNWappserver/bin/asadmin start-domain --user admin domain1
Solaris Cryptographic Framework (SCF) を構成する
Solaris Cryptographic Framework (SCF) ソフトウェアトークンには 非公開情報が含まれているため、pktool(1) コマンドを使用して トークンにパスワードを設定します。 このコマンドは、アプリケーション所有者 (今回は、GlassFish を root として実行するので、root ユーザ) としてシステムにログインすることで、ユーザーのデフォルトキーストア を初期化します。
SCF ソフトウェアトークンのピンを設定する手順
pktool setpin コマンドを実行すると、$HOME/.sunw/pkcs11_softtoken/ ディレクトリ内のソフトウェアトークンデータストアが初期化されます。 これらのファイルは、その内容を保護するために、所有者だけがアクセス できるように作成されます。つまり、ユーザーが妥当なデータストアに アクセスできるように、GlassFish を実行しているのと同じ root ユーザー として初期化を実行する必要があります。
1. root ユーザーになります。
# su - root
2. id コマンドを実行します。
# id
uid=0(root) gid=0(root)
3. pktool コマンドを実行します。
# pktool setpin
トークンパスフレーズを入力してください: <-- 既存のパスフレーズを入力 (デフォルトは changeme)
新しいパスフレーズを作成してください: <-- 新しいパスフレーズ
新しいパスフレーズを再入力してください: <-- 確認の為もう一度入力します
パスフレーズが変更されました。 <-- パスフレーズが変更されたというメッセージが表示されます
#
4. root のホームディレクトリ (/) に移動します。
# cd /
5. アクセス権をチェックします。
# ls -alrR .sunw
.sunw:
合計 9
drwx------ 4 root root 5 7月 27日 17:51 pkcs11_softtoken
drwxr-xr-x 25 root root 29 7月 27日 17:51 ..
drwx------ 3 root root 3 7月 27日 17:51 .
.sunw/pkcs11_softtoken:
合計 14
drwx------ 2 root root 2 7月 27日 17:51 public
drwx------ 2 root root 2 7月 27日 17:51 private
-rw------- 1 root root 103 7月 27日 17:51 objstore_info
drwx------ 3 root root 3 7月 27日 17:51 ..
drwx------ 4 root root 5 7月 27日 17:51 .
.sunw/pkcs11_softtoken/public:
合計 6
drwx------ 4 root root 5 7月 27日 17:51 ..
drwx------ 2 root root 2 7月 27日 17:51 .
.sunw/pkcs11_softtoken/private:
合計 6
drwx------ 4 root root 5 7月 27日 17:51 ..
drwx------ 2 root root 2 7月 27日 17:51 .
sw-90#
cryptoadm を使用して Solaris Cryptographic Framework を管理する手順
cryptoadm ユーティリティーは、システムの暗号化プロバイダ情報の表示、
各プロバイダに対する機構の構成、暗号化プロバイダのインストールまたは
アンインストールを行います。
Solaris Cryptographic Framework では、ユーザーレベルのプロバイダ
(PKCS#11 共有ライブラリ)、カーネルプロバイダ (ロード可能なカーネル
ソフトウェアモジュール)、カーネルハードウェアプロバイダ (暗号化ハード
ウェアデバイス) という 3 種類のプロバイダがサポートされます。
cryptoadm ユーティリティーには、メタスロットの機能を有効化または無効化
するサブコマンド、メタスロットの構成を表示するサブコマンド、
メタスロットの機構のポリシーを構成するサブコマンドがあります。
1. Solaris Cryptographic Framework のすべてのサービスプロバイダと、各プロバイダの暗号化機構を表示するには、cryptoadm list -m を実行します。暗号化プロバイダとして ncp と pkcs11_softtoken.so が利用できることを確認してください。NCP はカーネルプロバイダなので、出力リスト内で pkcs11_kernel.so は pkcs11_softtoken.so よりも前に表示されるはずです。
# cryptoadm list -m
ユーザーレベルプロバイダ:
=====================
プロバイダ: /usr/lib/security/$ISA/pkcs11_kernel.so
メカニズム:
CKM_DSA
CKM_RSA_X_509
CKM_RSA_PKCS
CKM_RSA_PKCS_KEY_PAIR_GEN
CKM_DH_PKCS_KEY_PAIR_GEN
CKM_DH_PKCS_DERIVE
CKM_ECDSA_KEY_PAIR_GEN
CKM_ECDH1_DERIVE
CKM_ECDSA
プロバイダ: /usr/lib/security/$ISA/pkcs11_softtoken.so
メカニズム:
CKM_DES_CBC
CKM_DES_CBC_PAD
CKM_DES_ECB
CKM_DES_KEY_GEN
[.... 省略 ...]
CKM_DSA
CKM_DSA_SHA1
CKM_DSA_KEY_PAIR_GEN
[.... 省略 ...]
CKM_TLS_MASTER_KEY_DERIVE_DH
CKM_SSL3_KEY_AND_MAC_DERIVE
CKM_TLS_KEY_AND_MAC_DERIVE
CKM_TLS_PRF
カーネルソフトウェアプロバイダ:
==========================
swrand: メカニズムが表示されませんでした。
rsa: CKM_RSA_PKCS,CKM_RSA_X_509,CKM_MD5_RSA_PKCS,CKM_SHA1_RSA_PKCS,CKM_SHA256_RSA_PKCS,CKM_SHA384_RSA_PKCS,CKM_SHA512_RSA_PKCS
md5: CKM_MD5,CKM_MD5_HMAC,CKM_MD5_HMAC_GENERAL
sha2: CKM_SHA256,CKM_SHA256_HMAC,CKM_SHA256_HMAC_GENERAL,CKM_SHA384,CKM_SHA384_HMAC,CKM_SHA384_HMAC_GENERAL,CKM_SHA512,CKM_SHA512_HMAC,CKM_SHA512_HMAC_GENERAL
sha1: CKM_SHA_1,CKM_SHA_1_HMAC,CKM_SHA_1_HMAC_GENERAL
blowfish448: CKM_BLOWFISH_ECB,CKM_BLOWFISH_CBC
arcfour2048: CKM_RC4
aes256: CKM_AES_ECB,CKM_AES_CBC,CKM_AES_CTR
des: CKM_DES_ECB,CKM_DES_CBC,CKM_DES3_ECB,CKM_DES3_CBC
カーネルハードウェアプロバイダ:
==========================
ncp/0: CKM_DSA,CKM_RSA_X_509,CKM_RSA_PKCS,CKM_RSA_PKCS_KEY_PAIR_GEN,CKM_DH_PKCS_KEY_PAIR_GEN,CKM_DH_PKCS_DERIVE,CKM_ECDSA_KEY_PAIR_GEN,CKM_ECDH1_DERIVE,CKM_ECDSA
sw-90#
2. 次のユーザーレベル機構を無効にして、その機構が NCP によって実行されるようにします。
# cryptoadm disable provider=/usr/lib/security/'$ISA'/pkcs11_softtoken.so \
mechanism=CKM_SSL3_PRE_MASTER_KEY_GEN,\
CKM_SSL3_MASTER_KEY_DERIVE,CKM_SSL3_KEY_AND_MAC_DERIVE,CKM_SSL3_MASTER_KEY_DERIVE_DH,\
CKM_SSL3_MD5_MAC,CKM_SSL3_SHA1_MAC
3.ユーザーレベル機構が無効になったことを確認します。
# cryptoadm list -p provider=/usr/lib/security/'$ISA'/pkcs11_softtoken.so
/usr/lib/security/$ISA/pkcs11_softtoken.so: すべてのメカニズムが有効です,
except CKM_SSL3_SHA1_MAC,CKM_SSL3_MD5_MAC,CKM_SSL3_MASTER_KEY_DERIVE_DH,
CKM_SSL3_KEY_AND_MAC_DERIVE,CKM_SSL3_MASTER_KEY_DERIVE,
CKM_SSL3_PRE_MASTER_KEY_GEN. random が有効になっています。
SCF プロバイダを構成する手順
NSS では secmod.db を使用して、利用可能な PKCS#11 モジュールを管理します。NSS に付属の CLI のセキュリティーモジュール データベースツール modutil を使用すると、secmod.db ファイル内の PKCS#11 モジュール情報を管理することができます。このセキュリティーモジュールデータベースツールには、PKCS#11 モジュールの追加または削除、パスワードの変更、デフォルトの設定、モジュールの内容の表示、スロットの有効化または無効化などの機能があります。modutil CLI は Messaging Server ソフトウェアにバンドルされており、Messaging-Server-Root/sbin ディレクトリにあります。次の例では、Messaging-Server-Root/sbin ディレクトリから modutil を実行し、cert8.db、secmod.db、および key3.db が config ディレクトリ (Messaging-Server-Root/config) にあると想定します。
1. 利用可能なすべての PKCS#11 モジュールを一覧表示します。
modutil を使用すると、利用可能なすべての PKCS#11 モジュールを一覧表示できます。デフォルトでは、NSS には内部 PKCS#11 モジュールがあります。
# cd /opt/SUNWappserver/domains/domain1/config
# /opt/SUNWappserver/lib/modutil -dbdir . -nocertdb -list
Using database directory ../config...
Listing of PKCS #11 Modules
-----------------------------------------------------------
1. NSS Internal PKCS #11 Module
slots: 2 slots attached
status: loaded
slot: NSS Internal Cryptographic Services
token: NSS Generic Crypto Services
slot: NSS User Private Key and Certificate Services
token: NSS Certificate DB
-----------------------------------------------------------
2. デフォルトの NSS ソフトウェアトークンの内容を表示します。
# /opt/SUNWappserver/lib/certutil -L -d .
verisignclass1ca T,c,c
thawtepersonalpremiumca T,c,c
baltimorecodesigningca T,c,c
verisignclass2g2ca T,c,c
verisignclass3g3ca T,c,c
entrustglobalclientca T,c,c
entrustsslca T,c,c
verisignclass3g2ca T,c,c
thawtepremiumserverca T,c,c
entrust2048ca T,c,c
valicertclass2ca T,c,c
gtecybertrust5ca T,c,c
s1as u,u,u
equifaxsecureebusinessca1 T,c,c
verisignclass1g3ca T,c,c
godaddyclass2ca T,c,c
thawtepersonalbasicca T,c,c
verisignclass1g2ca T,c,c
verisignclass2g3ca T,c,c
equifaxsecureca T,c,c
entrustclientca T,c,c
verisignserverca T,c,c
geotrustglobalca T,c,c
equifaxsecureebusinessca2 T,c,c
verisignclass3ca T,c,c
verisignclass2ca T,c,c
gtecybertrustglobalca T,c,c
entrustgsslca T,c,c
thawtepersonalfreemailca T,c,c
thawteserverca T,c,c
baltimorecybertrustca T,c,c
starfieldclass2ca T,c,c
equifaxsecureglobalebusinessca1 T,c,c
Solaris Cryptographic Framework をサービスプロバイダとして追加する手順
Messaging Server は、NSS 組み込み型ソフトウェアトークンを暗号化に使用するように構成されています。NSS 組み込み型ソフトウェアトークンでは、PKCS#11 を使用して暗号にアクセスします。Solaris Cryptographic Framework のユーザーレベル暗号化フレームワークを使用するように、Messaging Server の構成を変更することができます。その方法は簡単で、/usr/lib/libpkcs11.so ライブラリにリンクして、PKCS#11 の機能に直接アクセスするだけです。つまり、Solaris Cryptographic Framework を PKCS#11 モジュールとして登録します。
1. PKCS#11 ライブラリ /usr/lib/libpkcs11.so を Messaging Server ソフトウェアに登録し、Sun Metaslot というスロットを有効にします。
# ./modutil -dbdir ../config/ -nocertdb -add "Solaris Crypto Framework" -libfile
/usr/lib/libpkcs11.so -mechanisms RSA
WARNING: Performing this operation while the browser is running could cause corruption
of your security databases. If the browser is currently running,
you should exit browser before continuing this operation. Type 'q ' to abort,
or to continue:
Using database directory ../config...
Module "Solaris crypto Framework" added to database.
Sun Metaslot スロットを有効にする手順
1. 次の modutil コマンドを実行します。
# ./modutil -dbdir ../config/ -nocertdb -disable "Solaris Crypto Framework"
WARNING: Performing this operation while the browser is running
could cause corruption of your security databases.
If the browser is currently running,
you should exit browser before continuing this operation.
Type 'q ' to abort, or to continue:
Using database directory ../config...
Slot "Sun Metaslot" disabled.
Slot "ncp/0 Crypto Accel Asym 1.0" disabled.
2. 次の modutil コマンドを実行します。
# ./modutil -dbdir ../config/ -nocertdb -enable "Solaris Crypto Framework" -slot "Sun Metaslot"
WARNING: Performing this operation while the browser is running
could cause corruption of your security databases.
If the browser is currently running,
you should exit browser before continuing this operation.
Type 'q ' to abort, or to continue:
Using database directory ../config...
Slot "Sun Metaslot" enabled.
3. 次の modutil コマンドを実行し、Solaris Crypto Framework が正常に追加されたことを確認します。
# ./modutil -dbdir ../config/ -nocertdb -list
Using database directory ../config...
Listing of PKCS #11 Modules
-----------------------------------------------------------
1. NSS Internal PKCS #11 Module
slots: 2 slots attached
status: loaded
slot: NSS Internal Cryptographic Services
token: NSS Generic Crypto Services
slot: NSS User Private Key and Certificate Services
token: NSS Certificate DB
2. Solaris Crypto Framework
library name: /usr/lib/libpkcs11.so
slots: 2 slots attached
status: loaded
slot: Sun Metaslot
token: Sun Metaslot
slot: ncp/0 Crypto Accel Asym 1.0
token: ncp/0 Crypto Accel Asym 1.0
-----------------------------------------------------------
NSS ソフトウェアトークンから証明書と鍵のペアをエクスポートする手順
1. SSL のリスナーとして設定されている http-listener-2 の Cert nickname を確認する
# /opt/SUNWappserver/bin/asadmin get server.http-service.http-listener.http-listener-2.ssl.\*
管理ユーザー名を入力してください>admin
管理パスワードを入力してください>
server.http-service.http-listener.http-listener-2.ssl.cert-nickname = s1as
server.http-service.http-listener.http-listener-2.ssl.client-auth-enabled = false
server.http-service.http-listener.http-listener-2.ssl.ssl2-ciphers =
server.http-service.http-listener.http-listener-2.ssl.ssl2-enabled = false
server.http-service.http-listener.http-listener-2.ssl.ssl3-enabled = true
server.http-service.http-listener.http-listener-2.ssl.ssl3-tls-ciphers =
server.http-service.http-listener.http-listener-2.ssl.tls-enabled = true
server.http-service.http-listener.http-listener-2.ssl.tls-rollback-enabled = true
#
2. 次のコマンドを実行し、内部トークンに含まれる s1as の証明書を PKCS#12 形式のファイルにエクスポートします。
# /opt/SUNWappserver/lib/pk12util -o /tmp/s1as -n s1as -d /opt/SUNWappserver/domains/domain1/config
Enter Password or Pin for "NSS Certificate DB": <-- GlassFish インストール時に指定したマスターパスワードを入力
Enter password for PKCS12 file: <-- 出力する PKCS#12 形式のファイルのパスワードを設定
Re-enter password: <-- 確認の為再度入力
pk12util: PKCS12 EXPORT SUCCESSFUL
sw-90#
証明書と鍵のペアを Sun Metaslot (SCF) にインポートする手順
1. 次の pk12util コマンドを実行します。
# /opt/SUNWappserver/lib/pk12util -i /tmp/s1as -d /opt/SUNWappserver/domains/domain1/config -h "Sun Metaslot"
Enter Password or Pin for "Sun Metaslot": <-- pktool setpin にて入力したパスワードを入力
Enter password for PKCS12 file: <-- PKCS#12 形式のファイルのパスワードを入力
pk12util: PKCS12 IMPORT SUCCESSFUL
証明書と鍵のペアが正常にインポートされたことを確認する手順
この手順では、証明書と鍵のペアがトークンに正常にインポートされたことを確認します。
1. 次の certutil コマンドを実行します。
# /opt/SUNWappserver/lib/certutil -L -d /opt/SUNWappserver/domains/domain1/config -h "Sun Metaslot"
Enter Password or Pin for "Sun Metaslot": <-- pktool setpin にて入力したパスワードを入力
Sun Metaslot:s1as u,u,u
2. 次の certutil コマンドを実行します。
# /opt/SUNWappserver/lib/certutil -K -d /opt/SUNWappserver/domains/domain1/config -h "Sun Metaslot"
Enter Password or Pin for "Sun Metaslot": <-- pktool setpin にて入力したパスワードを入力
<0> s1as
GlassFish から Solaris Crypto Framework を利用する為の手順
1. SSL のリスナーとして設定されている http-listener-2 の Cert nickname を Sun Metaslot 内にある s1as に変更
# /opt/SUNWappserver/bin/asadmin set --user admin server.http-service.http-listener.http-listener-2.ssl.cert-nickname="Sun Metaslot:s1as"
管理パスワードを入力してください>
server.http-service.http-listener.http-listener-2.ssl.cert-nickname = Sun Metaslot:s1as
#
2. GlassFish を再起動
# /opt/SUNWappserver/bin/asadmin stop-domain
ドメイン domain1 が停止しました。
# /opt/SUNWappserver/bin/asadmin start-domain --user admin domain1
ドメイン domain1 を起動しています。お待ちください。
Default Log location is /opt/SUNWappserver/domains/domain1/logs/server.log.
管理パスワードを入力してください>
マスターパスワードを入力してください>
NSS スロット Sun Metaslot のパスワードを入力してください>
出力を /opt/SUNWappserver/domains/domain1/logs/server.log にリダイレクトしています
ドメイン domain1 が起動しました。
ドメイン [domain1] はその設定で [Sun GlassFish Enterprise Server v2.1 (9.1.1) (build b60e-fcs)] を実行しています。ログは [/opt/SUNWappserver/domains] にあります。
管理コンソールは [https://localhost:4848] で使用できます。
"asadmin" コマンドにも同じポート [4848] を使用します。
ユーザーの Web アプリケーションは次の URL で使用できます:
[http://localhost:8080 https://localhost:8181 ]。
次の web-contexts を使用できます:
[/web1 /__wstx-services ]。
標準の JMX クライアント (JConsole など) はドメイン管理のために JMXServiceURL:
[service:jmx:rmi:///jndi/rmi://sw-90.japan.sun.com:8686/jmxrmi] に接続できます。
ドメインは少なくとも次のポートで接続を待機しています:
[8080 8181 4848 3700 3820 3920 8686 ]。
ドメインはアプリケーションサーバークラスタおよびその他のスタンドアロンインスタンスをサポートします。
sw-90#
Crypto Accelerator が正常に動作している事を確認する
1. 設定した HTTP リスナーのポート番号を確認する
# //opt/SUNWappserver/bin/asadmin get server.http-service.http-listener.http-listene rr-2.\*
管理ユーザー名を入力してください>admin
管理パスワードを入力してください>
server.http-service.http-listener.http-listener-2.acceptor-threads = 1
server.http-service.http-listener.http-listener-2.address = 0.0.0.0
server.http-service.http-listener.http-listener-2.blocking-enabled = false
server.http-service.http-listener.http-listener-2.default-virtual-server = server
server.http-service.http-listener.http-listener-2.enabled = true
server.http-service.http-listener.http-listener-2.external-port =
server.http-service.http-listener.http-listener-2.family = inet
server.http-service.http-listener.http-listener-2.id = http-listener-2
server.http-service.http-listener.http-listener-2.port = 8181
server.http-service.http-listener.http-listener-2.redirect-port =
server.http-service.http-listener.http-listener-2.security-enabled = true
server.http-service.http-listener.http-listener-2.server-name =
server.http-service.http-listener.http-listener-2.xpowered-by = true
#
2. SSL アクセス前の利用状況を確認する
# kstat -n ncp0 -s rsaprivate
module: ncp instance: 0
name: ncp0 class: misc
rsaprivate 1
#
3. https://sw-90.japan.sun.com:8181/ へアクセスする
4. SSL アクセス後、再度利用状況を確認する
※ rsaprivate の値が増えているので、正常に利用している事が確認できる
# kstat -n ncp0 -s rsaprivate
module: ncp instance: 0
name: ncp0 class: misc
rsaprivate 2
#
参考情報
- Using the Cryptographic Accelerators in the UltraSPARCR T1 and T2 Processors
- 特集記事: UltraSPARC T1 プロセッサ搭載のシステム上での Sun Java System Messaging Server 6.3 および Solaris Cryptographic Framework の構成
- Configuring Messaging Server and UltraSPARC T1 and T2 Hardware SSL Acceleration
Posted at 04:00午後 7 29, 2009 by Masayuki Imai in Sun | 投稿されたコメント[0]
Solaris で Oracle を効率的に稼働させるための仕組み
はじめに
wikis.sun.com に Oracle on Sun に関する面白い情報がありましたのでご紹介したいと思います。Oracle データベースを Solaris 上で効率よく安定して稼働させるために、Solaris にどんな技術が実装されて来たのかが時系列でまとまっています。全ての技術を網羅している訳ではありませんが、皆さまのご参考になれば幸いです。元の文書に大きく加筆修正を施していますので、もしお時間があれば元文書もご覧下さい。
初期の技術革新
1993 年、Solaris 2.2 の ISM
Solaris 2.2 で ISM(Intimate Shared Memory) が実装されました。
ISM は、共有メモリ のアドレス変換テーブルをプロセス間で共有する機能です。ISM を使用しない場合は共有メモリのアドレス変換テーブルはプロセス毎に作成されますが、沢山のプロセスが同じ共有メモリを使用すると同じマッピング情報が重複して保持される事になり、カーネルメモリと TLB が無駄になります。SGA に接続する Oracle プロセスの数が多い大規模なシステムでは ISM の共有ページテーブル機能は非常に効果的です。また、ISM を使用して確保されるメモリページは物理メモリ上にロックされるという利点もあります。これにより ISM を使用する Oracle の SGA は常に物理メモリ上に常駐し、スワップアウトされないことが保証されます。これも大規模システムで性能を発揮するのに効果的です。ISM のもう一つの特徴として、大規模ページのサポートがあります。SPARC システムのデフォルトのページサイズは通常 8KB ですが、ISM を使用すると可能な場合は 4MB など、より大きなページサイズが適用されるようになります。大規模ページサイズを使用することでキャッシュミスを抑制し処理の効率が上がります。共有ページテーブル、大規模ページサポート、ページのロックという大規模システムでデータベースを効率よく実行するたに必要が技術が ISM によって実現しました。
試しに Oracle のサーバプロセスに pmap コマンドを実行すると "ism" が使用されていることが分かります。
# pmap -xs 21323
21323: oraclefoo (LOCAL=NO)
Address Kbytes RSS Anon Locked Pgsz Mode Mapped File
...
0000000380000000 2592768 2592768 - 2592768 4M rwxsR [ ism shmid=0x64 ]
# ipcs -ma
IPC status from as of Tue Jul 7 10:50:01 JST 2009
T ID KEY MODE OWNER GROUP CREATOR CGROUP NATTCH SEGSZ CPID LPID ATIME DTIME CTIME
Shared Memory:
m 100 0x8bba0d8c --rw-r----- oracle dba oracle dba 21 2654994432 423 4957 0:00:01 0:01:11 12:35:55
Jim Mauro が書いた Sun World の記事には ISM の詳細が解説されています。併せてご覧下さい。
ISM の実装は OpenSolaris のソースコードを "ISM" で検索して下さい。
"Oracle Database 管理者リファレンス" の中にも ISM に関する記述があります。
SDC(Solaris Developer Connection) にも ISM の使い方が詳解されています。
Java で ISM を使用する方法はこちらをご覧下さい。
ラッチ保有時のプリエンプション抑制
schedctl_init(3C) を始めとする schedctl API は Solaris のスケジューラによるプリエンプションを抑制するインターフェイスです。クリティカルなロックを保持しているスレッドがプリエンプトされてスレッドの優先順位の逆転が起きてしまうのを防ぎます。ロックを保持しているアプリケーションは schedctl API を使って、スケジューラに対してもう少し長い間 CPU を使用できるように依頼することができます。schedctl API は Oracle ではラッチで使用されています。ラッチを保持しているスレッドがスケジューラによって休眠させられて並列度が制限されることを防ぎます。
64bit Solaris
10 年以上前のことですが、Solaris は 2.7 から 64bit 実装が登場しました。64bit Solaris 上で 64bit Oracle を使用することにより、4GB 以上のメモリを搭載したマシンでもリソースを有効に使える様になりました。当時のフラッグシップだった Sun Enterprise 10000 は最大 64GB のメモリを搭載可能なマシンでした。一方、32bit 版の Oracle では genksms コマンドを使用して初めて 2GB 以上の SGA を確保する事が出来ました。
10 万 tpmC の壁を突破
1999 年、Sun と Oracle は TPC-C で 10 万 tpmC を超えて業界最高性能を達成しました。その時の記録は Sun Enterprise 10000 上の Solaris 2.7 と Oracle 8i の組み合わせで 115,395.73 tpmC です。この結果は、64bit Solaris, ISM, schedctl API 等、ここまで挙げて来た全ての技術革新の結実でした。
当時のプレスリリースはこちらです。
Solaris 9 が 2002 年に登場してから
DISM(Dymanic ISM)
DISM は共有ページテーブル、大規模ページサポートなどの ISM の機能に加えて、必要に応じてサイズを増やしたり、ページをロック/解除する機能を備えています。DISM は ISM の恩恵を受けつつ Oracle 9i から導入された動的 SGA を使用するために必要な機能です。Oracle の SGA_MAX_SIZE, MEMORY_TARGET または MEMORY_MAX_TARGET パラメータが適切に設定されている場合に DISM が使用されます。
また、Solaris の RCM(Reconfiguration Coordination Manager) のスクリプトと DISM, 動的 SGA を組み合わせることで、動的システムドメインからメモリを取り除く際も Oracle を停止せずに運用することが可能です。
Solaris 8 1/01 の機能比較表に DISM についての記載があります。
DISM には 共有ページテーブル、大規模ページサポート、ページのロックなど、 ISM と同じ特長があります。DISM ではこれに加え、他のアプリケーションに メモリを解放するためにページのロックが解除され、共有メモリセグメントの サイズを増やすために新たなページがロックされます。この機能により、Oracle データベースのパフォーマンスが著しく向上します。
Oracle 11g の管理者リファレンスにも DISM についての記載があります。
NUMA システムへの最適化
Solaris 9 9/02 から MPO(Memory Placement Optimization) という機能が実装されました。MPO は NUMA システム上でアプリケーションを効率よく動作させるための仕組みです。CPU からメモリまでの距離に応じて lgroup という区画を設定し、アプリケーションが使用するメモリの割り当て位置やスレッドがスケジュールされる CPU を 最適化します。lgroup へのインターフェイスとして lgrp_init(3LGRP) を始めとする lgroup API も実装されています。
Oracle では SGA のアクセスに lgroup API と madvise(3C) を使用することで NUMA マシンで性能が向上しています。これは Opteron や Nehalem を搭載した NUMA 構成のマシンでも非常に有効です。
Dual Core Opteron x4CPU のマシンで lgroup を表示させた例です。この場合は lgroup が 4 つ作成されています。
# uname -m i86pc # kstat -p 'unix:0:system_misc:ncpus' unix:0:system_misc:ncpus 8 # kstat -p 'lgrp:::cpus' lgrp:1:lgrp1:cpus 2 lgrp:2:lgrp2:cpus 2 lgrp:3:lgrp3:cpus 2 lgrp:4:lgrp4:cpus 2
MPO のドキュメントには Oracle を使用する際の MPO の利点が詳解されています。
Oracle と MPO の関係に関するプレゼンテーション資料もご覧下さい。
こちらは Jonathan Chew による MPO のオーバービューです。
大規模ページサポート
既に ISM, DISM の項で取り上げましたが、Solaris 9 より複数のメモリページサイズがサポートされています。この機能は MPSS(Multiple Page Size Support) と呼ばれ、プロセスが 8KB 以上のページサイズを使用することが可能になっています。特に Oracle の様にメモリの使用量が大きいソフトウェアでは MPSS を使用することで TLB ミスを抑制し、性能を向上することが可能です。
Sun SPARC Enterprise T5220 でサポートされているページサイズは以下の通りです。T5220 では最大 256MB までのページサイズを指定することが可能になっており、CMT マシンでは MPSS は特に有効です。
# uname -im sun4v SUNW,SPARC-Enterprise-T5220 # pagesize -a 8192 65536 4194304 268435456
Oracle の SGA が ISM, DISM により大規模ページサイズを使用していることは既にご紹介している通りです。Oracle 10g では memcntl(2) 関数を通じて PGA にラージページを使用することが可能です。Oracle のパラメータに "_realfree_heap_pagesize_hint=4M" を指定すると mmap() されたヒープがデフォルトの 8KB ではなく 4MB のページを使用する様になります。
MPSS についてはこちらもご覧下さい。
- http://www.solarisinternals.com/wiki/index.php/Multiple_Page_Size_Support
- http://blogs.sun.com/glennf/resource/fawcett.25kscale.pres.rev1.03.pdf
- http://dsstos.blogspot.com/2008/10/realfreeheappagesizehint-assessing.html
poll の改良
アプリケーションのスケーラビリティを高めるために poll インターフェイスにも改良が加わっています。Solaris 固有の機能として /dev/poll が用意されています。また Solaris 10 では Event Completion API が追加されました。
- /dev/poll デバイス
% ls -l /dev/poll lrwxrwxrwx 1 root root 29 Dec 12 2007 /dev/poll -> ../devices/pseudo/poll@0:poll
- http://developers.sun.com/solaris/articles/polling_efficient.html
- http://developers.sun.com/solaris/articles/event_completion.html
スケジューラの改善
Solaris のスケジューラにも改善が施されています。
FX (固定優先順位)スケジューリングクラスは、優先順位の逆転を軽減するために導入されました。FX スケジューリングクラスを使用すると Oracle LGWR プロセスを他の標準的なプロセスより高い優先順位を与えることが可能になります。優先順位の設定は priocntl(1) コマンドを使用します。設定したスケジューリングクラスは子プロセスにも継承されるので、Oracle のリスナープロセスに適切な優先順位を設定しておけば、サーバプロセスも同じ優先順位で実行されます。
また、Oracle CRS ではリアルタイムスケジューリングクラスを使用しています。Oracle RAC は LMS デーモンにリアルタイムクラス使用しており、キャッシュフュージョンは高い優先順位で行われます。
- Solaris で用意されているスケジューリングクラスの一覧
% priocntl -l
CONFIGURED CLASSES
==================
SYS (System Class)
TS (Time Sharing)
Configured TS User Priority Range: -60 through 60
RT (Real Time)
Maximum Configured RT Priority: 59
FX (Fixed priority)
Configured FX User Priority Range: 0 through 60
IA (Interactive)
Configured IA User Priority Range: -60 through 60
- Oracle 11g のドキュメント中の priority inversion の説明
UFS direct I/O の改良
UFS direct I/O は Solaris 2.6 から提供されていますが、Solaris 8 Update 3 から read / write 共に並列実行される様に改良されました。従来の direct I/O はファイル毎に書き込み時の並列度を 1 に制限するロックが設けられており、データベースの更新が多い場合は、このロックの取得が大きなオーバーヘッドになっていました。改善された direct I/O ではファイルサイズに変更がない場合は並列に処理されます。この改善により direct I/O は raw デバイスに対する I/O に近い性能を発揮できる様になりました。
Oracle で direct I/O を使用するには FILESYSTEMIO_OPTIONS 初期化パラメータに SETALL を指定するか UFS のマウントオプションに directio を指定します。
UFS direct I/O の並列処理について詳しくまとめられています。
Solaris Internals のフォローアップページにも詳しく記載されています。
MONITORING AND TUNING ORACLE のブループリントです。
以下は Oracle のドキュメントに記載されている FILESYSTEMIO_OPTIONS 初期化パラメータ情報です。
Solaris 10 が 2005 年に登場してから
MPSS サポートの拡張
MPSS がサポートするページサイズが 256MB まで拡大されました。この最適化はデフォルトで有効になっており、CMT サーバ上で Oracle を稼働させる際に特に性能が向上します。
Ravi の Blog には Sun Fire T2000 サーバ上でデータベースを稼働させた場合のラージページの恩恵がまとめられています。
プロセス間通信用パラメータの管理
project を利用することで、プロセス間通信のパラメータを reboot 無しに変更できる様になりました。Oracle 用のカーネルパラメータも project で管理します。
細かな変更点
その他の修正はこちらにも記載されていますので是非ご参照下さい。
dbwr が aio_waitn(3RT) API を使うときの効率性が上がりました。
- aio_waitn is desired : http://bugs.opensolaris.org/view_bug.do?bug_id=4503970
- http://docs.sun.com/app/docs/doc/817-0697/6mgfsdh34?q=aio_waitn
おわりに
ID 4503970 の レポート にある "There is also a request by Oracle..." という言葉が示しているように、データベースを効率よく動かすために Solaris に実装された仕組みは沢山あります。ここに挙っていない技術でも DTrace, ZFS, FireEngine, Crossbow, Zone, KAIO, libaio, proc tools, Sun Cluster, QFS 等、Solaris には Oracle を運用する上で便利だったり性能向上に貢献する技術が沢山含まれています。また、Solaris が元々備えている高いスケーラビリティや高負荷時の安定性、障害解析能力などの特徴はデータベースを稼働させるのに非常に役立ちます。こういった話もいずれ機会があればご紹介させて頂きたいと思います。
以上、Oracle と Solaris の歴史を機能実装的な側面からご紹介しました。何故 Solaris なのかという疑問が浮かんだ時に一つの答えとなれば幸いです。
Posted at 01:42午後 7 28, 2009 by Daisuke Homma in Sun | 投稿されたコメント[3]
DTrace の flowindent オプション紹介
今回は、DTrace の flowindent オプションを紹介します。
flowindent オプションは、モニタリングするプログラムに対して、関数の開始(entry)と 終了(return)の出力をインデント(->) を付けて表示させる事により、関数の 入れ子関係を把握しやすくする効果があります。
実際に使用する方法は、 D スクリプトの中に flowindent を定義するか、DTrace 実 行時に -F オプションを付与して実行します。
それでは、実際に flowindent の効果を確認してみましょう。
モニタリングするサンプルとして、下記テストプログラムを実行ファイル名 a.out で作成します。
テストプログラム
int main()
{
func1();
func2();
}
int func1()
{
func3();
}
int func2()
{
func1();
}
int func3()
{
func4();
}
int func4()
{
}
テストプログラムに対する関数の入れ子を確認する為に下記 D スクリプト を作成します。今回は、D スクリプトの中に flowindent オプションを 埋め込みました。また、関数の呼び出しを確認する為に pid プロバイダを 使用しております。
サンプル D スクリプト(flowindent.d)
#pragma D option flowindent
pid$target:a.out::entry
{
}
pid$target:a.out::return
{
}
早速 flowindent.d を実行してみましょう。
flowindent.d 実行結果
# dtrace -s flowindent.d -c a.out dtrace: script 'pid.sample.d' matched 15 probes dtrace: pid 1196 exited with status 16 CPU FUNCTION 0 -> _start 0 -> __fsr 0 <- __fsr 0 -> func1 0 -> func3 0 -> func4 0 <- func4 0 <- func3 0 <- func1 0 -> func2 0 -> func1 0 -> func3 0 -> func4 0 <- func4 0 <- func3 0 <- func1 0 <- func2 0 <- main
このように、関数の入りと出がインデントを付けて表示されました。
DTrace を使用しないで関数の入れ子状態を確認するデバッグには、よく関数の入りと出の 部分に printf() 文を入れて確認していましたが、DTrace を使用すればソースプログ ラムにデバッグ用のコード を埋め込む修正も必要ないですし、当然、確認の為にリコンパイルも必要ありません。
また、各関数を呼び出した回数や、各関数毎の実行時間の累積も DTrace を使うと 集積関数を使って簡単に計測する事ができます。
関数の呼び出し回数を計測するスクリプト(func_count.d)
pid$target:a.out::entry
{
@counts[probefunc] = count();
}
pid$target:a.out::return
{
}
func_count.d 実行結果
# dtrace -s func_count.d -q -c a.out __fsr 1 _start 1 func2 1 func1 2 func3 2 func4 2このように、各関数を実行した回数を集計して表示する事ができます。
関数の実行時間累積を計測するスクリプト(exectime.d)
pid$target:a.out::entry
{
self->ts[probefunc] = timestamp;
}
pid$target:a.out::return
/probefunc != "main"/
{
@sum[probefunc] = sum(timestamp - self->ts[probefunc] );
self->ts[probefunc] = 0;
}
exectime.d 実行結果
# dtrace -s exectime.d -q -c a.out __fsr 9923 func4 10553 func2 32865 func3 34526 func1 57725
このように、各関数を実行した累積時間を集計して表示する事ができます。
ここで使用した PID プロバイダは、ユーザが作成したプログラムのパフォーマンス 計測にとても便利ですので、開発者の方は是非マスターして下さい。
(参考情報)
過去の 「やっぱり Sun がスキ!」blog 記事一覧はこちらを参照下さい。 http://wikis.sun.com/display/yappri/Home
Posted at 02:12午後 7 24, 2009 by Naoyuki Yamada in Sun | 投稿されたコメント[0]
StarSuite (OpenOffice) で写真の背景を透明化するには
仕事柄、お客様に製品やソリューションのご紹介をすること が多いのですが、プレゼンテーションの資料作りにはいつも StarSuite のお世話になっています。写真をペタペタ貼って 視覚に訴えるのが好きなので、ファイルサイズはいつも10MB 近くになってしまいます。なのでCPUが速すぎて困るなん てことはありません。
サンの社員としては当然、サン製品の写真を多用するわけで、 そういうときは http://photos.sun.com/ からダウンロードします。ログイン の必要なページもありますが、"Products" のページは誰でも アクセスできますので、覚えておいて損は無いと思います。 きれいな製品写真が入手できるのでとても便利です。
ところで、製品単体を紹介する場合はこれで良いのですが、 最近はソリューション提案というのが重要らしく、従って プレゼン資料も1つのページに何枚も写真を貼らなくては なりません。で、実際切り貼りしてみると気が付くのですが、 写真の周辺部が透明でないとどうしても2枚の写真を寄せら れないんですね。フォトレタッチソフトを使えば良いのでしょ うが、どうも面倒です。
そういう時便利なのがスポイト機能です。この機能を使う には、プレゼンテーションファイルを開いた状態で、プル ダウンメニューの "ツール"->"スポイト" を選択・クリック します。するとスポイトダイアログが現れます。
左側に4つあるチェックボックスのうち、上の1つをチェック し、置換候補を「塗りつぶしなし」にした後、マウスを写真の 上へ持ってくると、スポイトダイアログの左上のボックスが マウスの指している部分の色に変わります。マウスを写真の周辺 部に置いて透明にしたい色が決まったら左クリックし、スポイト ダイアログの「置換」ボタンを押します。
こんなふうに重ね合わせも自然な感じです。皆さんもぜひ ご活用ください。知的生産性向上間違いなしです。
Posted at 10:33午前 6 29, 2009 by masahiko in Sun | 投稿されたコメント[1]
統計情報を一挙に取得するスクリプト
はじめに
今回はシステムの性能情報をまとめて取得するスクリプトをご紹介したいと思います。私が普段ベンチマークテストを行う時に使用しているスクリプトです。
システムの性能を解析する際は、解析対象のシステムの負荷が高い時に現場で解析を行う事が鉄則です。稼働中のシステムに接続して、コマンドの結果を見ながら問題範囲を狭めて行くと、効率の良い解析が出来るからです。しかし現実的には、常にシステムの負荷が高い時に解析を行える訳ではありません。何らかの事情で現場に行く事が出来ず、他の人に統計情報の取得を依頼して、後からログを解析する様な事は良くあります。また、誰かに性能解析を依頼する場合も、あらかじめ必要なログを取得しておき現場から離れた場所で解析して貰う事があります。
現場で解析が出来無い場合は、入手する必要のある情報を解析の前に考えておかなければなりません。まだ状況が不明な状態でどのログを取るべきかを決定するのは困難ですので、通常は網羅的に統計情報を取得しておく事になるでしょう。広範囲に情報を取得しておけば、解析する段になって情報が不足する事を防げるからです。従来であれば、そのような時に使用するツールは sar(1) であったり、rpc.rstatd(1M) を使用した統合監視ユーティリティがありました。ここでの問題は sar(1) や rpc.rstatd(1M) は必ずしも必要なデータを取得出来ない事、そして不足している情報があってもカスタマイズ出来ない事です。
この様な時に自分で修正可能なスクリプトを持っていると便利です。「ちょっと現場に立ち会えないんだけど、このスクリプトを実行してログを送ってもらえる?」と言っておき、時間がある時にゆっくり解析を進める事も可能です。急な出張が入ってしまったり、ちょっと体調を崩して出社出来なかったり、同時に複数のサイトを調査する必要が出ても、これがあれば多少は安心です。厳しいセキュリティによりログを持ち出せない場合でも常にマシンに張り付いている必要は無くなります。
前置きが長くなりましたが、後で解析出来る様に統計情報をまとめて取得しておく為のスクリプトのご紹介です。
使い方
基本的な使い方
この記事の一番下にあるスクリプトを stat.sh という名前で保存し、実行権限を付け、実行します。
# mkdir /var/tmp/stat # cd /var/tmp/stat # vi stat.sh # chmod +x ./stat.sh # ./stat.sh Ctrl-C to stop this.
Ctrl-C を押すと実行が終了します。何も押さなければ延々と統計情報を取得し続けます。
結果の見方
スクリプトを実行したディレクトリに log ディレクトリが作成され、そこに統計情報のログが保存されています。
# ls log 0619-172209.about.txt 0619-172209.netstat-tcp.log 0619-172209.cfgadm-alv.log 0619-172209.netstat.log 0619-172209.defaultrouter 0619-172209.nodename 0619-172209.dladm-bge0.log 0619-172209.nsswitch.conf 0619-172209.dladm.log 0619-172209.prstat.log 0619-172209.format.log 0619-172209.prtdiag-v.log 0619-172209.hosts 0619-172209.ps-ef.log 0619-172209.ifconfig-a.log 0619-172209.psrinfo.log 0619-172209.iostat.log 0619-172209.psrset.log 0619-172209.kmastat.log 0619-172209.release 0619-172209.messages 0619-172209.system 0619-172209.mount.log 0619-172209.uname-a.log 0619-172209.mpstat.log 0619-172209.vfstab 0619-172209.ndd-ip.log 0619-172209.vmstat-p.log 0619-172209.ndd-tcp.log 0619-172209.vmstat.log 0619-172209.netstat-nr.log
ファイル名の先頭の 0619-172209 は日付と時間です。6/19 の 17:22:09 にスクリプトを実行しました。
各ファイルには最長 1 時間分のログが保存されます。スクリプトの実行が 1 時間を越えると、自動的に新しいファイルが作成され、ログは新しいファイルに保存されます。
取得される情報はファイル名の通りです。XXXX-XXXXXX.vmstat-p.log には "vmstat -p 1" を実行した結果が保存され、XXXX-XXXXXX.cfgadm-alv.log には "cfgadm -alv" を実行した結果が保存されています。vmstat, mpstat, iostat 等、基本的な統計情報から解析を始めて下さい。
結果を保存する
log ディレクトリを gtar と bzip2 で固めるだけです。この状態で性能解析を担当する人に渡してあげれば便利です。
# gtar jcf ./log.tar.bz2 ./log
その他
stat.sh の引数にコメントを指定する事が出来ます
# ./stat.sh "MySQL 5.4 Benchmark" Ctrl-C to stop this. ^C # cat ./log/*.about.txt MySQL 5.4 Benchmark
取得したい統計情報があれば、必要に応じてスクリプトを改変して下さい。
おわりに
Solaris の統計情報を網羅的に取得するスクリプトをご紹介しました。Solaris を管理する上で、こういうダーティーなスクリプトが役に立つ局面もあるのではないかと思います。是非、色々と改造して使って下さい。
もし GUI で統計情報を見たい場合は Dim STAT や JKstat もご覧下さい。
スクリプト
#!/bin/sh
IVAL=1
DURATION=3600
DIR=./log
SH_PID=$$
PID=${SH_PID}
COMMENT=$@
if [ ! -d ${DIR} ]
then mkdir ${DIR}
fi
LANG=C; export LANG
LC_ALL=C; export LC_ALL
echo "Ctrl-C to stop this."
while :
do DATE=`date '+%m%d-%H%M%S'`
echo ${COMMENT} > ${DIR}/${DATE}.about.txt
# system configurations
cp /etc/nodename ${DIR}/${DATE}.nodename &
uname -a > ${DIR}/${DATE}.uname-a.log &
cp /etc/release ${DIR}/${DATE}.release &
cp /etc/system ${DIR}/${DATE}.system &
cp /var/adm/messages ${DIR}/${DATE}.messages &
prtdiag -v > ${DIR}/${DATE}.prtdiag-v.log &
cfgadm -alv > ${DIR}/${DATE}.cfgadm-alv.log &
psrinfo > ${DIR}/${DATE}.psrinfo.log
psrset > ${DIR}/${DATE}.psrset.log &
# network configurations
ifconfig -a > ${DIR}/${DATE}.ifconfig-a.log &
dladm show-link > ${DIR}/${DATE}.dladm.log
dladm show-dev > ${DIR}/${DATE}.dladm.log &
cp /etc/defaultrouter ${DIR}/${DATE}.defaultrouter &
cp /etc/nsswitch.conf ${DIR}/${DATE}.nsswitch.conf &
cp /etc/hosts ${DIR}/${DATE}.hosts &
netstat -nr > ${DIR}/${DATE}.netstat-nr.log &
netstat -a > ${DIR}/${DATE}.netstat.log &
# disk configuration
echo | format > ${DIR}/${DATE}.format.log &
cp /etc/vfstab ${DIR}/${DATE}.vfstab &
mount > ${DIR}/${DATE}.mount.log &
#luxadm probe > ${DIR}/${DATE}.luxadm-probe.log &
#luxadm -e port > ${DIR}/${DATE}.luxadm-port.log &
# kernel memory usage
echo ::kmastat | mdb -k > ${DIR}/${DATE}.kmastat.log &
# ndd
echo "tcp_time_wait_interval" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_time_wait_interval >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_conn_req_max_q" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_conn_req_max_q >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_conn_req_max_q0" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_conn_req_max_q0 >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_keepalive_interval" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_keepalive_interval >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_naglim_def" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_naglim_def >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_smallest_anon_port" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_smallest_anon_port >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_max_buf" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_max_buf >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_conn_hash" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_conn_hash >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_bind_hash" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_bind_hash >> ${DIR}/${DATE}.ndd-tcp.log
echo "tcp_listen_hash" >> ${DIR}/${DATE}.ndd-tcp.log
ndd -get /dev/tcp tcp_listen_hash >> ${DIR}/${DATE}.ndd-tcp.log
echo "ip_conn_status" >> ${DIR}/${DATE}.ndd-ip.log
ndd -get /dev/ip ip_conn_status >> ${DIR}/${DATE}.ndd-ip.log
echo "ip_squeue_fanout" >> ${DIR}/${DATE}.ndd-ip.log
ndd -get /dev/ip ip_squeue_fanout >> ${DIR}/${DATE}.ndd-ip.log
echo "ip_soft_rings_cnt" >> ${DIR}/${DATE}.ndd-ip.log
ndd -get /dev/ip ip_soft_rings_cnt >> ${DIR}/${DATE}.ndd-ip.log &
# process list
ps -ef > ${DIR}/${DATE}.ps-ef.log
# trapstat
# trapstat -t 1 3 > ${DIR}/${DATE}.trapstat.log &
# prstat
prstat -n 50 1 60 > ${DIR}/${DATE}.prstat.log &
# vmstat
vmstat ${IVAL} ${DURATION} > ${DIR}/${DATE}.vmstat.log &
PID="$! ${PID}"
# vmstat -p
vmstat -p ${IVAL} ${DURATION} > ${DIR}/${DATE}.vmstat-p.log &
PID="$! ${PID}"
# iostat
iostat -xnCMmp ${IVAL} ${DURATION} > ${DIR}/${DATE}.iostat.log &
PID="$! ${PID}"
# mpstat
mpstat ${IVAL} ${DURATION} > ${DIR}/${DATE}.mpstat.log &
PID="$! ${PID}"
# netstat
netstat -sP tcp ${IVAL} ${DURATION} > ${DIR}/${DATE}.netstat-tcp.log &
PID="$! ${PID}"
# network performance counter
NIC=`dladm show-dev -p | grep 'link=up' | awk '{printf "%s ", $1}'`
for i in ${NIC}
do dladm show-dev -s -i 1 ${i} > ${DIR}/${DATE}.dladm-${i}.log &
DL_PID="$! ${DL_PID}"
done
trap "kill -9 ${DL_PID} ${PID}
echo 'script done' " 2
sleep ${DURATION}
kill -9 ${DL_PID}
PID=${SH_PID}
DL_PID=""
done
Posted at 02:31午後 6 24, 2009 by Daisuke Homma in Sun | 投稿されたコメント[0]
SS7000 Update 情報
今回は、昨年の11月に発表した Sun Storage 7000 シリーズに関して、 リリースされてから現在までのメジャーなアップデートを紹介します。
1. Sun Storage 7310 のリリース
5 月末に、新しいラインナップである Sun Storage 7310が発表されました。
SS7310 が発表される前は、クラスタ構成を組む場合、最上位機種 の SS7410 以外選択肢がありませんでしたが、SS7310 がラインナップに追加された事により価格を抑えたクラスタ 構成を組む事が可能になりました。( Read Cache 用 SSD も 600GB までサポートです。)
SS7410 と SS7310 の主な違いは、コントローラ部分に使用しているサーバが SS7410 は 2U なのに対して、SS7310 は 1U になります。

Sun Storage 7310 最大構成
2. SS7110 の容量アップ
SS7110 が発表された当初は、使用する SAS Disk が 146GB のみのサポートであった為、 最大容量が 2TB でしたが、4月末に 300GB SAS Disk がサポートされた事により、SS7110 の 最大容量が、4.2 TB になりました。これからも 400GB など大容量の構成が期待できます。
3. SS7210 に J4500 の拡張性
SS7210 は、高さ 4U で SATA Disk 48 本内蔵できる高密度のストレージサーバです。発表当時は最大で 48 TB までの 拡張性でしたが、5 月末のアップデートで J4500 JBOD ストレージの増設が可能になりました。
これで、48TB で足りない場合、さらに J4500 を 2 台増設できますので、最大で 142TB まで増設 可能になりました。
最後に、
SS7000 シリーズは、価格性能比に優れているだけでなく、使いやすい GUI が好評のプロダクトです。この GUI を 体感できるシミュレータが以前から公開されておりますが、このシミュレータも進化しており、VMware 版だけでなく VirtualBOX 版も 公開されております。是非お試し下さい!
[シミュレータ URL] http://www.sun.com/storage/disk_systems/unified_storage/resources.jsp
(参考情報)
過去の 「やっぱり Sun がスキ!」blog 記事一覧はこちらを参照下さい。 http://wikis.sun.com/display/yappri/Home
Posted at 11:14午前 6 23, 2009 by Naoyuki Yamada in Sun | 投稿されたコメント[0]