EC2 Linux インスタンスのメモリ不足エラーを防ぐために Apache ウェブサーバーのメモリ割り当てを調整するにはどうすればよいですか?

最終更新日: 2021 年 9 月 16 日

Amazon Elastic Compute Cloud (Amazon EC2) Linux インスタンスで実行されている Apache ウェブサーバーは、断続的に応答しなくなります。インスタンスのシステムログに、「メモリ不足」、「oom」、「oom-killer」、「プロセスをフォークできませんでした」、またはその他のメモリ不足の旨のメッセージが表示されています。これを修正するにはどうすればよいですか?

簡単な説明

システムログを表示してエラーメッセージを確認するには、次の手順を実行します。

  1. Amazon EC2 コンソールを開いて、[インスタンス] を選択します。
  2. インスタンスのチェックボックスを選択します。
  3. [Actions] (アクション)、[Monitor and troubleshoot] (モニタリングとトラブルシューティング)、[Get system log] (システムログの取得) の順に選択します。

注: 新しい Amazon EC2 コンソールを使用していない場合は、[Actions] (アクション)、[Instance Settings] (インスタンスの設定)、[Get System Log] (システムログの取得) の順に選択します。

インスタンスへのターミナルセッションを確立すると、Linux インスタンスのディストリビューションに適した場所にスタックトレースが表示されることがあります。

Debian と Ubuntu: /var/log/syslog

Amazon Linux、CentOS、および RHEL: /var/log/messages

systemd を使用しているシステム: journalctl

解決方法

断続的な停止と、メモリ不足のエラーメッセージは、インスタンスのメモリが使い果たされたことを示している可能性があります。

サーバーが受け入れる接続の数と、そのサーバーが開始するプロセスの数に対する制限を設定できます。Apache プロセスの通常のメモリ使用量を計算し、Apache に割り当てるメモリの合計をその平均値で割ることで、制限値を得ることができます。

Apache 2.4 を実行している場合は、次の手順を実行します。

1.    インスタンスに対するターミナルセッションを開始します。接続できない場合は、インスタンスの再起動が必要になることがあります。

2.    ターミナルセッションから、top コマンドを実行して、インスタンス上のメモリ常駐プロセスのリストを表示します。
メモリ使用量の割合で降順にリストをソートします。rpm ベースのインスタンスでソートするには、Shift + O を押してから、n を押します。
他の Linux ディストリビューションでは、該当するオプションを選択してメモリ使用量でプロセスをソートします。

3.    Apache プロセスに対して返される %MEM 値の列を調べ、平均値を決定します。

4.    Apache プロセスの %MEM 値が他の Apache プロセスの %MEM 値に比べて異常に大きい 1 つ以上の Apache プロセスを探します。%MEM 値が大きい場合は 、サーバー上で実行されているウェブアプリケーションでメモリリークが発生している可能性があります。潜在的なメモリリークの影響を軽減するには、変数 MaxRequestsPerChild のデフォルト値を 4500 に設定します。

設定変数を設定するには、/etc/httpd/config.d ディレクトリ内に新しいファイルを作成します。次のコマンド例では、新しいファイルは prefork.confです。

$ sudo vim /etc/httpd/config.d/prefork.conf

MaxRequestsPerChild 変数をステップ 6 の例に示す値に設定します。

5.    ServerLimit および MaxRequestWorkers 設定変数の値を次のように計算します。

インスタンスの RAM が 4 GB を超える場合は、90% を Apache プロセスの平均 %MEM 値で割ります。例えば、平均 %MEM 値が 0.8% の場合、90% (0.9) を 0.8% (0.008) で割ると結果が 112.5 で、最も近い整数 (この場合は 112) に丸めます。

インスタンスの RAM が 4 GB 以下の場合は、80% を Apache プロセスの平均 %MEM 値で割ります。例えば、平均 %MEM 値が 0.8% の場合、80% (0.8) を 0.8% (0.008) で割ると、結果は 100 になります。

注: これらの値は、インスタンスが専用のウェブサーバーであると想定して計算されています。サーバーで他のアプリケーションをホストしている場合は、この計算を行う前に、90% または 80% のいずれかから、これらのアプリケーションの合計メモリ使用量の割合を引きます。RAM が 4 GB 以下のインスタンスで、Apache に加えて他のアプリケーションを実行している場合は、パフォーマンスが低下することがあります。

6.    prefork.conf ファイルの MaxRequestWorkers および ServerLimit 設定変数を更新し、変更を保存します。

以下はその例です。

IfModule mpm_prefork_module
    StartServers          10
    MinSpareServers       20
    MaxSpareServers       40
    MaxRequestWorkers     112
    ServerLimit           112
    MaxRequestsPerChild   4500
/IfModule

7.    ターミナルセッションから以下のコマンドを実行して、ウェブサーバーを再起動します。

sudo service httpd restart

Apache 2.2 を実行している場合は、次の操作を行います。

1.    インスタンスに対するターミナルセッションを開始します。接続できない場合は、インスタンスの再起動が必要になることがあります。

2.    ターミナルセッションから、top コマンドを実行して、インスタンス上のメモリ常駐プロセスのリストを表示します。
メモリ使用量の割合で降順にリストをソートします。
rpm ベースのインスタンスでソートするには、Shift + O を押してから、n を押します。他の Linux ディストリビューションでは、該当するオプションを選択してメモリ使用量でプロセスをソートします。

3.    Apache プロセスに対して返される %MEM 値の列を調べ、平均値を決定します。

4.    Apache プロセスの %MEM 値が他の Apache プロセスの %MEM 値に比べて異常に大きい 1 つ以上の Apache プロセスを探します。%MEM 値が大きい場合は 、サーバー上で実行されているウェブアプリケーションでメモリリークが発生している可能性があります。潜在的なメモリリークの影響を軽減するには、設定変数 MaxConnectionsPerChild のデフォルト値を 4000 から 1000 に変更します。

この変更により、メモリリークの原因を特定して修正しながら、問題がある程度緩和されます。メモリリークが疑われる場合は、新しい設定値でインスタンス上の httpd.conf ファイルを更新し、変更を保存して、ステップ 7 にスキップします。

5.    ServerLimit および MaxClients 設定変数の値を次のように計算します。

インスタンスの RAM が 4 GB を超える場合は、90% を Apache プロセスの平均 %MEM 値で割ります。例えば、平均 %MEM 値が 0.8% の場合、90% (0.9) を 0.8% (0.008) で割ると結果が 112.5 で、最も近い整数 (この場合は 112) に丸めます。

インスタンスの RAM が 4 GB 以下の場合は、80% を Apache プロセスの平均 %MEM 値で割ります。例えば、平均 %MEM 値が 0.8% の場合、80% (.8) を 0.8% (.008) で割ると、結果は 100 になります。

注: これらの値は、インスタンスが専用のウェブサーバーであると想定して計算されています。サーバーで他のアプリケーションをホストしている場合は、この計算を行う前に、90% または 80% のいずれかから、これらのアプリケーションの合計メモリ使用量の割合を引きます。RAM が 4 GB 以下のインスタンスで、Apache に加えて他のアプリケーションを実行している場合は、パフォーマンスが低下することがあります。

6.    インスタンスの httpd.conf ファイルの設定変数 MaxClientsServerLimit を新しい値で更新し、変更を保存します。

以下はその例です。

MaxClients = 112 
ServerLimit = 112

7.    ターミナルセッションから以下のコマンドを実行して、ウェブサーバーを再起動します。

apachectl graceful

この記事は役に立ちましたか?


請求に関するサポートまたは技術サポートが必要ですか?