Quantcast
Channel: しのぶら!!! » sawanoboly
Viewing all articles
Browse latest Browse all 15

mod_load_monitorでリクエストをredisにカウントする

$
0
0

apache httpd のモジュールとして mod_load_monitor というのが作られました。

開発は @matsumotory さん、経緯などは下記からたどっていこう。

ちょっとだけ遊んでみました。
人間とウェブの未来 – ロードアベレージを監視して任意のコマンドを実行する(Apacheで)

httpdのリクエスト処理をフックしてサーバのLoadAverageを計測、閾値によりコマンド実行。

折角なので実行するコマンドの例示として、閾値Overのリクエストを個別に集計してみよう。

mod_load_monitorの設定

集計にはredisを使って任意のキーをincrementする方式でカウントしてみる。

LoadModule load_monitor_module /usr/lib/apache2/modules/mod_load_monitor.so
LoadMonitorOver  1.0 "/usr/bin/redis-cli -s /var/run/redis/redis.sock -n `date +%m` incr over_$LOAD_MON_FILENAME"
LoadMonitorUnder 1.0 "/usr/bin/redis-cli -s /var/run/redis/redis.sock -n `date +%m` incr under_$LOAD_MON_FILENAME"

本来必要なコマンドは redis-cli incl $key だけで、任意KeyのValueが数だったら1つ増やすという処理。これを下記要領で。

  • 現在月をDBのindexにした、ラクチンな月ごと集計!
    • system()を使っているのでdateの箇所に展開が使える
  • とりあえずファイルパスをキーにカウント、prefixでover/underを判別
  • 接続をUnixソケットに

redisをモニターしながらアクセス

アクセス毎にインデックス7番のDBに対してincrが発行されているのがわかる。

redis 127.0.0.1:6379[7]> MONITOR
OK
1343363853.354785 (db 7) "MONITOR"
1343363856.543896 (db 7) "SELECT" "7"
1343363856.544411 (db 7) "incr" "under_/var/www/favicon.ico"
1343363857.488522 (db 7) "SELECT" "7"
1343363857.488986 (db 7) "incr" "under_/var/www/favicon.ico"
1343363859.188487 (db 7) "SELECT" "7"
1343363859.189031 (db 7) "incr" "under_/var/www/5"
1343363859.378521 (db 7) "SELECT" "7"
1343363859.379157 (db 7) "incr" "under_/var/www/5/"
1343363859.648242 (db 7) "SELECT" "7"
1343363859.648668 (db 7) "incr" "under_/var/www/5/"
1343363860.273772 (db 7) "SELECT" "7"
1343363860.274207 (db 7) "incr" "under_/var/www/7"
1343363860.453436 (db 7) "SELECT" "7"
1343363860.453912 (db 7) "incr" "under_/var/www/7/"
1343363860.628093 (db 7) "SELECT" "7"
1343363860.628502 (db 7) "incr" "under_/var/www/favicon.ico"

キーが作られている様子。

> keys under*
1) "under_/var/www/5/"
2) "under_/var/www/5"
3) "under_/var/www/7/"
4) "under_/var/www/favicon.ico"
5) "under_/var/www/7"

キーの中身、カウントになっている。

> mget under_/var/www/favicon.ico under_/var/www/7/
1) "3"
2) "1"

最初からログをMapReduceしたようなKey/Valueになります。

実際にカウントするならVirtualHost名でやるのが一番使いでがありそう。

パフォーマンスへの影響

当たり前のように甚大です。軽くabしてみます、多重5の2000リクエスト。

まずredisフックなし、2450rpsほど。

Concurrency Level:      5
Time taken for tests:   0.816 seconds
Complete requests:      2000
Failed requests:        0
Write errors:           0
Total transferred:      1404000 bytes
HTML transferred:       850000 bytes
Requests per second:    2450.81 [#/sec] (mean)
Time per request:       2.040 [ms] (mean)
Time per request:       0.408 [ms] (mean, across all concurrent requests)
Transfer rate:          1680.14 [Kbytes/sec] received

Redisフック、273rpsとなった、軽く10%程度にまで落ち込む。

Concurrency Level:      5
Time taken for tests:   7.300 seconds
Complete requests:      2000
Failed requests:        0
Write errors:           0
Total transferred:      1404000 bytes
HTML transferred:       850000 bytes
Requests per second:    273.97 [#/sec] (mean)
Time per request:       18.250 [ms] (mean)
Time per request:       3.650 [ms] (mean, across all concurrent requests)
Transfer rate:          187.82 [Kbytes/sec] received

一応シンプルにファイル追記にした場合は450rpsほどでした。

LoadMonitorUnder 1.0 "echo $LOAD_MON_FILENAME >> /tmp/under"

お遊び色のモジュールに便乗してやってみたネタなのでこんなもんで。

credisでやったらちゃんと早いんだろうな。

追記: 集計をまとめる

redis上でkeysからhashに移せば hgetallでひとまとめのJsonとして受け取れる。

MapReduceのようだ。


> r = Redis.new
> r.select 7
> r.keys.each { |k| r.hset("2012-07", k, r.get(k)) }

> puts JSON.pretty_generate(r.hgetall("2012-07")  )
< {
<   "under_/var/www/5/": "2",
<   "under_/var/www/5": "1",
<   "under_/var/www/7/": "1",
<   "under_/var/www/favicon.ico": "3",
<   "under_/var/www/7": "1",
<   "under_/var/www/3/": "2000"
< }

Viewing all articles
Browse latest Browse all 15

Trending Articles