
私は Web サイトを運営しており、購読者には正規のオプトインによる毎日の電子メール ニュースレターを送信しています。Web ホスティングと電子メールの送信は、どちらも同じマシンで行われています。
私の毎日のメール ニュースレターの購読者は約 100,000 人います。私の PHP スクリプトは、つい最近まで、購読者全員にメールを送るのにかなりうまく機能していましたが、リストが大きくなるにつれて、対応できなくなりました。
top を実行すると、CPU が 2 つしかないにもかかわらず、負荷が非常に高くなります (通常は少なくとも 6 または 7、時には 15 にもなります)。ただし、sar を実行すると、CPU は平均して約 30% の時間アイドル状態になります。つまり、CPU に縛られているわけではないようです。iostat を実行すると、各デバイスの %util が非常に低い (5% 以下) ため、ディスクに縛られているわけではないようです。
CPUやディスクに縛られているようには見えないので、なぜトップはこのような高い負荷を報告しているのでしょうか?
さらに、CPUやディスクに縛られているようには見えないので、私の電子メール送信スクリプトが追いつけないのはなぜですか?
top を実行すると、次のようになります。
top - 11:33:28 up 74 days, 18:49, 2 users, load average: 7.65, 8.79, 8.28
Tasks: 168 total, 5 running, 162 sleeping, 0 stopped, 1 zombie
Cpu(s): 38.9%us, 58.6%sy, 0.8%ni, 0.0%id, 0.7%wa, 0.2%hi, 0.8%si, 0.0%st
Mem: 3083012k total, 2144436k used, 938576k free, 281136k buffers
Swap: 2048248k total, 39164k used, 2009084k free, 1470412k cached
iostat -mx を実行すると、次のようになります。
avg-cpu: %user %nice %system %iowait %steal %idle
34.80 1.20 55.24 0.37 0.00 8.38
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 0.19 71.70 1.59 29.45 0.02 0.07 5.90 0.55 17.82 1.16 3.59
sda1 0.00 0.00 0.00 0.00 0.00 0.00 7.10 0.00 13.80 13.72 0.00
sda2 0.05 50.45 1.13 24.57 0.01 0.29 24.25 0.35 13.43 1.15 2.97
sda3 0.05 10.17 0.20 2.33 0.01 0.05 43.75 0.05 20.96 2.45 0.62
sda4 0.00 0.00 0.00 0.00 0.00 0.00 2.00 0.00 70.50 70.50 0.00
sda5 0.07 0.22 0.03 0.07 0.00 0.00 32.84 0.08 856.19 8.03 0.08
sda6 0.02 5.45 0.03 0.72 0.00 0.02 67.55 0.02 26.72 5.26 0.39
sda7 0.00 1.56 0.00 0.42 0.00 0.01 38.04 0.00 8.88 5.84 0.24
sda8 0.01 3.84 0.20 1.35 0.00 0.02 28.55 0.05 31.90 4.08 0.63
sar を実行すると、次のようになります。
09:40:02 AM CPU %user %nice %system %iowait %steal %idle
09:50:01 AM all 30.59 1.01 49.80 0.23 0.00 18.37
10:00:08 AM all 31.73 0.92 51.66 0.13 0.00 15.55
10:10:06 AM all 30.43 0.99 48.94 0.26 0.00 19.38
10:20:01 AM all 29.58 1.00 47.76 0.25 0.00 21.42
10:30:01 AM all 29.37 1.02 47.30 0.18 0.00 22.13
10:40:06 AM all 32.50 1.01 52.94 0.16 0.00 13.39
10:50:01 AM all 30.49 1.00 49.59 0.15 0.00 18.77
11:00:01 AM all 29.43 0.99 47.71 0.17 0.00 21.71
11:10:07 AM all 30.26 0.93 49.48 0.83 0.00 18.50
11:20:02 AM all 29.83 0.81 48.51 1.32 0.00 19.52
11:30:06 AM all 31.18 0.88 51.33 1.15 0.00 15.47
Average: all 26.21 1.15 42.62 0.48 0.00 29.54
私がたまたま実行した特定の時点でリストされたプロセスのトップをいくつか示しますtop -c
。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
8180 mysql 16 0 57448 19m 2948 S 26.6 0.7 4702:26 /usr/sbin/mysqld --basedir=/ --datadir=/var/lib/mysql --user=mysql --pid-file=/var/lib/mysql/bristno.pid --skip-external-locking
26956 brristno 17 0 0 0 0 Z 8.0 0.0 0:00.24 [php] <defunct>
26958 brristno 17 0 94408 43m 37m R 5.0 1.4 0:00.15 /usr/bin/php /home/brristno/public_html/dbv.php
22852 nobody 16 0 9628 2900 1524 S 0.7 0.1 0:00.17 /usr/local/apache/bin/httpd -k start -DSSL
8591 brristno 34 19 96896 13m 6652 S 0.3 0.4 0:29.82 /usr/local/bin/php /home/brristno/bin/mailer.php 1qwqyb6 i0gbor
24469 nobody 16 0 9628 2880 1508 S 0.3 0.1 0:00.08 /usr/local/apache/bin/httpd -k start -DSSL
25495 nobody 15 0 9628 2876 1500 S 0.3 0.1 0:00.06 /usr/local/apache/bin/httpd -k start -DSSL
26149 nobody 15 0 9628 2864 1504 S 0.3 0.1 0:00.04 /usr/local/apache/bin/httpd -k start -DSSL
ありがとう、ドミトリ!
1) 過去 1 か月間に少なくとも 5 回バウンスした電子メール アドレスの登録を解除するスクリプトがすでにあるので、これによってリストがアクティブな電子メール アドレスに比較的限定されることを期待しています。
2) 私はexim 4.69を使用しています。私の設定ファイルは
設定ファイル
ログファイルは次の場所にあります:
/var/log/exim_mainlog
/var/log/exim_paniclog
/var/log/exim_rejectlog
さらに、/etc/syslog.conf を見ると、次のようになっています。
# Log all the mail messages in one place.
mail.* -/var/log/maillog
先頭の「-」が何を意味するのか分かりません-/var/log/maillog
が、そのファイルを見ると、そこに多くの情報が記録されていることは明らかです。
さらに、このファイルには多くの情報が記録されています。
/var/log/exim_mainlog
私はその後、/etc/exim.conf に次の行を追加しました:
no_message_logs
これによってメールのログ記録が無効になると思いました (exim を再起動しました) が、/var/log/maillog と /var/log/exim_mainlog を見ると、両方のファイルでまだ新しいログ エントリが受信されています。
質問:ほとんど/すべての exim ログを無効にするにはどうすればいいですか?
3) /var/log/exim_paniclog を見ると、次のようなエントリが大量に見つかります。
2010-12-19 04:03:32 1PUFB1-0006xZ-GF User 0 set for local_delivery transport is on the never_users list
しばらく調べてみると、exim がルート メール アドレスに配信しようとしているようです。CPU リソースをできるだけ少なく使用しながら、ルートへのメール配信を処理する最善の方法は何ですか?
答え1
前述のように、負荷平均は実行キュー内の待機プロセスの数に関係します。これらの各プロセスが実行する作業がほとんどなく、プロセッサをすぐに解放する場合は、一般的な CPU あたり 1 つの経験則よりもはるかに大きな負荷平均を処理できます。
メールはまさにこの好例です。各プロセスはメッセージを送信するために CPU を必要としますが、その必要量はごくわずかです。メール システムが 25 ~ 35 の負荷平均で sendmail を実行しているのを見たことがありますが、システムは依然として対話的で正常に動作しています。
マーク
答え2
システム メトリック (負荷、CPU、I/O) は、多くの場合、ほとんどの人がシステムのパフォーマンスを示す唯一の指標ですが、実際のトランザクション パフォーマンスはまったく異なります。これらのメトリックは、パフォーマンスがどのように制約されているかについてのガイダンスを提供できますが、実際には、トランザクションが実際にどのくらいの時間がかかるかを確認する方がはるかに有用です。
私の電子メール送信スクリプトが追いつけないのはなぜですか?
これは、メール キューがクリアされないという問題が発生していることを意味しますか? それとも、スクリプトの実行にかかる時間の長さですか? それとも、高負荷に基づいて問題があると推測していますか?
mfarver が言うように、メール システムで高負荷になることは珍しくありません。特に、スパムを避けるためにメール サーバーで同期チェックが行われる回数が増えているためです。
個人的には、私は exim の大ファンではありません。sendmail と postfix の方がずっと良い経験があります。ただし、MTA の本格的なテストを行ってから数年経っていることは認めます。確かに、電子メールの処理について、より高度な知識が必要になる領域に入りつつあります。
ログ記録をオフにするのではなく、ルート アカウントの転送を一時的に追加して、配信されていないすべての電子メールの内容を正確に確認することをお勧めします。
MTA は受信者に直接メールを送信するように設定されていると推測します。パフォーマンスの問題がある場合は、スマート リレーを使用してサーバーからメッセージをより速くオフロードすることを検討してください。ただし、まずは Exim をキューのみに切り替えて、負荷 (およびさらに重要なパフォーマンス) の問題が解決されるかどうかを確認してください。また、DNS キャッシュを調べて、改善できるかどうかを確認してください。
すでにスマート リレーを使用している場合は、正しく設定されているかどうかを確認してください。私の経験では、sendmail ベースのセットアップでは、MTA がスマート ホストに接続できない場合、php mail() 呼び出しが長時間ブロックされます (ただし、何らかの理由でメッセージは配信されます)。
現在、多くのメール プロバイダーがスパム ブロックの方法としてスロットリングを実装しています。メール リストをドメインで並べ替えると DNS ルックアップが減りますが、リモート システムがメールをスロットリングまたはブロックする問題が発生する可能性があります。スパマーと思われないようにするために、実用的なことはすべて実行してください (例: SPF、DKIM)。私の記憶が正しければ、Exim は milter を直接サポートしていません。milter-limit など、便利な milter が多数あります。
答え3
high load
たとえば、CPU で実行したいプロセスの平均サイズですrun queue
。スクリプトは CPU を大量に消費するようです。したがって、スクリプトをプロファイルして、そのソースをここに投稿する必要があります。手紙はどのように送るのですか?
答え4
メールログ エントリは、各エントリでフラッシュしないようにマークされています。これにより、このログへの書き込みによる CPU オーバーヘッドが軽減されます。ただし、Exim を使用しているため、このログはデフォルトでは使用されません。設定をチェックして、syslog の使用が有効になっていないことを確認してください。
ログに記録される内容を減らすには、log_selector
設定に仕様を追加します。可能な値は、Exim 仕様 (おそらく第 49 章) に詳しく記載されています。ただし、これはおそらく問題ではありません。
exiwhat
実行して、どのような配信が試行されているかを確認してください。キューに 1 時間以上置かれている、配信待ちのメッセージや fer が多数あるべきではありません。キューにしばらくmailq
置かれているメッセージのリストが長い場合は、バウンスする可能性のある配信を試行していることを示しています。
Exim は、同時に実行される多数の配信プロセスをうまく処理できません。役立つ可能性のある構成の変更を検討する必要があります。
- 再試行の間隔を長くし、メッセージを未配信としてバウンスするまでの時間を短くしてみてください。これにより、配信できないメッセージをバウンスするために必要な試行回数が減ります。
- 即時配信の試行を無効にして、配信がキューから実行されるようにします。
queue_only_load
これを条件付きで実行する場合は、 を使用することをお勧めします。 queue_run_max
キュー ランナー プロセスの数を制限するように設定します。
配信の試行を解決するには、トランスポートまたはエイリアスを使用できます。私は自分の電子メール アドレスにルートのエイリアスを設定しています。Ubuntu はこのルーターを使用して、ルートとして実行される配信を防止します。
メール4ルート: debug_print = "R: $local_part@$domain の mail4root" ドライバー = リダイレクト ドメイン = +local_domains データ = /var/mail/mail file_transport = アドレスファイル ローカルパーツ = ルート ユーザー = メール グループ = メール