2012年6月15日金曜日

Amazon ELBをうまくつかうには、KeepAliveを有効にしよう。Timeoutは60秒より だいぶ長くしよう。その背景。

鯖管のメモ帳: AWSのELBでHealthyHostCountが0になるという記事の中で

■AWSのELBとApacheを使う際の注意点

・Timeoutは120以上が推奨

・ApacheのKeepAliveは有効にすべし。ELBとの接続効率があがる。

という形ですでにやるべきことは書いてあるのが、なぜそうなるか。。(いそがしい人は後は読まなくてok!)

根本的な理由としては、ELBはTCPを単にリレーしているのではなくて、アプリケーションレイヤのプロキシであることによるものが大きい。ELBはバックエンドのEC2との間で無通信の場合でも60秒はセッションを維持する。

ELBはTCP Persistent Connectionを提供し、webサーバとの間のTCPセッションをつかいまわすことによってTCPのハンドシェイク時間を削減して高速化している。



webサーバのTimeoutを60秒より短かくするとどうなるか。どうかするとあわれなELBはwebサーバから切られたことを知らず、TCPセッションを使おうとして失敗することもある。折角ハンドシェイクをとばして高速化できるチャンスを逃してしまうことになる。

じゃあなんでELBでないフツーのサイトやフツーのロードバランサで構成するwebサイトにおいて「KeepAliveを無効にして、Timeoutは短かく(たとえば5秒)しよう」という言説が流れているのか。

これは、クライアントがずっとコネクションをはりっぱなしにする傾向があるから。

HTTP keep-alive connection timeouts « FastMail.FM Weblog というすばらしい記事によると、

  • Opera 11.11 – 120 seconds
  • Chrome 13 – at least 300 seconds (server closed after 300 second timeout)
  • IE 9 – 60 seconds (changeable in the registry, appears to apply to IE 8/9 as well though the page only mentions IE 5/6/7)
  • Firefox 4 – 115 seconds (changeable in about:config with network.http.keep-alive.timeout preference)

といった具合。ほとんどのwebサイトにおいては、いくら通信が高速化されるとはいえ100秒も通信維持されても困ることばかりだろう。

「数千数万のクライアントからのコネクションを維持したままだとサーバのメモリを食って死んでしまう」→「ならば、そんなクライアントとは手を切るぜ」→「そのためには..」という常識がうまれた。

ELBはトラフィックが増えれば自在にリソースを変更するすぐれもの。そもそもELBがTCPのセッションを維持するのにどんだけメモリを食っていようが、そんなことはユーザの知ったことではない。そこが普通のロードバランサとは違う。

ELBをサーバとクライアントの間において、コネクションを維持したらどうなる? クライアントががんばって用意しているHTTP keepaliveはELBとの間で維持して、サーバはELBとのコネクションだけを考えればいいから、高速化する。

というわけで、ELBを使わない手はないし、その機能を生かすためにwebサーバはTCP keepaliveを有効にしてTimeoutを120秒にするのがいいのでした。