Hatena::ブログ(Diary)

(ひ)メモ このページをアンテナに追加 RSSフィード

2013-09-24 (Tue)

YAPC::Asia 2013でLT『How to inspect a RUNNING perl process』してきました&スピーカーへのお願い

YAPC::Asia 2013でLT『How to inspect a RUNNING perl process』してきました

ハングアップとかメモリバカ食いとか、稀にしか発生しないヘンテコ状態のシューティングやるには静的デバッグより、今ヘンテコ状態にあるプロセスを直接まさぐるのが手っ取り早いよねーということで、既存の手法、

  • strace
  • gdb
  • bulkdbg
  • gdbperl

に加え、拙作の inspect-perl-proc について話しました。

今のところ 3 つのことができます。

  • スタックトレースを採取する (perlのpackage名と行番号も表示されます)
  • パッケージ毎のメモリ使用量を採取する
  • %INCのダンプを採取する

キモは、コードの変更とかプロセスの再起動等々、ヘンテコ状態プロセスはいじらずそのままの状態で、外部からこれらの情報を採取できる、という点です。

Perlで書かれたWebアプリや常駐daemonの面倒をみたことがある人なら、「今動いてるこいつの状態をのぞきたい…」と思ったことが一度ならずあるはずと思うので、是非、ご活用いただければ幸甚です。

また、機構上、任意のPerlコードをターゲットのプロセス上で実行できるので、「こんなこともできるとイイネ!」というアイディアを思いついたら是非、プルリください。


YAPC::Asia 2013のスピーカーの方へ

スピーカーの人は、マイページ

から自分のトークの編集画面にいって、「スライドURL」のところに公開したスライドのURLを書いて欲しいです。

自分の場合、数年前のYAPC::Asiaのトークのスライドを見たいことがちょくちょくあって、過去のYAPC::Asiaのトーク一覧ページを見るのですが、そこにスライドのURLがちゃんと書いてあると未来のだれかの手間が省けていいかなーと思います。動画のURLとかも多分、トークのページから辿れるようになると思うんで、ここにポインタまとめておくと色々捗ると思います。

YAPC::Asiaの感想

残念ながら土曜日は参加できなかったんですが、初対面の人も含めいろんな人といろんな話ができて充実した1.5日間でした。

特に、懇親会で @ さんとの立ち話がステキにまとめられていて参考になりました。


あとは拙作の AWS::CLIWrapper がいくつかのトークで言及されていました。こういうのって作者冥利に尽きますね。

2013-09-13 (Fri)

ファイル指定で、ページキャッシュにのっているか確認したり追い出したり

ファイル指定で、ページキャッシュにのっているか確認したり追い出したりするPerlモジュールを書きました。

Linux なら動くはずですが、動かなかったら教えてください。あと一応、FreeBSD 8.3以上でも動くと思います。

既存の実装にGooglelinux-ftoolsやエヌハヤシ氏のpagecache-toolがありますが、これのPerlモジュール実装(XS)になります。


たまにfreeコマンドでみるとbuffers/cacheが食っててswapしてる(本当はbuffer/cacheを解放してメモリ割り当てて欲しいんですが…)サーバーがいます。

こういった状況を解消する/未然に防ぐために、ページキャッシュにのりがちなApacheのログファイルやMySQLのバイナリログファイルを明にページキャッシュから追い出すのに便利です。


あるファイルがページキャッシュにのっているか確認するには、Sys::PageCacheのfincore()関数を使って調べるか、同梱のpagecache-check.plを使えばよいです。

### 調べてみると、まだページキャッシュにのっていない
$ pagecache-check.pl dekai.log
dekai.log: cached/total_size=0/3221225472 cached/total_pages=0/786432

### catで読み捨てて、
$ cat dekai.log >/dev/null

### 再度調べると、ページキャッシュにのっていることが確認できる。
$ pagecache-check.pl dekai.log
dekai.log: cached/total_size=3221225472/3221225472 cached/total_pages=786432/786432

ページキャッシュから解放するには、Sys::PageCacheのfadvise()関数にPOSIX_FADV_DONTNEEDを添えて呼ぶか、同梱のpagecche-clear.plを使えばよいです。

### まず、ページキャッシュにのっているか調べる。
$ pagecache-check.pl dekai.log
dekai.log: cached/total_size=3221225472/3221225472 cached/total_pages=786432/786432

### pagecache-clear.pl でページキャッシュから追い出す。
$ pagecache-clear.pl dekai.log
dekai.log:
  before cached/total_size=3221225472/3221225472 cached/total_pages=786432/786432
  after  cached/total_size=0/3221225472 cached/total_pages=0/786432

### 念の為確認。
$ pagecache-check.pl dekai.log
dekai.log: cached/total_size=0/3221225472 cached/total_pages=0/786432

また pagecache-clear.pl にはファイルの先頭から何%の部分をページキャッシュから追い出すか指定することもできます。

$ pagecache-check.pl dekai.log
dekai.log: cached/total_size=3221225472/3221225472 cached/total_pages=786432/786432

### 先頭から70%ぐらいを追い出して、おしりの30%ぐらいはページキャッシュにのせたままにする
$ pagecache-clear.pl -r 0.7 dekai.log
dekai.log:
  before cached/total_size=3221225472/3221225472 cached/total_pages=786432/786432
  after  cached/total_size=966365184/3221225472 cached/total_pages=235929/786432

アクセスログやバイナリログなど、古い世代のファイルは全部ページキャッシュから追い出すけど、最新のファイルは少しページキャッシュにのせたままで先頭部分をページキャッシュから追い出す、といった処理も書けます。cronで動かしておくとよいですね。

2013-09-06 (Fri)

AWS::CLIWrapper-1.00 をリリースしました

先日 awscli が正式リリースされたので、

Perlのラッパーの AWS::CLIWrapper-1.00 をリリースしました。


awscli にはこれまで何度か互換性のない変更が行われており、不用意に awscli のバージョンを上げると古い awscli 向けに書いたスクリプトが動かなくなったりしていました。

正式リリースされたので、もうこうのような非互換変更は入らないだろうということで、できるだけ古いawscli向けに書いたスクリプトも新しいawscliで動くようにAWS::CLIWrapper側で非互換部分を吸収するようにしました。

awscli >= 0.14.0 は "Key", "Values", "Value", "Name" など先頭大文字のパラメータを要求する

filterやtagで使われるパラメータ名が、awscli < 0.14.0では"key", "values", "value", "name"と小文字だったのですが、0.14.0以降では先頭大文字になりました。

AWS::CLIWrapperは、awscliのバージョンを見て、内部的に大文字/小文字の変換します。

本来、このようなスクリプト

my $res = $aws->ec2('describe-instances' => {
    'filters' => [{ name => 'tag:Name', values => ["foo*"] }],
});

をawscli >= 0.14.0で動かすと(nameとvaluesが小文字なので)エラーになるのですが、AWS::CLIWrapper-1.00を使えば大丈夫です。

awscli >= 0.14.0 は ec2 run-instancesのパラメータに--countを要求する

awscli < 0.14.0では--min-countと--max-countだったのですが、>= 0.14.0では--count N or --count MIN:MAXに変わりました。

これもAWS::CLIWrapper-1.00ではawscliのバージョンを見てよきにはからってくれます。

awscli >= 0.15.0 のコマンド s3 と s3api

awscli < 0.15.0では"s3"コマンドしかなかったのですが、>= 0.15.0ではナント!"s3"が"s3api"に移動し、更にナント!ナント!! "s3"が全く別の高レベル操作のコマンドに変わりました。

AWS::CLIWrapper-1.00では、もしawscli >= 0.15.0でかつサブコマンドが低レベル操作(--list-bucketsとか--put-objectとか)のものだったら、内部的に "s3" の代わりに "s3api" を呼びます。これで古い時代に書かれたスクリプトも動きます。

返り値の型(互換対応あきらめ><)

awscliのバージョンによって、返される結果の構造が違います。

例えば elb describe-load-balancers の場合、awscli 0.9.3 だと

[
    {
        "DNSName": "xxx.elb.amazonaws.com",
        ...
    },
    ...
]

のようなリストが返るのですが、1.0.0だと

{
    "LoadBalancerDescriptions": [
        {
            "DNSName": "xxx.elb.amazonaws.com",
            ...
        },
        ...
    ],
    ...
}

のようにハッシュで返ってきます。

各コマンドの各サブコマンド×awscliのバージョンで網羅的に調べるのは大変なので、これはAWS::CLIWrapper側で対応するのはあきらめました。。。

かなりダサいですが、スクリプト側でこんな感じで互換対応してもらえればと思います。

for my $rs (@{ ref($res) eq 'ARRAY' ? $res : $res->{LoadBalancerDescriptions} }) {

ほかのawscliの非互換変更をみつけたら

是非、教えてください! できるだけAWS::CLIWrapper側で非互換を吸収する対応をしたいと思っています。

参考

2003 | 11 | 12 |
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 05 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 12 |
2012 | 01 | 02 | 03 | 06 | 08 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 |
2015 | 01 | 02 | 07 | 10 |
2016 | 01 | 05 | 10 | 12 |
2017 | 07 |
2018 | 05 |