ウェブサーバーのメモリリーク

ウェブサーバーのメモリリーク

最近、サーバーのパフォーマンスに問題があります。現在、4GB と 160GB のディスク容量を持つ Fedora サーバーを実行しています。搭載されているすべてのファイルで、ディスクの上限がほぼいっぱいになっています。複数の Web サイトを運営しており、各 Web サイトのバックアップも複数あります。ただし、実際にトラフィックがあるのは 1 つのサイトだけです。かなりの数の訪問者がいる e コマース サイトです。

最近、読み込み時間が遅くなり、空きメモリがかなり少なくなっていることに気が付きました (1 GB 未満)。サーバーを再起動すると (今では 1 日に 3 回行う必要があります)、すべて正常になります。最初は 2.2 GB の空きメモリがありますが、3 ~ 4 時間後にはメモリが消費され、読み込み時間が遅くなっていることに気が付きます。この原因が何なのか、またはもっと良いサーバーにアップグレードする時期が来ただけなのか、わかりません。アップグレードしてから、MySQL リクエストのどこかでボトルネックになっていることに気付くのは避けたいです。

どのようなアイデアや提案でも歓迎します。

編集-

3 つの vhost もあり、ファイルは 60,000 を超えています。

             total       used       free     shared    buffers     cached
Mem:          4003       3372        630          0        398       1717
-/+ buffers/cache:       1256       2746
Swap:         8189          0       8189

21:21:49 up 46 min,  1 user,  load average: 3.75, 4.20, 4.03

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  2      0 592728 409640 1838360    0    0   165   411  953  473  9  8 47 36  0

そして、こちらがトップのスナップショットです。

 1356 mysql     20   0 1374m 219m 5320 S  5.6  5.5  14:06.21 mysqld
15796 root      20   0  103m  20m  440 D  1.0  0.5   0:04.42 sendmail
 1081 root      20   0  103m  20m  440 D  0.7  0.5   0:21.73 sendmail
24013 root      20   0 97416  22m 2648 D  0.7  0.6   0:15.15 mailq
 1525 root      20   0  247m 7980 3472 S  0.3  0.2   0:06.88 vlogger (access
 1530 apache    20   0  539m  13m 3008 S  0.3  0.3   0:03.56 httpd
 2399 apache    20   0  539m  12m 2748 S  0.3  0.3   0:00.85 httpd
 5763 root      20   0  121m 4932 3868 S  0.3  0.1   0:00.07 sshd
12326 apache    20   0  539m  12m 2992 S  0.3  0.3   0:00.38 httpd
12421 apache    20   0  539m  12m 2988 S  0.3  0.3   0:00.45 httpd
16396 apache    20   0  538m  12m 2284 S  0.3  0.3   0:00.09 httpd
17050 root      20   0 15368 1256  868 R  0.3  0.0   0:00.09 top
    1 root      20   0 37336 4104 1908 S  0.0  0.1   0:02.82 systemd
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd
    3 root      20   0     0    0    0 S  0.0  0.0   0:00.03 ksoftirqd/0
    5 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/0:0H
    6 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kworker/u:0
    7 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/u:0H
    8 root      RT   0     0    0    0 S  0.0  0.0   0:00.11 migration/0
    9 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/0
   10 root      RT   0     0    0    0 S  0.0  0.0   0:00.14 migration/1
   12 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/1:0H
   13 root      20   0     0    0    0 S  0.0  0.0   0:00.02 ksoftirqd/1
   14 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/1
   15 root      RT   0     0    0    0 S  0.0  0.0   0:00.15 migration/2
   17 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/2:0H
   18 root      20   0     0    0    0 S  0.0  0.0   0:00.03 ksoftirqd/2
   19 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/2
   20 root      RT   0     0    0    0 S  0.0  0.0   0:00.11 migration/3
   22 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 kworker/3:0H
   23 root      20   0     0    0    0 S  0.0  0.0   0:00.02 ksoftirqd/3
   24 root      RT   0     0    0    0 S  0.0  0.0   0:00.01 watchdog/3
   25 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 cpuset
   26 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 khelper
   27 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kdevtmpfs
   28 root       0 -20     0    0    0 S  0.0  0.0   0:00.00 netns
   29 root      20   0     0    0    0 S  0.0  0.0   0:00.00 xenwatch

答え1

sar をランプアップし、1 分ごとに ps テーブルを出力します。詳細な回答を参照してください。ここ

次回サーバーがダウンしたときは、sar -r追跡に役立ててくださいいつそれが起こった。今、ps-cronjobまたは私の出力を使用してくださいgithub 上の ps 用 perl ラッパーどのプロセスが原因であるかを突き止めます。

たとえば、サーバーが 12:00:00 から 13:00:00 の間にダウンしたとします。 を使用しますsar -r -s 12:00:00 -e 13:00:00。これで、データのスパイクが確認できます。(もっと簡単なら、グラフを作成する Java ベースのユーティリティがありますが、通常は面倒な作業に見合うものではありません。) たとえば、12:15 にスパイク (または谷) が見られるとします。次に、列化された ps 出力を、たとえば 12:00 から 12:15 の間の時間範囲でスキャンし、pid と時間で並べ替えて、メモリ列を確認します。

awk '/^=== .* 12:00:/,/^=== .* 12:16:/' /var/log/sa/ps/today |
 sort -k 1n -k 16 

(ソート オプションでは、時刻が 16 列目にあると想定していますが、そうでない場合もあります)。次に、awk を使用して出力を再度フィルターし、出力行間の違いを見つけることができます。

... | awk 'lastpid && lastpid==$1 && last != $0 { print} /^[0-9]/ { lastpid=$1;last=$0; }'

これはかなり粗雑なフィルターです。一部のプロセス (mysql、postgresql、snmpd など、コマンド ラインが常に変化するプロセス) では、これはあまり役に立ちませんが、awk を微調整して原因を見つけられるようになることを期待します。

関連情報