Skip to main content
『Ficia』インフラと
 Perlにまつわる
   エトセトラ
    ひろせ まさあき
     id:hirose31
自己紹介

• ひろせ まさあき
 • id:hirose31
 • http://twitter.com/hirose31
• えとらぼ(株)
 • インフラの設計・構築・運用管理
http://ficia.com
アジェンダ
I. mod_perl 2 Tips & Tricks

 • メモリ関係のパラメータチューニング
 • Tips 3
II. 構成・運用支援ツールとPerl

 • MATRIXとその周辺
I
 mod_perl 2
Tips & Tricks

         Linux kernel 2.6.29.X
         Apache 2.2.X (Prefork)
         mod_perl 2.0.4
mod_perl 2 Tips & Tricks




           メモリ関係の
            パラメータ
           チューニング
推測するな
計測すべし
計  測
    ↓
パラメータの調整
メモリ使用量の計測
• ざっくりなら
 • ps, top
• fork(2) - Copy on Write
 • 書き込みがあるまで親プロセスと同
  じページをポイント

 • 親との共有領域と固有領域
CoW
  httpd                 httpd          httpd

 libperl               libperl        libperl
loaded                loaded         loaded
modules        fork   modules        modules
(startup.pl)          (startup.pl)   (startup.pl)

 variables                            variables
                       variables




   親                     子              子
CoW
  httpd                 httpd          httpd

 libperl               libperl        libperl
loaded                loaded         loaded
modules        fork   modules        modules
(startup.pl)          (startup.pl)   (startup.pl)

 variables                            variables
                       variables
                                     loaded
                                     modules
                                      variables




   親                     子              子
共有領域の計測

• /proc/PID/smaps (kernel >=2.6.14)
 • 共有領域 = Shared_Clean + Shared_Dirty
• shared_memory_size.pl $(pgrep httpd)
 • use Linux::Smaps
 • id:naoya♥♥
PID      VSZ     RSS   SHARED
20765   346040   59376    59064   (   99%)
20768   346040   59376    59064   (   99%)
20799   346040   59376    59064   (   99%)
20802   346040   59376    59064   (   99%)
PID      VSZ     RSS    SHARED
20765   346040   59376     59064   (   99%)
20768   346040   59376     59064   (   99%)
20799   346040   59376     59064   (   99%)
20802   346040   59376     59064   (   99%)


  PID      VSZ      RSS   SHARED
20765   433476   113716    45844   (   40%)
20768   433032   113432    46736   (   41%)
20799   434688   115000    45736   (   39%)
20802   435160   115548    45728   (   39%)
太る
  PID      VSZ     RSS    SHARED
20765   346040   59376     59064   (   99%)
20768   346040   59376     59064   (   99%)
20799   346040   59376     59064   (   99%)
20802   346040   59376     59064   (   99%)


  PID      VSZ      RSS   SHARED
20765   433476   113716    45844   (   40%)
20768   433032   113432    46736   (   41%)
20799   434688   115000    45736   (   39%)
20802   435160   115548    45728   (   39%)
太る#1 原因

• 子プロセスが、後でロードしたモジュー
 ルの分

• CoW故に
※子プロセス間ではメモリ共有はしない
太る#1 対策
• 使うモジュールは起動時に親プロセスでロード
 する

 • PerlPostConfigRequire startup.pl
• モジュールの一覧は?
 • PerlResponseHandler Apache2::Status
   • Loaded Modules で一覧を確認
☺ロード済みなので即戦力
太る#2 原因
• Perl内でのメモリアロケーション
 • メモリプール的な?
• もりもり太る例
 • slurp的な一気読み
 • File::Find - 再帰のせい?
• パフォーマンス、利便性との兼ね合い
太る#2 対策
• 太っているモジュールを探す
 • Apache2::Status + B::TerseSize
 • Memory Usage で一覧を確認
太る#2 対策
• メモリ食いのモジュールを:
 • 他のモジュールを使う
 • コードに手を入れる
 • スルー
計  測
    ↓
パラメータの調整
httpd.conf

StartServers
MinSpareServers
MaxSpareServers
MaxClients
MaxRequestsPerChild
httpd.conf
• {Start,{Min,Max}Spare}Servers,
 MacClient

 • smapsの結果と搭載メモリを鑑みて計算
 • 増減があるので、実際に変更して様子を
   見る

   • 「swapしたら負けかなと思ってる」
httpd.conf
• {Start,{Min,Max}Spare}Servers,
 MacClient

 • 全部同じ値にして、起動時に一気に
   fork(2)する

   • reqが来てはじめてよっこらせと
    fork(2)するのは時間がもったいない

   • 起動時にload avgが上がるのは運用で
    回避(Tipsで後述)
StartServers
         {Min,Max}Spare
#procs




               t
StartServers
         {Min,Max}Spare

                 fork!
#procs




             fork!

           fork!

         fork!



                         t
StartServers
         {Min,Max}Spare

                 fork!          fork!
#procs




             fork!
                               fork!
           fork!
                              fork!
         fork!
                             fork!



                         t
StartServers
         ={Min,Max}Spare
#procs




         idle




                t
StartServers
         ={Min,Max}Spare
fork!

fork!
#procs




fork!
         idle
fork!

fork!


                t
StartServers
         ={Min,Max}Spare
fork!

fork!           ♪∼
#procs




fork!
         idle
fork!

fork!


                     t
StartServers
         ={Min,Max}Spare
fork!

fork!           ♪∼       ♪∼
#procs




fork!
         idle
fork!

fork!


                     t
Apache Process
    Report
httpd.conf
• MaxRequestsPerChild
 • そこそこ小さい値に
 • 早期刈り取り
   • 肥大化
   • リーク
httpd.conf

StartServers          42
MinSpareServers       42
MaxSpareServers       42
MaxClients            42
MaxRequestsPerChild   64
httpd.conf

PerlOptions +Clone

PerlOptions +Parent
PerlOptions
• Clone
 • VirtualHostごとにインタプリタ
  プールを持つ (threadモードのとき
  のみ?)

• Parent
 • VHごとにインタプリタプールを持つ
  (=Clone)

 • VHごとに親インタプリタを持つ
+Parent

• VirtualHostごとに空間を分離できる
 • メモリ空間
 • 名前空間
• 反面、メモリ使用量が増える
 • multi Parent VS multi instance
mod_perl 2 Tips & Tricks




              Tips         3
#1 PerlSwitches
   とsymlink
• PerlSwitches
 • -I/path/to/mylibdir
 • -Mlib=/path/to/mylibdir
• 指定パスがsymlinkだと探しに行かない
 • failed to resolve handler...
#2 VirtualHostごとに
 ErrorLogを吐きたい
 • トップレベルのserverコンテキストの
     ErrorLogに出力されてしまう
warn "Test: warn";             #   warn
die "Test: die";               #   die
eval q[my $v2 = "3:" + 4;];    #   eval
my %h1 = qw(foo bar baz);      #   実行時エラー


print STDERR "Test: STDERRn"; # STDERR
my $v1 = "2:" + 3;             # use warnings
(undef) . "xxx";               # use warnings
#2 VirtualHostごとに
 ErrorLogを吐きたい
 • warn            #httpd.conf
                   PerlOptions ... +GlobalRequest
 • die
 • eval
                   #Handler
                   use Apache2::Log ();

 • 実行時エラー          $SIG{__WARN__} =
                     &Apache2::ServerRec::warn;




•   STDERR         *STDERRをtieしてprint STDERRを
                   Apache2::ServerRec::warnにする




•   use warnings            未解決 情報求む!
#3 init.d/httpd
• 問題点
• stop
 • stopしたのに新規リクエストが来ちゃう
 • ロードバランサのヘルスチェック間隔
• start
 • 起動直後にリクエストがきちゃう
 • fork(2)しまくって高負荷なのでちょっ
  と待ちたい
#3 init.d/httpd
• httpdが生きている状態でも、LBの
  VirtualServerGroup(VSG)から離脱できる
  ようにする

• LBのヘルスチェックURLを動的なものに
 • curl -H ‘Host: health’ http://svXXX/alive.php
 • フラグファイルによってres codeを変える
   •   touch -t '+1 hours' /tmp/stop-sv

 • now - mtime <= 5分 ? 503 : 200
#3 init.d/httpd
• stop
 • configtest
 • ロードバランサのVSGから離脱
 • apachectl -k graceful-stop
 • clear semaphore (ipcs -s, ipcrm)
• start
 • VSGに参加しないようにする
 • configtest
 • apachectl -k start
 • sleep 3 && VSGに復帰
続いて
II
構成・運用支援ツール
   とPerl
問題提起
• サーバがたくさんあると・・・
 • どのサーバがどの役割だっけ?
 • 1サーバで複数の役割を持ってるさらに混乱
 • 役割変更のたびにOSインストールと
   か・・・
• 管理情報がいろんなところにあって収集つか
  ない
解決案

• 構成管理情報の一元管理
• テキスト形式
 • 人が読めて編集できる
• 数十台ならこんな簡単な形式でもOK
svNNN
realname               MATRIX                    (XXX)
                                                  remark

              sv101:   <lv1>
              sv102:   <ll2>                       [TTNNN]
              sv103:   <lv2>                        Complex
              sv104:   <ll1>
<TTNNN>
 systemname   sv105:   <co1>     (core)
 Archetyp     sv106:   <co2>
              sv107:   <ap101>   ficia irori [mc101]
                                                           XXXXX
              sv108:   <ap102>   ficia *FREE*              assigned prj
              sv109:   <ht101>   ficia irori [qu101]
              sv110:   <ht101>   [qu102]
              sv111:   <db101>   (db100)
              sv112:   <db102>                     *XXX*
              sv113:   <st101>   (st100)            special state
              sv114:   <st102>
              sv115:   <ap103>   ficia *STOP*
Archetyp
          and
        Complex



sv101       sv102       sv103

        /           /           /
Archetyp
                and
              Complex


      core                    Web
                  Web         static
                  app
      sv101       sv102       sv103
Archetyp      /           /            /
Archetyp
                 and
               Complex
 Q4M
                                kumo
                   Q4M                        log
       core
                         kumo     Web
                    Web           static
                    app         mcd
       sv101        sv102             sv103
Archetyp       /            /                   /
Complex
MATRIXの反映

• activate-matrix (with Perl)
 • 3 steps
   1.ActivateMATRIX::Generate::*

   2.ActivateMATRIX::Execute::*

   3.ActivateMATRIX::Suggest::*
Generate

• as YAML
 • ganglia (PHP)
 • Archer (Perl)
• Nagios host.cfg
• OS起動時に読む用(役割切り替え)
 • shでハンドリングしやすい形式
Execute

• 起動時にMATRIXを読んで、あとは参照せず
 にループするdaemonの類いを再起動/再読
 み込み

• monitor-ping (AnyEvent::FastPing)
Suggest

• 残作業とかを表示
 • 自動でやるのはちと怖いのとか
• ロードバランサへの反映手順
 • generate config, copy , diff, apply
MATRIXと
         その周辺

edit!    MATRIX
        sv101:   <lv1>
        sv102:   <ll2>
        sv103:   <lv2>
        sv104:
        sv105:
        sv106:
                 <ll1>
                 <co1>
                 <co2>
                           (core)                           ...
        sv107:   <ap101>   ficia irori [mc101]
        sv108:   <ap102>   ficia *FREE*
        sv109:   <ht101>   ficia irori [qu101]
        sv110:
        sv111:
                 <ht101>
                 <db101>
                           [qu102]
                           (db100)               activate
        sv112:   <db102>
        sv113:
        sv114:
        sv115:
                 <st101>
                 <st102>
                 <ap103>
                           (st100)

                           ficia *STOP*
                                                  matrix    ...
まとめ
I. mod_perl 2 Tips & Tricks

 • メモリ関係のパラメータチューニング
 • Tips 3
II. 構成・運用支援ツールとPerl

 • MATRIXとその周辺
ご清聴ありがとう
 ございました