文字列から特定桁の数字を抜き出す

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の適正値調べた

参考.


わけあってMaxClientsの設定を色々調べました。初っ端から言い訳ですが勉強中なので、あまり鵜呑みにしないでください。

追記

topのSHRの項目が共有メモリサイズだと思ってたけど、naoyaさんのblogによると違うらしい。

なので↓に出てくるtopのSHMを使っている計算は間違ってる模様。同URLのperlLinux::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を詳しく解説されてる記事を参照。

  • RSS: プロセスが使っている物理メモリサイズ
  • SHR: 共有されているメモリサイズ

forkされた子プロセスが使うメモリは全て個別ではなくて、ある程度は共有されているのでMaxClientsを掛ける値は、(RSS - SHR)でいい。ということで計算式が変わって、

(RSS - SHR) * MaxClients <= OSメモリ容量

じゃ、RSSとかSHRとか、プロセスが消費するメモリ量はどうやって調べるのか。

プロセスの消費メモリ量の調べ方

SHR: 共有されているメモリサイズ

topのSHRの項目を確認する。psでの見方はわかりませんでした。

RSS: プロセスが使っている物理メモリサイズ

ps、topのRSSの項目を確認する。静的なページ(mod_phpmod_perlを使わない)の場合は、数M程度。httpdのサイズにも依存すると思うので、あまり使用しないモジュールはstaticに組み込まないほうが良い。
(これは使用メモリ量に限った話ではないと思いますが)


mod_phpmod_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
メモリ使用量まとめ

RSS: 子プロセスの平均消費物理メモリ => 16M
SHR: 子プロセスの平均消費共有メモリ => 11M

MaxClients計算
  • (16-11) * MaxClients + "apache 親プロセス使用メモリ" + ""OSその他の使用メモリ" < 4000
  • (16-11) * MaxClients < 4000 ## 親プロセス、OS等は思い切って省略!!
  • 5 * MaxClients < 4000
  • MaxClients < 800

というわけでこの場合、MaxClientsは800が上限!
サーバの設定みたら1000だったよ。あわわわ。