Flickrの中のヒトのLAMP構成プレゼン(Hardware Layouts for LAMP Installations)訳

del.icio.us見てたら面白いファイルがあったので訳しながらはてな記法ワープロでメモったものを公開します。2005/10/18-25に行われたZend/PHP Conference & ExpoにてFlickrのJohn Allspaw氏が発表されたプレゼンの内容のようです。英語読めるヒトは本物のほうをご覧ください。そもそもプレゼンなので長文はほとんどないし、図も入ってるので。天丼に親近感を覚えました。
あと はてな記法ワープロいいですね。ついでにはてな記法なプレゼンツールも是非作ってください!!!
普通にSQL書いてMySQL使うのは出来るけど負荷とかほとんど考えたことないなーと思って「実践ハイパフォーマンスMySQL」読んでたところでhttp://del.icio.us/tag/flickr+mysqlあたりで見つけました。「実践ハイパフォーマンスMySQL」だと6章から9章辺りが関係あります。
このプレゼンの中では前半部はよく見る内容だなと思って見てたんですけど、ロードバランシング以降の話(port exhaustion,10k vs 15k drive, SQUID辺りの具体的な数値とか)は知らなかったので勉強になりました。

実践ハイパフォーマンスMySQL

実践ハイパフォーマンスMySQL

このプレゼンの構成

  • MySQL構成
  • その他、(運営していて学んだ?)秘技
  • キャッシュコンテンツに関する考察

One box

ボトルネック

Two Box

  • トラフィックアプリケーション
  • MySQLだけ他のマシンに。その他(Apache,PHP)は一つのマシンに。
  • このマシンはネットワーク的に分離するべき。
ボトルネック
  • InnodbのDisk I/O
  • MyISAMのテーブルロック
  • ネットワークI/O

レプリケーションを使った多マシン構成

  • 更に高トラフィック
  • 書き込みと読み込みの分離(マスタはinsert/update/delete,スレーブはselect)
  • ネットワーク、disk I/O,その他"ボックス内"ボトルネックは減少する
  • アプリケーション内部でselectとinsert/update/deleteを分離する、か
  • ロードバランシング

スレーブ遅延

  • スレーブがレプリケーションについていけなくなる状態。以下の2要因による。
  • 次のような現象が発生
    • ユーザが入力したデータ(写真、コメント等)がすぐに出てこない
    • その結果ユーザは何度もアクション(再投稿、再読み込み)を起こす。これが更に負荷を高める

Hardware load balancing mysql

  • 標準的なMySQLマスタ/スレーブ レプリケーション
  • 全ての書き込み(insert/update/delete)はマスタへ。
  • 全ての読み込み(select)はロードバランサへ行き、そこから全てのスレーブに拡散される

ロードバランシングの良い点

  • アトミックなクエリにより、アプリケーションに影響を与えずにスレーブに追加・削除が可能
  • モニタリングポイントの追加と異常処理の自動化
  • スレーブプールを一つのリソースとして扱うことができ、許容限度を知っていれば許容量工数計画を更に簡単に出来る

各スレーブの許容限度(最大QPS能力)の測定方法

  1. まずベンチマークして予測する(またはトム(誰)のハードウェアのベンチマーク(http://www.tomshardware.com/ )結果かanadtech.comを参照する)
  2. 予想より多くのマシンを用意
  3. 恐ろしい(?):遅延検出中に、トラフィックが安定している時の製品のスレーブプールからマシンを削除
  4. スレーブ遅延が発生する直前のQPSが許容限度である

ロードバランシングの悪い/困難なところ

  • 全てのロードバランサが均一に作られるとは限らない。全てのロードバランサ会社がこの使い方を想定しているとは限らないので、サポートも受けられないかもしれない
  • 高ボリューム状態で試している人が少ないため、コミュニティでのサポートも期待出来ない
  • わかったこと

ポートの消耗(Port exhaustion)

問題
  • ロードバランサは交通巡査でしかない
  • 多くのコネクションを持つことによる影響:各IP(VIP)毎に64,511ポートまでしか使用できない
  • 64,511 ports / 120 sec.ポート毎だと...
  • IP毎に同時実行可能なコネクションは最大535*1

ポートの消耗(Port exhaustion(cont'd*2続き))

解決
  • データベース スレーブ/ファーム側のIPプールの使用(Netscalerでは"subnet IPs",Alteonでは"PiPs"と呼んでいる)
  • port/connection使用率をモニタし、追加タイミングを知る

ヘルスチェック

  • ロードバランサはMySQLスレーブの状態について関与しないが、3306ポートが応答を返す間はトラフィックを分配する
  • ロードバランサはSQLをしゃべらない。ふるいTCP,HTTP/S,FTPくらい

ヘルスチェック(cont'd続き)

二つのオプション
  • 汚い、が有効な方法
    • 各サーバにモニタを設置し、MySQL動作中はポート3306を切る(またはfirewall)
  • きれいだが、少し動作が増える方法
    • 各サーバにモニタを設置し、xinetd(nagios monitorとか)でチェックを走らせる
    • ロードバランサがポート3306に問いかけてきたら"OK"を返す。そうでない場合はプールから自動的に外される
    • スレーブ遅延の発生とその自動処理の分離検出とそれに対する対抗処理には良い

バランシングアルゴリズム

  • ロードバランサはHTTP,FTP,基本的なTCPは知っているが、SQLは知らない
  • 注意事項二点
    • そのサーバのプール内にいるべきか?(ヘルスチェック)
    • 負荷はどのように平衡を保つべきか?
      • "最低接続数","最低帯域幅","最低hoge hoge" ->駄目
      • 何故なら全てのSQLが均一に生成されるわけではないから
      • "ラウンドロビン"か"ランダム"を使え
      • 何のことかわからない人は:Evil Favoritism(TM)

一方、"in-the-box"考察

  • メモリインターリーブは違いを「生む」
  • 常にRAID10を(あなたが狂人ならRAID0でも)。RAID5は駄目(Innodbでは常に)
  • RAID10は多くの読み込み能力と書き込みペナルティを持つが、RAID5はそうでは無い
  • 常にHW RAID書き込みキャッシュのためのバッテリバックアップを持つ
    • または書き込みキャッシュを使用しない

"in-the-box"考察(cont'd続き)

  • 常に不正/再構築ドライブのための専用モニタ(nagiosとか)を持つ
  • SATA or SCSI? SCSIがいいよ!
  • 10k or 15k RPM? 15kがいいよ!

(ディスク制限されている時に比べて最大20%のパフォーマンス増か)

  • 64bit Linux(AMD64 or EM64T)向け:
    • Innodb バッファプール用にRAMを再大容量にせよ
    • スワッピングは悪、以下のどちらかにせよ
      • 切る(ちょっと怖い)
      • 取り除いて代わりに /proc/sys/vm/swapiness = 0をセットする

10k v.s. 15kドライブはそれほど重要なことか? ->実測値による証明(10k vs 15kなスレーブ遅延発生グラフ)

SAN(Storage Area Network)でMySQLを使う

  • 出来るだけローカルと同じレイアウトにせよ
  • HBA(fiber card)ドライバがLinuxで十分にサポートされているか明らかにせよ
  • データベース間でボリュームを共有するな
  • 正確なQueue Depth Sizeを忘れるな。それはHBA -> switch ->storageから増加する

静的コンテンツのキャッシング

  • SQUID、いいじゃない
  • PHPフロントエンドマシンから変化しないデータを参照する負荷を和らげる
  • 静的ページを生成し、それらをsquidでキャッシィングしよう。

静的コンテンツのキャッシング(cont'd続き)

SQUIDの基本レイアウト

  • squidが80ポートでリクエストを受付
  • キャッシュミスしたリクエストは81ポートのapacheへ。
  • apacheNFSマウントされたディレクトリをdocrootとして使用
  • ローカルサブネットまたは専用ネット上に存在すべき

高容量SQUIDingのための良いHWレイアウト

  • キャッシュディレクトリのために多スピンドルSCSIなものを使え
  • RAIDは使うな
  • ネットワーク接続のストレージ、またはオリジナルサーバから分離されたマシンを使え
  • キャッシュディレクトリのためにnoatimeなext3を使え
  • squid統計をモニタせよ

Flickr:How We Roll

図参照

すばらしいSQUID統計:

  • >2800images/sec, 〜75-80%がキャッシュヒット
  • 〜1000万の写真が常にキャッシュされている
  • 150万のキャッシュがメモリ内にある


2005/11/29 04:29 一部修正しました。
id:kdaibaさん、id:rhosoiさん、ご指摘ありがとうございます。

*1:正確ではない。tcp_tw_recycle,tcp_tw_reuseに関連する

*2:cont'dの意味がわからないのでそのまま