rpmで依存するライブラリが含まれるパッケージをYumで検索する

Yumはなにも考えなくても依存関係を綺麗に調整してくれるから、便利だと思う。
しかしながら、どうしてもrpmパッケージをインストールしたいことは多々ある。

先日、rpmのインストールをしようとした所、下記依存関係のエラーが出た。

libssl.so.6()(64bit) is needed by HOGEHOGE

ありがちなエラーである。
さて、みなさんはこんなエラーが出たらどうするだろうか。
私は、今までこのようなエラーが出たら、ググッて解決していた。
先人のみなさんがブログなどに必ず残していてくれるから、まずまず解決できることが殆どだった。
しかしながら、たまたま色々調べていたらこんな記事を見つけた。

なんと、依存するライブラリをYum検索できるらしいのだ。ねぇみんな知ってた? 知ってるって? あぁそうでしたか…。

試しに上記ライブラリを検索してみた。

[vagrant@test vagrant]$ yum whatprovides libcrypto.so.6
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: ftp.tsukuba.wide.ad.jp
 * epel: ftp.kddilabs.jp
 * extras: ftp.tsukuba.wide.ad.jp
 * updates: ftp.tsukuba.wide.ad.jp
openssl098e-0.9.8e-20.el6.centos.1.i686 : A compatibility version of a general cryptography and TLS library
Repo        : base
Matched from:
Other       : libcrypto.so.6

おおぅ!ちゃんと出てくるではないか。。

ブログにもある通り、検索対象は/etc/yum.repos.d/配下のリポジトリなので、野良rpmはヒットしない。
だけど、標準のリポジトリ内のパッケージであればこのように検索出来るようだ。

今まで幾度と無くrpmパッケージをインストールしてきては、怒られたら地道にググッて依存関係を解決していたのだけど、今後はもう少し時間を短縮できそうだ。
ブログを書かれた方には感謝したい。

まだまだ知らないオプションは沢山ありそうだから、たまにはmanコマンドを眺めて知らないオプションを使ってみることにしよう。

apacheのprefork MPMについて

こんにちは、いなむーです。

今回はapacheのMPM(マルチプロセッシングモジュール)について、再度色々勉強したものをまとめておこうと思います。
(誤りがありましたらご指摘ください!)
また、今回はMPMと言いつつも、preforkモデルの取り扱いが多いので、preforkに焦点をあてて調べていきます。

参考にしたサイトはこちら。apache公式ドキュメント

MPMとは

公式ドキュメント引用
スレッドを使わず、先行して fork を行なう ウェブサーバを実装しています。 スレッドセーフでないライブラリとの互換性をとるために、 スレッドを避ける必要のあるサイトでは、このモジュールの使用が適切でしょう。 あるリクエストで発生した問題が他のリクエストに影響しないように、 個々のリクエストを単離するのにも、最適な MPM です。

親となるプロセスをpre”事前”にfork”分岐”(複製)するのがprefork式です。workerでは、プロセスをforkせずにスレッド同士でメモリなどを共有するので、効率的に処理が行える反面、問題のあるリクエストがあった場合に、共有しているスレッド同士も影響が発生します。それを避けるのに適した方式がpreforkだと書かれています。

各ディレクティブについては様々なサイトで既に書かれていますが、自分用に残しておきます。

StartServers

  • 起動時に生成される子サーバプロセスの数
  • 動的に制御される

    MaxSpareServers

  • アイドル状態のサーバープロセス数の最大個数を設定

    アイドル状態なので、リクエスト処理していないプロセスです。
    リクエストが増えると、MaxClientsまでプロセスをforkしていきます。
    アイドル状態のプロセスが、MaxSpareServersよりも多い状態になった場合は、その値までプロセスをkillしていきます。

    MinSpareServers

  • アイドル状態のサーバープロセス数の最低個数を設定

    これもアイドル状態なので、リクエスト処理していないプロセスです。
    アイドル状態のプロセスがこの値よりも少なくなったら、プロセスは最高で1秒につき1個の割合で新しい子プロセスを生成するようです。

    ServerLimit

  • MaxClientsに設定可能な上限値
  • ServerLimitはデフォルトが256。
  • 256よりも大きい値を設定する場合は、Maxclientsディレクティブよりも上に記述する必要がある。
  • workerモデルの場合に、ThreadsLimitと組み合わせてMaxClientsに設定可能な値を設定する。

    preforkの場合はServerLimitとMaxClientsの値をべつべつに設定する意味がないので、同じ値を設定しておくと良いように思います。

    MaxRequestPerChild

  • 個々の子プロセスが稼働中に扱うリクエスト数の上限
  • 子プロセスがMaxRequestPerChildの値だけリクエストを受け付けると、プロセスからは終了する。

    各プロセスの遷移はこちらのメルカリのエンジニアさんが6年前に書かれた内容が大変分かりやすいです。

    こちらに書かれている通り、forkはリソースを大変消費するため、StartServers,MaxSpareServers,MinSpareServersは値を同じにしておくと良さそうであるということには、納得と理解ができました。

    しかしながら、MaxClientsについては、気になる記述があります。
    正確にはMaxClientsではなく、ServerLimitで、

    公式ドキュメント引用
    このディレクティブを使用する際は特に注意してください。 ServerLimit が必要以上に大きな値に 設定された場合は、余計な未使用共有メモリが割り当てられます。

    という記載がありました。
    しかしながら、上記記事を確認すると、LinuxはCoWがあるのでそこまでメモリを使用しないという記事がありました。


    CoWでは、親プロセスのメモリ空間をコピーし、メモリーのデータはコピーしないため、forkした直後ではメモリーは消費していない状態であるためです。
    もちろん子プロセスそれぞれが稼働していくと、個別にメモリーを確保していくためメモリー使用率はあがっていきます。

    ちなみに、MinSpareServersやMaxSpareServersの値を同じにするのなら、なんでこのディレクティブがあるのか?と思い、かなり調べたのですがそれらしい記述は見当たりませんでした。
    これは恐らくですが、これらのディレクティブが出た当初は、サーバーには複数のミドルウェアと複数の機能を同居させ、リソースも潤沢に無かったであろう時代だったのかと思います。
    Apacheが稼働していない時は、無駄なプロセスは開放していき、他のプロセスにリソースを回すことを優先されたのではないかと勝手に推測しました。
    ※私がサーバー管理をし始めた頃でも、まだ貧弱なサーバーでウェブサイトを運営してたりして、OOM killerとかで死んだとかはよくありました。今では余程メモリをバカ食いするor致命的なメモリリークとか無い限り、OOM killerは見なくなりました。

    色々パラメータについての理解は深まりましたが、実際にプロセスの数はどのような動きをするのかを試してみました。

    MaxSpareServers

    MaxRequestsPerChildに関わらず子プロセスはリクエスト処理が完了すると、すぐにkillされる。

    MaxSpareServers   20
    ServerLimit      30
    MaxClients       30
    MaxRequestsPerChild  40000
    
    $ ab -n 10000 -c 200 http://localhost/
    

    プロセス数が31になるまで何度か繰り返す

    grep -fl "/sbin/httpd" | wc -l
    31
    :
    21
    

    プロセスが31になるが、abが終わるとすぐに21(MaxSpareServersの値)までプロセス数が下がることが分かる。

    MaxRequestsPerChild

    値が低いと子プロセスのkillとforkを頻繁に繰り返す。

    下記では「MaxRequestsPerChild」を「10」にしてテストしてみました。

    StartServers       8
    MinSpareServers    5
    MaxSpareServers   20
    ServerLimit      30
    MaxClients       30
    MaxRequestsPerChild  10
    
    $ ab -n 3000 -c 30 http://localhost/
    
    Time taken for tests:   22.767 seconds
    
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Total:          1  227 409.3     20    2019
    

    そうすると、このリクエストでは約23秒かかってます。
    次に、他のパラメータは同じで、「MaxRequestsPerChild」を「100」に設定して、テストしてみます。

    テストパターン2

    MaxRequestsPerChild  10 -> 100
    
    Time taken for tests:   4.729 seconds
    Connection Times (ms)
                  min  mean[+/-sd] median   max
    Total:          2   47 189.2      4     999
    

    abも同じでテストしましたが、結果、約5秒まで短縮されました。
    「MaxRequestsPerChild」が少ないと、子プロセスが頻繁にforkされ、killされるので、その間はクライアントは待たされてしまうという結果が出ました。
    この値は公式ドキュメントにもあるようにメモリーリーク対策になるため、起動プロセス数のピーク時に合わせて、値を検討していくと良さそうに思われます。

    その他検証してわかったこと

    MaxClients以上にStartServersを設定しても、プロセスは生成されませんでした。
    当たり前と言えばそうなのですが、「へぇ〜」という気持ちになりました。

    apacheは手軽にインストールでき、安定して稼働する素晴らしいソフトウェアです。
    デフォルト値でもサービス稼働できてしまうミドルウエアの1つでもあります。
    その反面、Webサーバーという多種多様なアプリケーションに対応するため、アクセスが多いサイトでは、デフォルト値では捌ききれない場合があります。
    また、CPUやメモリー、アプリケーションのキャッシュ、ディスクIO、スループット、バックエンドとの接続など、ありとあらゆる要素によって、処理能力に差が出てきます。

    今回の検証で、ベンチマークテストが重要であることを再認識出来た結果と言えます。
    今後もテストケースを重ねて、対象ホストで最適なパラメータチューニングが出来るように精進しようと思いました。

    以上。

  • Linuxサーバーで消してしまったファイルを復元してみる

    はてなブックマークを見ていたところ、下記エントリーを発見しました。

    彼は新卒研修時に誤って消してしまったファイル郡を自力で復元したという強者のようですが、インフラ屋さんとしては、使うことがなかったとしても(使いたくない。。。)、知っておいて損は無いなと思い、全く同じように検証してみました。

    まずは事前に準備しておきます。

    環境 CentOS6
    ファイルシステム ext4
    

    ext3,ext4にのみ対応しているようです。xfsは非対応の様子というか復元不可能?

    $ yum -y install e2fsprogs-devel
    

    これが無いとコンパイル時に怒られます。

    extundeleteをダウンロードして、ホームディレクトリへ保存しておきます。

    コンパイル手順です。

    $ tar xfvj extundelete-0.2.4.tar.bz2
    $ mkdir ~/mytmp
    $ ./configure --prefix=/home/kazuma/mytmp
    Configuring extundelete 0.2.4
    Writing generated files to disk
    $ make && make install
    make -s all-recursive
    Making all in src
    extundelete.cc:571: 警告: unused parameter ‘flags’
    Making install in src
    /usr/bin/install -c extundelete '/home/kazuma/mytmp/bin'
    $ ls -l ~/mytmp/bin/extundelete
    -rwxr-xr-x 1 kazuma kazuma 1187055 4月 10 23:53 2016 /home/kazuma/mytmp/bin/extundelete
    

    以上でコンパイルが完了です。

    次に削除→復元を実施してみます。

    $ cd ~/mytmp/
    $ mkdir testdir
    $ cd testdir
    $ touch test{0..99}.txt
    $ echo "hoge" > ./*.txt
    $ rm -rf testdir
    

    削除を実施してみました。
    次にhistoryから削除コマンドを実施したタイミングを確認します。

    # zsh
    $ history -i
    67 2016-04-11 00:17 rm -rf testdir
    
    # bash
    $ HISTTIMEFOMRMAT="%F %T" history
    ログアウトすると設定が消える。
    

    ファイルを復元してみます。

    $ date
    2016年 4月 11日 月曜日 00:22:21 JST
    
    $ sudo bin/extundelete --restore-all --after $(date +%s -d '2016-04-11 00:16') /dev/vg01/lv_home
    Only show and process deleted entries if they are deleted on or after 1460301360 and before 9223372036854775807.
    NOTICE: Extended attributes are not restored.
    WARNING: EXT3_FEATURE_INCOMPAT_RECOVER is set.
    The partition should be unmounted to undelete any files without further data loss.
    If the partition is not currently mounted, this message indicates
    it was improperly unmounted, and you should run fsck before continuing.
    If you decide to continue, extundelete may overwrite some of the deleted
    files and make recovering those files impossible. You should unmount the
    file system and check it with fsck before using extundelete.
    Would you like to continue? (y/n)
    y
    Loading filesystem metadata ... 40 groups loaded.
    Loading journal descriptors ... 30565 descriptors loaded.
    Searching for recoverable inodes in directory / ...
    153 recoverable inodes found.
    Looking through the directory structure for deleted files ...
    Unable to restore inode 145199 (kazuma/Maildir/.Trash/Mob Psycho 100 v06.rar): No undeleted copies found in the journal.
    Unable to restore inode 825 (kazuma/.vim/.netrwhist~): No undeleted copies found in the journal.
    Unable to restore inode 145300 (kazuma/bash-config/.git/refs/heads/master.lock): No undeleted copies found in the journal.
    Unable to restore inode 145277 (kazuma/bash-config/.git/refs/heads/add-install-shell.lock): No undeleted copies found
    in the journal.
    Unable to restore inode 145298 (kazuma/bash-config/.git/refs/heads/add-install-shell): No undeleted copies found in the journal.
    Unable to restore inode 145299 (kazuma/bash-config/.git/refs/remotes/origin/master.lock): No undeleted copies found in the journal.
    Unable to restore inode 145284 (kazuma/bash-config/.git/objects/pack/pack-f7f0571b9953eac493d1e32a45d01f5ee791245d.keep): No undeleted copies found in the journal.
    Unable to restore inode 1083 (kazuma/bash-config/.git/logs/refs/heads/add-install-shell): No undeleted copies found in the journal.
    Unable to restore inode 145362 (kazuma/bash-config/.bashrc.swp): No undeleted copies found in the journal.
    Unable to restore inode 145363 (kazuma/bash-config/.bashrc.swx): No undeleted copies found in the journal.
    Unable to restore inode 145202 (kazuma/drop_wpadmin_atack/log/.drop.sh.swp): No undeleted copies found in the journal.
    Unable to restore inode 145205 (kazuma/drop_wpadmin_atack/log/.drop.sh.swx): No undeleted copies found in the journal.
    Unable to restore inode 145204 (kazuma/drop_wpadmin_atack/drop.sh~): No undeleted copies found in the journal.
    Unable to restore inode 145339 (kazuma/serverlist/lib/serverlist/.swp): No undeleted copies found in the journal.
    Unable to restore inode 145358 (kazuma/serverlist/lib/serverlist/.swpx): No undeleted copies found in the journal.
    Unable to restore inode 145308 (kazuma/serverlist/lib/.serverlist.rb.swp): No undeleted copies found in the journal.
    Unable to restore inode 145297 (kazuma/serverlist/.git/refs/heads/test.lock): No undeleted copies found in the journal.
    Unable to restore inode 145340 (kazuma/serverlist/.git/refs/remotes/origin/test.lock): No undeleted copies found in the journal.
    Unable to restore inode 145341 (kazuma/serverlist/.git/config.lock): No undeleted copies found in the journal.
    Unable to restore inode 145311 (kazuma/serverlist/serverlist.gemspec~): No undeleted copies found in the journal.
    Unable to restore inode 144842 (postgres/data/pg_xlog/archive_status/GMT): No undeleted copies found in the journal.
    Unable to restore inode 144844 (postgres/data/pg_xlog/archive_status/UCT): No undeleted copies found in the journal.
    Unable to restore inode 144843 (postgres/data/pg_xlog/archive_status/UTC): No undeleted copies found in the journal.
    Unable to restore inode 144845 (postgres/data/pg_subtrans/Riyadh87): No undeleted copies found in the journal.
    Unable to restore inode 144837 (postgres/data/pg_multixact/offsets/Rio_Branco): No undeleted copies found in the journal.
    Unable to restore inode 144840 (postgres/data/pg_multixact/offsets/Curacao): No undeleted copies found in the journal.Unable to restore inode 144841 (postgres/data/pg_multixact/offsets/Port_of_Spain): No undeleted copies found in the journal.
    Unable to restore inode 145408 (lost+found/conftest.TPo): No undeleted copies found in the journal.
    Unable to restore inode 145279 (lost+found/HEAD): No undeleted copies found in the journal.
    Unable to restore inode 1078 (lost+found/logs): No undeleted copies found in the journal.
    Unable to restore inode 145291 (lost+found/COMMIT_EDITMSG): No undeleted copies found in the journal.
    Unable to restore inode 145203 (lost+found/drop.sh): No undeleted copies found in the journal.
    20 recoverable inodes still lost.
    Unable to restore inode 827 (file.827): No undeleted copies found in the journal.
    Unable to restore inode 145192 (file.145192): No undeleted copies found in the journal.
    Unable to restore inode 145197 (file.145197): No undeleted copies found in the journal.
    Unable to restore inode 145200 (file.145200): No undeleted copies found in the journal.
    Unable to restore inode 145209 (file.145209): No undeleted copies found in the journal.
    Unable to restore inode 145210 (file.145210): No undeleted copies found in the journal.
    Unable to restore inode 145257 (file.145257): No undeleted copies found in the journal.
    Unable to restore inode 145289 (file.145289): No undeleted copies found in the journal.
    Unable to restore inode 145293 (file.145293): No undeleted copies found in the journal.
    Unable to restore inode 145295 (file.145295): No undeleted copies found in the journal.
    Unable to restore inode 145296 (file.145296): No undeleted copies found in the journal.
    Unable to restore inode 145342 (file.145342): No undeleted copies found in the journal.
    Unable to restore inode 145343 (file.145343): No undeleted copies found in the journal.
    Unable to restore inode 145355 (file.145355): No undeleted copies found in the journal.
    Unable to restore inode 145359 (file.145359): No undeleted copies found in the journal.
    Unable to restore inode 145360 (file.145360): No undeleted copies found in the journal.
    Unable to restore inode 145364 (file.145364): No undeleted copies found in the journal.
    Unable to restore inode 145365 (file.145365): No undeleted copies found in the journal.
    Unable to restore inode 145366 (file.145366): No undeleted copies found in the journal.
    
    

    inodeを失ったものもあるようですが、復元できていることが確認できました。

    復元したファイルを確認します。

    $ cd ~/mytmp/RECOVERED_FILES/kazuma/mytmp/RECOVERED_FILES
    $ ls
    test.txt test19.txt test3.txt test40.txt test51.txt test62.txt test73.txt test84.txt test95.txt
    test0.txt test2.txt test30.txt test41.txt test52.txt test63.txt test74.txt test85.txt test96.txt
    test1.txt test20.txt test31.txt test42.txt test53.txt test64.txt test75.txt test86.txt test97.txt
    test10.txt test21.txt test32.txt test43.txt test54.txt test65.txt test76.txt test87.txt test98.txt
    test11.txt test22.txt test33.txt test44.txt test55.txt test66.txt test77.txt test88.txt test99.txt
    test12.txt test23.txt test34.txt test45.txt test56.txt test67.txt test78.txt test89.txt
    test13.txt test24.txt test35.txt test46.txt test57.txt test68.txt test79.txt test9.txt
    test14.txt test25.txt test36.txt test47.txt test58.txt test69.txt test8.txt test90.txt
    test15.txt test26.txt test37.txt test48.txt test59.txt test7.txt test80.txt test91.txt
    test16.txt test27.txt test38.txt test49.txt test6.txt test70.txt test81.txt test92.txt
    test17.txt test28.txt test39.txt test5.txt test60.txt test71.txt test82.txt test93.txt
    test18.txt test29.txt test4.txt test50.txt test61.txt test72.txt test83.txt test94.txt
    
    $ cat test.txt
    hoge
    
    

    ファイルの復元ができたことが確認できました。

    削除ファイルは書き込みさえしなければ、ファイルポインタを失っただけのため、inodeが分かれば復元できるという実験でした。
    使いたくないコマンドではあれど、備忘録として頭の片隅にでも残しておきます。

    以上。