併設の「ぼくんちのTV別館 (さくらのVPS3台体制)」が1日80万PVに達し、サーバーのパフォーマンスが著しく悪くなり、ほぼフリーズしたような状態になった後に行ったチューニング。

VPS 3台の内訳

VPS A ・・・・・ 本体。MTOS5 + PHP化した静的HTML
VPS B ・・・・・ 画像サーバー (javascriptやcssも含む)
VPS C ・・・・・ アクセス解析 + 逆アクセス解析ツール + 1MB超えたファイルなど

サーバーの仕様は3台とも同じ。
 ・メモリ1GB HDD20GB の初期980円(後から増強)コース
 ・OS: Cent OS 5.11 (64bit)
 ・httpサーバー: Apache2系
※画像サーバだけでも Nginx にしよう・・・・と思いつつも全く手が付いていない状態。

1.アクセスが増えすぎた後、どうなったか

  • 画像サーバーが応答しなくなった。
  • 画像サーバーにsshログインできなくなった

2.sshログインできなくなった場合

  • さくらの管理画面のコンソールを使ってログインを試みる
    • ログインできない場合でも、エラーメッセージが表示される。
    • メッセージを元に対策が取れる。
    • 今回の場合、iptablesのコネクションが一杯になっていた。
  • どうにもならない時は強制リブートをかける。
    • 詰まっているパケットが破棄されてログイン可能になる。

3.sshログイン後

  • TOPコマンドで得られる情報だけで判断しない。
  • iptablesやTCP接続が一杯になり、通信が破棄されているケースは TOPコマンドでは判断できない

4.iptables

  • パケットが一杯になった時のエラー1
    ip_conntrack: table full, dropping packet.
    printk: 1243 messages suppressed.
  • パケットが一杯になった時のエラー2
    httpd: apr_sockaddr_info_get() failed for hogehoge.com
    httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
    apacheのエラーとして記録される。
    「apachectl configtest」や「httpd 再起動」した時に上記エラーが出る。
    名前解決がうまくいっていないように見えるが、パケットが一杯になっているだけ。
  • 解決方法

5. iptables 未検証項目

  • iptables ディレクティブは上から順に処理される。
    ディレクティブの記述順を変更するとどうなるだろう?
  • 例えば 80番ポートより先に22番ポートの処理を記述すれば、sshのアクセス処理は優先されるんじゃないだろうか?
  • まだ試していない。優先順位低め。気が向いたときに試す。
    たぶん上手くいく。

6. httpd Client

  • どうやらクライアント数が多すぎたらしい。メモリ不足に陥っていた。
  • 画像サーバー側のチューニング
    • チューニング後
      StartServers 80
      MinSpareServers 100
      MaxSpareServers 100
      MaxClients 100
      MaxRequestsPerChild 8000
      MaxMemFree 768
      なんとか動くようになった。MaxMemFree を2048→768 に減らしたのが効果が大きかった。
      • ただし、この時点では3万PV/hour (推定40万リクエスト/hour)位までアクセスは落ちていた。
      • スタティクファイルのみを配信するサーバーなので、[MaxMemFree] はかなり小さい値でも問題なさそう。
      • 今度 [MaxMemFree 512]まで下げてみよう。
  • HTMLサーバー側のチューニング
    • チューニング
      StartServers 35
      MinSpareServers 35
      MaxSpareServers 35
      MaxClients 35
      MaxRequestsPerChild 4000
      MaxMemFree 2048
      • これで良い感じになった。
      • cgi やphp化したhtmlを走らせているので、1つの子プロセスが結構メモリを食っていた。35個でもギリギリswapが発生するかしないか・・・・という感じ? 少し様子見
      • /etc/php.ini 
        memory_limit = 16M に設定
        無駄にメモリを食わせない。
  • その他メモ

7. KeepAlive

  • 個人的に一番ショックを受けた項目。
    画像サーバーもKeepAlive OFFの方が高速だった!
  • KeepAliveTimeout 1 でもアクセス多いとセッション足りなくなる。
  • 余談メモ

8. TCPセッションの数を増やす


9. 今後の予測をしてみる

  • 次に大量アクセスが来た場合、以下のエラーが発生すると予測する。

10. サーバー増強を視野に入れる

  • ここまで書いたすべての対策を行うと、http Clientに割り当てできるメモリが僅かになる。起動できるClientの数が足りなくなる。結局アクセスを捌き切れなくなる。
    • 2~4GBのメモリが使えるサービスを使う。
    • これ以上 多くのメモリを積んでも、100Mbps 共有回線の20~40%を常時占有する状態になってしまう。
    • メモリ増やすより台数増やす。
  • (今のページ構成の場合) 10万PV/hourのアクセスが発生すると、30Mbpsの転送量が発生する。
    • 100Mbps 共有回線で常時 30Mbps を占有するのはさすがに申し訳ない
    • 回線品質の高い サービスを利用する or クラウドを利用する。
    • 見積もってみたら月額5万コースだ...orz
    • やっぱり さくらのVPSの下位グレードを3~4台借りて負荷分散した方が安いなコレ。
    • あと、画像を減らそう。
  • いちおうクラウドも勉強してみる
    • 一度組めばスケールするの簡単そうだけど、最初に構成組むのが異様に難しいなコレ(^_^;

11. まとめ - 今回 効果があった対策

  1. 画像専用サーバーでもKeepAliveはOFFにする
  2. httpd Clientの数は必要最小限に減らす。forkしないようにする。
    httpdが使うメモリの量もギリギリまで減らす。
  3. メモリに余裕が出来た分をiptablesのパケット処理やTCPセッション数の増加に回す。
    • サーバー素人の浅はかな考えだけど、
      メモリ使用量は
      httpd Client : iptabls+TCP : MySQL = 4:4:2
      くらいにしとけば良いんじゃないだろうか?

今回の場合、この3つが正解だった。
VPSを初めて触った2011年当時、あれこれをチューニングを施したつもりになっていたが、まだまだだった。

12. その他に行った事

  • 画像サーバー側が限界に近かったので、
     ・ブログのヘッダ画像 2個
     ・javascript ファイル 1個
     ・css ファイル 2個
    上記5点を HTMLサーバー側に移動した。

13. チューニング後のパフォーマンス

エラーが出なくなった、パフォーマンスが落ちなくなった、というだけで、処理能力は上がらなかったようだ。次に大量アクセスを貰うまで、正確な結果は分からない。

  • 画像サーバー側
    •  5万PV/hour (70~90万リクエスト/hour ?)でもパフォーマンス低下はしなくなった。
    • しかし、対策前の障害発生中でも、最大 75万リクエスト/hour くらい処理してた。
    • あれ?変わらない...?でもまあ、 チューニング後はサーバーのパフォーマンスが落ちなくなったので良しとしよう。
    • ※チューニング後、まだ5万PV/hour以上のアクセスは来ていない。
  • HTMLサーバー側
    • 12万PV/hour でも何とか応答していたものが、5万PV/hourがほぼ限界になってしまった。(13~15万リクエスト/hour → 30~40万リクエスト/hour に増大したため)
    • 最終的なチューニングが終わった後は 5万PV/hourクラス のアクセスは発生していない。もう少し余力はあるかも?
  • 余談: アクセス解析サーバ
    • Mogura PlusXをインストールしたサーバー。
      CPU負荷は一番高いが、今の所チューニングなしでも元気に動いている。
    • ピーク時・・・・7万件/hour のアクセスを解析。もう少しイケる。
      (12万PVが発生した際、画像サーバーに置いたjavascript が応答しなくなったため、解析ツールにアクセスが飛ばなかった。)

過去、私の見立てが甘かった。

  • 2015年2月に 4.3万PV/hour のアクセスが発生した際、3つのサーバー全てでロードアベレージ0.3前後だった。
  • ロードアベレージだけを見て「この位のアクセスならVPS1個で処理できるかも」とメモをしていたが、大間違いだった。安定稼働できるギリギリのアクセスだったかもしれない。
  • しかし・・・・
    • 当時・・・・
      画像1個のページに9万PV/day
      画像9個のページに4万PV/day
    • 今回・・・・
      画像9~11個のページに9万PV/day X2ページ
      画像9~16個のページに5万PV/day X3ページ
      画像5~15個のページに3万PV/day X5ページ
    • といった感じで、画像サーバーへの負荷は当時の4~5倍は発生していた。前回と今回を比較してはいけないな、とも思った。

次にやること

abテストする。
過去abテストした時は、リアルで大量にアクセスを捌いた経験が無かったので、ベンチマークの数値にイマイチ実感がなかった。今回の経験を踏まえ、もう一回abテストしてみる。

その他: mod_evasive20.c

  • DDos 対策モジュール。
  • 当初から画像サーバーにのみ導入中。
    たまに役に立つので、今回の負荷対策でも停止させずにそのまま様子見。