PHPセッション用のUbuntuのガベージコレクションcronジョブの実行に25分かかります。なぜですか?


13

Ubuntuには、古いPHPセッションを検索して削除するcronジョブがセットアップされています。

# Look for and purge old sessions every 30 minutes
09,39 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] \
   && [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
   -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) ! -execdir \
   fuser -s {} 2> /dev/null \; -delete

私の問題は、このプロセスの実行に非常に長い時間がかかり、大量のディスクIOがあることです。CPU使用率グラフは次のとおりです。

CPU使用率グラフ

実行中のクリーンアップは、青緑のスパイクで表されます。期間の初めに、PHPのクリーンアップジョブはデフォルトの09分と39分にスケジュールされました。15:00にcronから39分の時間を削除したので、サイズの2倍のクリーンアップジョブは半分の頻度で実行されます(ピークが2倍の幅で、半分の頻度になります)。

IO時間に対応するグラフは次のとおりです。

IO時間

ディスク操作:

ディスク操作

アクティブなセッションが約14,000であったピーク時には、CPUの1つのコアの100%と、全期間にわたってディスクIOの100%と思われるものを使用して、クリーンアップが25分間実行されていることがわかります。なぜそれほどリソースを消費するのですか?lsセッションディレクトリのは、/var/lib/php5第二のほんの一部になります。では、なぜ古いセッションをトリムするのに25分かかるのでしょうか?これを高速化するためにできることはありますか?

このデバイスのファイルシステムは現在ext4で、Ubuntu Precise 12.04 64ビットで実行されています。

編集:私は負荷が異常なプロセス「フューザー」によるものであると疑っています(rm私が見ているパフォーマンスよりも単純なものがいまいましい光景であると思っているので)。フューザの使用を削除して、何が起こるかを確認します。


あなたのウェブサイトがどれだけ多くのトラフィックを生成し、それだけのセッションを生成しますか?
マイケルハンプトン

回答:


9

の削除がfuser役立つはずです。このジョブは、fuser見つかったすべてのセッションファイルに対してコマンドを実行します(ファイルが現在開いているかどうかを確認します)。これはDebianのバグでした(UbuntuはDebianに基づいています)。

memcachedの代わりに、セッションファイルにtmpfs(メモリ内のファイルシステム)を使用することもできます。memcachedのように、これは再起動時にセッションを無効にします(これは、シャットダウンスクリプトでこのディレクトリをバックアップし、スタートアップスクリプトで復元することで回避できます)が、セットアップははるかに簡単です。しかし、それはfuser問題を解決しません。


フューザーのバグは、以前のバージョンは分岐したが、完了時に決して収まらず、fuserメモリを消費するゾンビ状態の数千のプロセスを残し、サーバーがクラッシュするというバグだったようです。これは、使用しているpsmiscのバージョンで既に修正されていると思います。
thenickdude

それは別のバグです。数千のfuserプロセスを開始するという単純な問題があり/proc/ます。すべてのプロセスで開いているファイルを検索する必要があります。
トメツキー

9

人気のあるWebサイトを作成し、この間ずっと仮想マシンで実行し続けることができました。おめでとうございます。

あなたが本当に一日あたり200万ページビューで引っ張っている場合は、ファイルシステム内のPHPセッションのLOTを積み重ねするつもりだ、と彼らはあなたが使用するかどうかに関係なく削除するには長い時間がかかるとしているfuserか、rmまたはA掃除機。

この時点で、セッションを保存する別の方法を検討することをお勧めします。

  • 1つのオプションは、セッションmemcachedをに保存することです。これは非常に高速ですが、サーバーがクラッシュまたは再起動すると、すべてのセッションが失われ、全員がログアウトされます。
  • セッションをデータベースに保存することもできます。これはmemcachedよりも少し遅くなりますが、データベースは永続的であり、簡単なSQLクエリで古いセッションをクリアできます。ただし、これを実装するには、カスタムセッションハンドラー記述する必要があります。

Memcachedは確かにオプションです。ただし、メインのmemcachedインスタンスとは別のプールにする必要があります。そうしないと、セッションがキャッシュのプレッシャーからランダムに排除されます。ただし、14,000個のファイルを削除するのに25分かかるとは思いません。それは私には遅すぎるように聞こえます。数時間待って、シンプルのパフォーマンスがどのrmようなものかを確認します。
thenickdude

全体的なアーキテクチャについて詳しく知ることなく、どちらか一方を推奨することをためらいます。
マイケルハンプトン

memcache.session_redundancy = 2を設定すると、Memcachedサーバーをプールして冗長性を確保できます。serverfault.com/questions/164350/…を参照してください。Redisは、永続性を懸念する場合に適したオプションであり、SQLデータベースストアよりもはるかに高速です。
jfountain

4

したがって、ここでユーザーが推奨するMemcachedおよびデータベースセッションストレージオプションは、どちらもパフォーマンスを向上させるのに適した選択肢であり、それぞれに長所と短所があります。

しかし、パフォーマンステストによって、このセッションメンテナンスの膨大なパフォーマンスコストは、ほぼ完全fuserにcronジョブでの呼び出しにかかっていることがわかりました。古いセッションをトリミングするrm代わりにfuser2:30にスイッチオーバーが発生するNatty / Oneiric cronジョブに戻した後のパフォーマンスグラフを次に示します。

CPU使用率

IO時間の経過

ディスク操作

UbuntuのPHPセッションクリーニングによる定期的なパフォーマンスの低下はほぼ完全に解消されていることがわかります。Disk Operationsグラフに表示されるスパイクの大きさははるかに小さくなり、このグラフで測定できる程度の細さで、以前のサーバーパフォーマンスが25分間大幅に低下した小さな短い中断を示しています。余分なCPU使用量は完全に排除され、これはIOにバインドされたジョブになりました。

(無関係のIOジョブは05:00に実行され、CPUジョブは7:40に実行され、これらは両方ともこれらのグラフに独自のスパイクを引き起こします)

私が現在実行している変更されたcronジョブは次のとおりです。

09 *     * * *     root   [ -x /usr/lib/php5/maxlifetime ] && \
   [ -d /var/lib/php5 ] && find /var/lib/php5/ -depth -mindepth 1 \
   -maxdepth 1 -type f -cmin +$(/usr/lib/php5/maxlifetime) -print0 \
   | xargs -n 200 -r -0 rm

-print0 | xargs ...必要ではありません-そのまま-deleteそこに置いておくことができます。しかし、同等の速度で両方の方法で動作します。
トメツキー

1

セッションに関するいくつかの調査を行っているときに、この投稿に出会いました。受け入れられた答えは非常に良いですが(また、フューザー呼び出しはしばらくの間gcスクリプトから削除されました)、他の誰かが同様の問題に遭遇した場合、他のいくつかの考慮事項に注意する価値があると思います。

説明したシナリオでは、OPはext4を使用していました。ext4のディレクトリは、htreeデータベース形式でファイルデータを保存します。これは、複数のディレクトリにファイルを分散する場合と比較して、単一のディレクトリに多くのファイルを保持する場合の影響が無視できることを意味します。これはすべてのファイルシステムに当てはまるわけではありません。PHPのデフォルトハンドラーを使用すると、セッションファイルに複数のサブディレクトリを使用できます(ただし、制御プロセスがこれらのディレクトリに再帰していることを確認する必要があります。上記のcronジョブはそうではありません)。

(fuserへの呼び出しを削除した後の)操作のコストの多くは、まだ古くなっていないファイルを調べることから生じます。(たとえば)単一レベルのサブディレクトリと、各サブディレクトリ(0 /、1 /、... d /、e /、f /)を検索する16個のcronジョブを使用すると、発生するロードバンプがスムーズになります。

より高速なサブストレートでカスタムセッションハンドラーを使用すると役立ちます-ただし、インターネット上で公開されているものの品質の範囲はそのままにして、選択できるものはたくさんあります(memcache、redis、mysqlハンドラーソケット...)アプリケーション、インフラストラクチャ、およびスキルに関する要件。デフォルトのハンドラーと比較して、セマンティクス(特にロック)の処理に頻繁に違いがあることを忘れないでください。


0

そのような種類のトラフィックでは、セッションを中断しないでください。memcacheのようなものを使用する必要があります。必要なのはphpをセットアップするだけで、コードを変更する必要はありません。たとえば

http://www.dotdeb.org/2008/08/25/storing-your-php-sessions-using-memcached/

時間がかかる理由は、削除できるファイルを確認するためにソートしなければならない膨大な量のファイルによるものです。Memcacheは、コードで設定したセッションの長さを考慮して、これらを自動的に期限切れにすることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.