文字列から特定桁の数字を抜き出す
project eulerの8問目を見てて、ふと疑問に思った。
この場合、まず数値列(文字列)から全ての5桁の数字を取ってきたいとする。簡単にするために、20桁の数値列で考える。
$str = '0123456789' x 2; while ($str =~ m/(\d{5})/g) { print $1, "\n"; }
これだと、5桁の数字が
01234 56789 01234 56789
こう出てくるんだけど、そうじゃなくて
01234 12345 23456 34567 45678 56789 ...
ってやるにはどうしたらいいんだろう。
追記 (一応解決した)
pos関数でマッチしたオフセットをシフトさせればいいのかな。
$str = '0123456789' x 2; while ($str =~ m/(\d{5})/g) { print $1, "\n"; pos($str -= 4; }
とやって、マッチする毎にオフセットを4つ前に戻せば望み通りのことはできました。なんだかad hocな感じがするけど :-)
追記2
commentでツッコミいただいたのでsubstrでやってみる。
こんなのでいいですか><
$length = length $str; for $i (0..$length) { $num = substr($str,$i,5); next if $num =~ m/\D/; last if length $num != 5; print "$num\n"; }
追記3
いやいや、こんなことしなくても正規表現で先読みすりゃいいだけじゃないか。
$str = '0123456789' x 2; while ($str =~ m/(?=(\d{5}))/g) { print $1, "\n"; }
先読みでゼロ幅だからマッチ位置は変わらないけど、/gがあるのでループごとに1つ進む。
crondのログをmessagesに出力させない
/var/log/messages
May 3 12:12:01 hoge crond(pam_unix)[13044]: session opened for user root by (uid=0) May 3 12:12:02 hoge crond(pam_unix)[13044]: session closed for user root
cronが実行されるたびに、こんなのがいっぱい出てくるけど邪魔ずら。どうもfacilityがauth、priorityがinfoらしいので、/etc/syslog.confを変更する。
/etc/syslog.conf
#*.info;mail.none;authpriv.none;cron.none; /var/log/messages *.info;mail.none;authpriv.none;cron.none;auth.!=info /var/log/messages auth.info /var/log/authinfo
apacheのMaxClientsの適正値調べた
参考.
- http://www.typemiss.net/blog/kounoike/20060202-61
- http://d.hatena.ne.jp/babie/20060201/p3
- http://yutuki.blogspot.com/2007/08/apache-maxclients.html
- http://d.hatena.ne.jp/hideden/20080409/1207740439
わけあってMaxClientsの設定を色々調べました。初っ端から言い訳ですが勉強中なので、あまり鵜呑みにしないでください。
追記
topのSHRの項目が共有メモリサイズだと思ってたけど、naoyaさんのblogによると違うらしい。
なので↓に出てくるtopのSHMを使っている計算は間違ってる模様。同URLのperlのLinux::Smapsを使ってメモリ情報を見ると、topで表示されるSHMより多いメモリ量を共有しているぽい。ということは、この例でもMaxClientはもう少し大きくできるはず。次回計算するときはLinux::Smapsで取った値で計算しよう。
例
/procから取った値で計算したほうが共有しているメモリサイズが多く表示されている。
- /proc以下の情報
# perl shared_memory_size.pl `pgrep httpd` | head -5 PID RSS SHARED 2168 9216 6548 (71%) 2169 9488 6600 (69%) 2170 9324 6524 (69%) 2171 9412 6708 (71%)
- top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2168 apache 15 0 149m 9216 3716 S 0.0 0.1 0:00.35 httpd 2169 apache 15 0 150m 9488 3352 S 0.0 0.1 0:00.31 httpd 2170 apache 15 0 149m 9324 3716 S 0.0 0.1 0:00.38 httpd 2171 apache 15 0 149m 9412 3880 S 0.0 0.1 0:00.31 httpd
### 追記ここまで
MPMがworkerの場合
>> 結論:良くわからず
メモリに関してはスレッド間で共有するので、あまり気にしなくてよい?CPUの強さ、コンテンツ、アクセス数との兼ね合いでload averageが増えすぎないように適当に設定。Quad Coreのweb専用サーバ、かつ静的コンテンツだけならMaxClientsは数千ぐらいはいけるかな。
すいません、適当です><
MPMがpreforkの場合
リクエストごとに子プロセスが応答してメモリを使うので、増やしすぎに注意。大雑把に言うと、次の式を満たせばいい?
子プロセスの消費メモリサイズ * MaxClients < OSメモリ容量
実際にはOSとapache親プロセスが使用するメモリも考えないといけない。が、preforkした子プロセスが使うメモリと比較して小さいと思うので無視して計算した。
ただ、これは子プロセスが使ってるメモリが全く共有されてないとして計算した数字なので、MaxClientsはもう少し大きい数値でも良いはず。この辺りはnaoyaさん他、copy on writeを詳しく解説されてる記事を参照。
forkされた子プロセスが使うメモリは全て個別ではなくて、ある程度は共有されているのでMaxClientsを掛ける値は、(RSS - SHR)でいい。ということで計算式が変わって、
プロセスの消費メモリ量の調べ方
RSS: プロセスが使っている物理メモリサイズ
ps、topのRSSの項目を確認する。静的なページ(mod_php、mod_perlを使わない)の場合は、数M程度。httpdのサイズにも依存すると思うので、あまり使用しないモジュールはstaticに組み込まないほうが良い。
(これは使用メモリ量に限った話ではないと思いますが)
mod_php、mod_perl使ってる場合は数10Mぐらい行くようです。なので、いかに使用メモリのうち共有させるかがミソのようです。これについてはmod_perlで親プロセスとのCopy on Writeな共有メモリを増やす方法。 - Perlとかmemoとか日記とか。参照。
実際の某サーバの設定を検討
というわけで、ここまで来たのであるサーバを調べてみる。
OS:CentOS 4.4
memory: 4G
apache 1.3.37
app: php 4.4.4
httpdのsize: 1.8M
topの一部
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 7235 nobody 15 0 38252 16m 11m S 0 0.4 0:06.60 libhttpd.ep 7258 nobody 16 0 37360 15m 11m S 0 0.4 0:06.51 libhttpd.ep 7268 nobody 16 0 37360 15m 11m S 0 0.4 0:06.88 libhttpd.ep 7240 nobody 16 0 37356 15m 11m S 0 0.4 0:07.28 libhttpd.ep
psの一部
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 3126 0.0 0.0 35348 4100 ? Ss 2007 0:14 /usr/local/apache/bin/httpd nobody 7228 0.0 0.3 37476 15840 ? S 04:02 0:07 /usr/local/apache/bin/httpd nobody 7229 0.0 0.3 37092 15436 ? S 04:02 0:07 /usr/local/apache/bin/httpd nobody 7230 0.0 0.3 37096 15168 ? S 04:02 0:06 /usr/local/apache/bin/httpd nobody 7231 0.0 0.3 37388 15840 ? S 04:02 0:06 /usr/local/apache/bin/httpd
MaxClients計算
- (16-11) * MaxClients + "apache 親プロセス使用メモリ" + ""OSその他の使用メモリ" < 4000
- (16-11) * MaxClients < 4000 ## 親プロセス、OS等は思い切って省略!!
- 5 * MaxClients < 4000
- MaxClients < 800
というわけでこの場合、MaxClientsは800が上限!
サーバの設定みたら1000だったよ。あわわわ。