Postfix パフォーマンスチューニング


Postfix パフォーマンスチューニングの目的

このドキュメントにあるヒントや tips はすでに動いている Postfix システムの パフォーマンスを向上するのに役立ちます。あなたの Postfix システムがメールを 送信したり受信したりできないのであれば、 DEBUG_README ドキュメントを手引きとして 使い、まずその問題を解決する必要があります。

外部コンテンツフィルタのパフォーマンスをチューニングするには、まず FILTER_READMESMTPD_PROXY_README ドキュメントの 情報を読んでください。そしてコンテンツフィルタコードのレイテンシをなくす ようにします。できるだけ遅延が大きかったり遅延のバラツキが大きい外部 データソースへの問い合わせを避けるようにしてください。CPU/メモリを使い 果たさないように、コンテンツフィルタは並列数を小さくして走らせますが、 レイテンシがあると、コンテンツフィルタのスループットは苦しむことに なるでしょう。大容量環境では RBL 検索や複雑なデータベース検索などを 避けるべきです。

メール受信のパフォーマンスに関する話題:

メール配送のパフォーマンスに関する話題:

他の Postfix パフォーマンスチューニングに関する話題:

以下のツールは人工的に負荷をかけてメールシステムのパフォーマンスを 測定することができます。これらは通常 Postfix とともにはインストール されません。

一般的なメール受信パフォーマンスの tips

SMTP クライアントに対する Postfix の応答が遅い場合:

SMTP サーバプロセスをより多く働かせる

Postfix バージョン 2.0 以前では、smtpd(8) サーバは SMTP クライアントにエラーを報告する前に一時停止します。この アイディアはタール抗 (tar pitting) と呼ばれます。しかし、これらの遅延は Postfix も遅くします。smtpd(8) サーバの応答が 遅いとセッションに時間がかかり、その結果負荷をさばくのにより多くの smtpd(8) サーバプロセスが必要となって しまいます。Postfix smtpd(8) サーバプロセス 制限に達すると、新しいクライアントはサーバプロセスが利用可能になるまで 待たなければいけません。これはクライアントすべてのパフォーマンスが悪くなる ことを意味します。

遅延を無効にすることで smtpd(8) サーバの エラー応答の扱いを高速化することができます:

/etc/postfix/main.cf:
    # Postfix 2.1 では不要です
    smtpd_error_sleep_time = 0

上の設定を使うと、Postfix 2.0 以前では同じ SMTP サーバプロセス数で より多くの SMTP クライアントにサービスを提供できます。次のセクションでは、 Postfix が多数のエラーを出すクライアントをどう扱うかについて記述して います。

大量にエラーを出す SMTP クライアントを遅くする

Postfix smtpd(8) サーバはセッションごとの エラーカウントを管理しています。メッセージの転送に成功するとエラー カウントはリセットされ、クライアントの要求が認識できなかったり実装されて いなかったり、クライアントの要求が アクセス制限を犯す場合、他の エラーが起こった場合には、エラーカウントは増加します。

セッションごとのエラーカウントが増加するにつれ、 smtpd(8) サーバは振る舞いを変えて応答に遅延を 入れ始めます。これはリソースの使用を制限するために暴走したクライアントを 遅くするという考えです。この振る舞いは Postfix のバージョンに依存します。

重要: これらの遅延は Postfix も遅くします。遅延を大きく設定しすぎると、 同時 SMTP セッションの数が増加して smtpd(8) サーバプロセス制限に達し、新しい SMTP クライアントは smtpd(8) サーバプロセスが利用可能になるまで 待たなければいけません。

Postfix バージョン 2.1 以降:

Postfix バージョン 2.0 以前:

過剰に接続するクライアントに対する測定

注意: この機能は Postfix バージョン 2.1 には含まれていません。

Postfix smtpd(8) サーバは同じ SMTP クライアントからの同時接続数と、あるクライアントが単位時間内に接続できる 接続数を制限することができます。これらの統計情報は anvil(8) サーバに よって管理されます (翻訳: anvil(8) サーバが止まると接続制限は働かなく なります)。

重要: これらの制限はひどい乱用から smtpd(8) サーバを保護することを意図しています。これらを通常の正常なトラフィックの 制限には使わないでください: そうしてしまうとメールがおぞましい遅延に 苦しめらることになります。

一般的なメール配送パフォーマンスの tips

遅延メール配送を試行する頻度のチューニング

Postfix は同時に 1000 もの SMTP クライアントプロセスを動かすように 設定することができますが、同じリモートシステムに同時に 1000 の接続を 張ることはあまり望ましいことではありません。こういった理由で、Postfix にはこのいわゆる "大群" 問題を避ける機構があります。

Postfix キューマネージャは TCP スロースタートフロー制御戦略と同様な ものを実装しています: あるサイトに配送する際、始めは少数のメッセージを 送り、そしてうまくいっている間は並列数を増やしていきます; 混雑してきたら 並列数を減らします。

transport 特有の並列数制限の例:

上の並列制限のデフォルト値は広範囲な場面でうまく動きます。混雑したからと いって条件反射的にこれらのパラメータを変更すると、実際には問題を悪化させる ことになりかねません。特に、配送先への並列数のデフォルトを大きくすべきでは ありません。少数の大規模なドメインにメールを配送する transport のみに 限定すべきです。

並列数を大きくすることが要求される一般的な場面は、インターネットと イントラネットメール環境の間で大量のメールを中継するゲートウェイ上です。 およそ半分のメール (内行きと外行きが同じ量と想定します) が内部のメール ハブ宛です。内部メールハブは外部メールをすべてゲートウェイからのみ受け取る ため、ゲートウェイの内部 SMTP サーバの容量に対する要求を大きくするように 設定するのは妥当です。

内行きの並列制限のチューニングには試行錯誤は不要です。特にゲートウェイが 複数の MX ホストに対して転送しているのであれば、大量に受け入れられる メールハブは簡単に (デフォルトの 20 より大きな) 50 や 100 の同時接続を 扱えるはずです。MX ホストがすべて動いていてタイムリーな方法で接続を受けて いるのであれば、スループットは高いでしょう。どの MX ホストも落ちていて 完全に応答しなければ、N 個の MX ホストがあると、接続レイテンシの平均は 少なくとも 1/N * $smtp_connection_timeout まで上がります。これは スループットを最大で配送先並列数 * N / $smtp_connection_timeout に制限 します。

例えば配送先並列数を 100 で2つの MX ホストがあるとすると、それぞれの ホストは最大 50 の同時接続が扱えます。一方の MX ホストがダウンし、 デフォルトの SMTP 接続タイムアウトが 30s だと、スループット制限は1秒あたり 100 * 2 / 30 ~= 6 メッセージとなります。これは接続状況がよくて複数の MX ホストがある大量の配送先では接続タイムアウトを低く 5s くらいの値、もしくは すべてではない1つ以上の MX ホストがダウンした際の輻輳を防ぐのに 1s に してもよい、ということを示唆しています。

必要ならば、relay transport や特定の大容量な配送先専用の transport に 対して transport_destination_concurrency_limit に (これはキューマネージャの パラメータなので main.cf に) 高い値を設定し、smtp_connection_timeout に (このパラメータは transport ごとの名前ではないので master.cf で "-o" を 付けて上書きして) 低い値を設定してください。

同時配送数のチューニング

default_destination_recipient_limit パラメータ (デフォルト: 50) は Postfix 配送エージェントがそれぞれのEメールの コピーで送る受信者数を制御します。特定の Postfix 配送エージェントに対して この設定を上書きすることができます。例えば "uucp_destination_recipient_limit = 100" とすると、それぞれの UUCP 配送ごとの受信者数を100に制限します。

Eメールメッセージがある配送先に対する受信者制限を超えると、Postfix キューマネージャは受信者リストを小さいリストに分割します。Postfix は メッセージの複数のコピーを並列に送ろうとします。

重要: メッセージ配送ごとの受信者数を増やす際には注意してください; smtpd(8) がメモリを使い果たしたりハード受信者 制限に到達すると接続を強制的に切ることがあり、そのメッセージが配送 されなくなってしまいます。

smtpd_recipient_limit smtpd_recipient_limit パラメータ (デフォルト: 1000) は Postfix smtpd(8) サーバが配送ごとに受け取る受信者数を 制御します。デフォルトの制限は SMTP クライアントが送る妥当なものよりも 大きい値です。この制限は暴走したクライアントからローカルメールシステムを 保護するために存在しています。

配送ごとの受信者数のチューニング

Postfix 配送エージェント (smtp(8), local(8) など) がメッセージを配送できない場合、 メッセージ自身を非難するか、受信組織を非難するかもしれません。

この処理は少数のパラメータ群で支配されます。

queue_run_delay (デフォルト: 1000 秒)
キューマネージャが遅延メールのキューをスキャンする頻度。
minimal_backoff_time (デフォルト: 1000 秒)
メッセージを見ない最短時間、および "死亡" 配送先から離れる最短時間。
maximal_backoff_time (デフォルト: 4000 秒)
配送の失敗後メッセージを見ない最長時間。
maximal_queue_lifetime (デフォルト: 5 日)
配送できないとして送り返されるまでにメッセージがキューに滞在する時間。 0を指定すると、最初の配送試行に失敗したらすぐにメールは送り返されます。
bounce_queue_lifetime (デフォルト: 5 日, Postfix バージョン 2.1 以降で使えます)
配送できないと見なされるまでに MAILER-DAEMON メッセージがキューに とどまる時間。0 を指定するとメールは1回だけ試行されます。
qmgr_message_recipient_limit (デフォルト: 20000)
多くのメモリ内キューマネージャデータ構造のサイズ。特にこのパラメータは "死亡" 配送先の短期間メモリ内リストを制限します。リストに合わない配送先は 追加されません。

重要: 遅延メール配送の試行頻度を上げたり、遅延メールキューを頻繁に flush すると、実際に Postfix メール配送のパフォーマンスが悪くなったと 感じるかもしれません。以下のような兆候です:

メールが頻繁に遅延する場合、配送試行の頻度を上げるよりも問題を修復する 方が常によいです。しかし配送試行の頻度しか制御できないのであれば、問題の ある配送先に対して専用の fallback_relay "墓場" マシンを使って、通常のメール配送のパフォーマンスを破綻させない ようにすることを検討してください。

Postfix プロセス数のチューニング

default_process_limit 設定パラメータは Postfix が走らせるデーモンプロセスの数を直接制御します。 Postfix 2.0 の時点では、デフォルトの制限は 100 smtp クライアントプロセス、 100 サーバプロセスなどです。これはメモリが少ないシステムやバンド幅の 狭いネットワークのシステムを苦しめるかもしれません。

デフォルトではない default_process_limit を main.cf ファイルに指定することで全体のプロセス制限を変えることが できます。例えば、最大 10 の smtp クライアントプロセス、10 の smtp サーバ プロセスなどとするには:

/etc/postfix/main.cf:
    default_process_limit = 10

変更を有効にするには "postfix reload" を実行する必要があります。この 制限は main.cf が更新されても自動的には読み込まない Postfix master(8) デーモンによって強制されます。

特定の Postfix デーモンに対するプロセス制限は、master.cf ファイルを 編集することで上書きできます。例えば、同時に 100 の SMTP メッセージは 受けたくないが、ローカルメール配送のプロセス制限は変更したくない場合、 次のように指定できます:

/etc/postfix/master.cf:
    # ====================================================================
    # service type  private unpriv  chroot  wakeup  maxproc command + args
    #               (yes)   (yes)   (yes)   (never) (100)
    # ====================================================================
    . . .
    smtp      inet  n       -       -       -       10      smtpd
    . . .

ファイルやソケットをオープンする数のチューニング

Postfix が過剰にファイルやソケットをオープンすると、プロセスは致命的 エラーで異常終了し、システムは "file table full" エラーをログに記録するかも しれません。