Archive for the ‘japanese’ Category
メモ: DTraceを少し勉強してみた
なぜか今まで自分で調べるほど興味が向かなかったDTraceですが、最近よく耳にするようになった事もあり、少し勉強してみました。Mac OS X (10.5) から標準で使えるというのも大きかったですね。正直なところ、Solarisでしか動作しなかったら、DTraceに興味を示さなかったと思います。
ググってみたら、ITMediaなどで詳しく書かれている人がいるので、Yet another DTrace entryになってしまいますが、私の個人メモという事でお許しください。DTraceを調べてて思ったのが、Paul van den BogaardというSUNの人が書かれた、DTrace by Example: Solving a Real World Problemというドキュメントが凄く解り易かったです。
DTraceを簡素にいうと?
DTraceとはSUNがSolarisのために開発したダイナミックなトレーシング機能で、runtimeでシステムの動作をkernelレベルからトレースできるプロダクトです。Paulの資料ではフレームワークという表現がされていて、現在はSolarisの他にMac OS Xで使用する事が可能です。
DTraceを使うとシステム管理者や開発者などは手元のプログラムと、その更に下にあるOSに関する様々な情報を取得する事が可能になり、システムのプロファイリングやデバッグに役立ちます。ただ、DTraceと一言でいっても、様々なコンポーネントが絡んでいるので、気をつけないといけませんね:
- OSのカーネル
- D言語
- dtraceコマンド
- dtraceのバーチャルマシン
- dtraceのプローブ
- dtraceのプロバイダ
- dtraceの各種ライブラリ
私が見たところ、DTraceの良いところは、ユーザ(システム管理者など)にとって興味のない情報を含んだ膨大なトレース結果が返されるのではなく、トレースする・返す情報を細かいレベルまで実際にD言語をつかって指定する事が可能な事でしょうか(例えばシステムコールの発行数・実行時間だけを返せとか)。つまりD言語をつかってカスタムなトレーサやプロファイラーを書く事ができるわけですね。
DTraceの流れ
D言語で記述されたトレーススクリプトは、dtraceコマンドによって実行します。スクリプトを受け取ったdtraceコマンドはOSのカーネルに組み込まれたdtraceのバーチャルマシンが理解できる中間形式に変換します(Javaでいうbytecodeっぽいですね)。あとはバーチャルマシンがユーザのスクリプトに記述されたロジックに基づいた集計を行ってくれます。
集計の流れ、そしてProbeとProvider
DTraceにはprobeという概念があり、probeとはカーネル内の計測ポイントを示します。Probeには様々な種類があり、それぞれ特定の条件下で有効になります(とあるシステムコールが発行されたなど)。したがって、D言語のスクリプトに特定のprobeを指定すると、そのprobeが有効になった際に報告される情報を収集できるとの事。
ちなみに私の使っているMacBook Pro (OS X 10.5.5, DTrace API version 1.2.2) のDarwin kernelに組み込まれているprobeの総数を見てみたところ:
… (省略)
21652 plockstat4556 libSystem.B.dylib pthread_rwlock_wrlock$UNIX2003 rw-error
21653 plockstat4556 libSystem.B.dylib pthread_rwlock_unlock rw-release
21654 plockstat4556 libSystem.B.dylib pthread_rwlock_unlock$UNIX2003 rw-release
2万個以上ものProbeが発見されました。けっこうな数ですね〜。実際はオン・ザ・フライでprobeを生成するproviderが存在するので、probeはもっとあるらしいです。
SUN KKのDTraceドキュメント(日本語)によると、Probeが有効になると以下の情報が取得可能との事です:
- 関数に渡されたすべての引数
- カーネル内のすべての大域変数
- 関数が呼び出された日時を示すタイムスタンプ
- 関数を呼び出したコードセクションを示すスタックトレース
- 関数が呼び出されたとき実行中だったプロセス
- 関数を呼び出したスレッド
また、カーネル内でProbeを実際に有効にするカーネルモジュールをProviderと呼びます。Providerには色々な種類があって、特定のプロバイダに関連するprobeは、そのProviderにグルーピングされる様です。
ググってみたらProviderのリスト・種類の説明はDTraceのwikiとSolaris Dynamic Tracing Guideに載っていました:
http://wikis.sun.com/display/DTrace/Providers
http://docs.sun.com/app/docs/doc/817-6223(チャプター17から32まで)
D言語の書き方
私自身が人に教えれるほどD言語を把握していない事と、仕様を書くとブログエントリーの域を超えてしまうので、控えさせて頂きますが、DTraceユーザガイドの第3章に基本的な説明が記載されています。
楽な逃げ道を紹介すると、自分で頑張ってスクリプトをガリガリ書かなくても、DTraceToolKitという200種類以上もの充実したスクリプト集があります(存在を教えてくれたkiyotakaさんに感謝)。OS Xだと動かないスクリプトも結構あるみたいですが、私が試してみたメモリ関連のスクリプトは大丈夫っぽいです。
DTraceをMac OS Xで使ってみる(ワンライナー)
トリッキーな検査でなければ、スクリプトファイルを作成しなくても端末上でdtraceを試す事が可能です。
例えばプロセスがファイルを開いたら即座に報告する:
$ sudo dtrace -n 'syscall::open*:entry { printf("%s %s", execname, copyinstr(arg0)); }'
read(2)を呼んだプロセスを即座に報告する:
$ sudo dtrace -n 'syscall::read:entry { printf("%s", execname); }' // OUTPUT: // CPU ID FUNCTION:NAME // 1 17602 read:entry mDNSResponder // 1 17602 read:entry mDNSResponder // 1 17602 read:entry EchoPod // 1 17602 read:entry EchoPod
-p オプションでトレース対象を特定のプロセスに絞る (例, pid=6455):
$ sudo dtrace -p 6455 -n 'syscall::read:entry { printf("%s", execname); }'
など、ご覧の通りD言語を少し学ぶとPerlのワンライナー感覚で色々と遊べます。
余談
memcached-1.2.6には、ほぼ全てのコマンドに対しdtrace probeが組み込まれており、configure時に--enable-dtraceを指定するとprobeを適応する事ができるのです。つまり、memcachedに特化したtop(1)的なプログラムを数行で書けてしまうのです。
が、、現状だとOS Xの実装がSolarisと違うため、OS Xだとビルドに失敗してしまいます(dtraceの-Gオプションを認識しない)。この問題はSUNの技術者が絶賛対応中なので、1.3シリーズにはOS Xでビルドできるようになると期待していて、今後はmemcachedを修行相手にしてdtraceの知識や腕を磨きたいな〜、と思っています。
memcached Night #1 in Tokyo
memcached Night #1 in Tokyoで私が使用した講演資料を公開しました。
最近になって開発が一段落したという事もあり、講演時にベンチマークを取っておらず、説得力に欠けたスライドがいくつかあったかと思います。後付けになってしまいましたが、簡単なベンチマークを講演資料に追加しました。私の結果を要約すると、リクエストのconcurrencyが少ない場面だと、プロトコル間のパフォーマンスに差は見られませんが、同時リクエスト数を増やしていくと、パフォーマンスの差が見えてくるといったところです。今後はもっとヘビーなワークロードでテストを行う必要がありそうですね。
イベント自体は他のスピーカーの方達の話も面白く、ゲーム業界でもmemcachedが大事なところで使われているなど、本当に勉強になりました。参加者の皆さま、あらためて有り難うございます。懇親会も楽しく、COOKPADさんがあれだけのサービスを少数精鋭で支えている(技術面で)という話が私の中で印象強かったです。ぜひまたやりましょう。
最後に二つほど、明らかにさせておきたい事がありましたので、この機会に書かせて頂きます。
プロトコルドキュメントに関して
MIRACLE LINUXの吉岡さんのブログエントリーに固定長ヘッダのサイズが16バイトと書かれていて、それはおかしいぞ?と思い、見てみたらSix Apartのsvnレポジトリに入っているドキュメントが古いという事に気がつきました。現時点の仕様では固定長ヘッダのサイズは24バイトで、Trond Norbyeのgitレポジトリに現時点で最新のドキュメントがあります(紛らわしくて、すみません)。
チェックアウトするブランチ
講演以来、様々な方達にバイナリプロトコルのソースツリーを試して頂けているのですが、masterではなく、binprotというブランチ(http://github.com/tmaesaka/memcached/tree/binprot)をチェックアウトしてください。
さて来月、memcached hackathonの参加に米国に行きますので、その際にmemcached Nightで皆さまから頂いたフィードバックや日本での普及活動を口頭で伝えてきますね。