isucon夏期講習2015_2 実践編
TRANSCRIPT
Satoshi "Moris" Tagomori (@tagomoris)
Fluentd, Norikra, MessagePack-Ruby,... Docker logging driver for Fluentd (docker v1.8)
Treasure Data, Inc.
おしらせ
• YAPC::Asia 2015 「ISUCONの勝ち方」 by @kazeburo 08/22 10:00~ (トラックE)
• YAPC::Asia 2015 「How to create/improve OSS product and its community」 by @tagomoris08/22 20:20~ (前夜祭セッション)
今後の練習について
• GCPでisucon4予選環境を作る
• https://github.com/isucon/isucon4/tree/master/qualifier/gcp
• Vagrantなどでその他
• http://d.hatena.ne.jp/tmatsuu/20150815/1439643715
実践編• 予選と決勝の相違点
• 予選の準備
• ISUCONの準備
• ISUCONでやること(予選編)
• 決勝の準備
• ISUCONでやること(決勝編)
• ISUCONアプリケーションのチューン
• ISUCONアプリケーションの設計と再設計
予選と決勝の相違点• 同じところ
• 競技内容、競技時間、チームプレイ
• 違うところ
• 実施環境 (リモート vs 会場)
• サーバ環境 (クラウド vs オンプレ)
• サーバ台数 (1 vs 3~5)
サーバ環境の違い• 予選はクラウド上の特定のインスタンスタイプを指定
• 間違えると失格なので注意
• イメージを与えられる(通常セットアップ済み)
• そのクラウドサービスのアカウントが必要
• 決勝は主催者が準備したサーバを与えられる
• 複数台与えられる
• 1台以外は未セットアップ、ということもある
• サーバセットアップの能力(速さ)も多少重要に
予選の準備• 使用クラウドサービスのアカウント取得
• 今年はGoogle Compute Engine
• Billingの設定が必要(クレジットカード)
• 操作方法を学ぶ
• 少なくとも1度はサーバを立ててログインしてみる
• 手元に必要な環境を作る (SDKのインストール等)
ISUCONの準備• git/ssh/sdk/チャットツールなど、使うものを揃える
• そしてそれに慣れておく
• 制限時間内でのチームとしての動きかたを決めておく
• 実際に7時間とって練習してみるとよい
• 誰が何を使えて何ができるのかがわかってくる
• 変更したコードのデプロイ手順・方法に矛盾がないようにしておく
ISUCONでやること(予選編)• 初動
• レギュレーションを読む • インスタンス起動、アプリケーションの稼動確認
• 初期状態の保存 (特にソースコードと設定) • 初期値の計測、アクセスログの保存と分析
• アプリケーションのチューン(後述) • 終了前後
• スコアの確認、ソースコードや設定の保存
• 主催者への提出物などを確実に (ミスると失格だぞ!)
レギュレーションを読む(2)
• スコア算出方法の確認
• そもそも何をやったらスコアが上がるか?
• どのリクエストの高速化がスコア上昇に寄与するか?
• こだわってもスコアに関係ないリクエストはないか?
• マイナス要因となるものはあるか?
(参考) ISUCON4決勝のスコア算出ルール
• ベンチマークサーバによる採点配分は以下のとおりとする。
• 広告主によって広告の入稿が成功する … 3 点
• 入稿された広告動画ファイルが配信される(impression) … 0.001 点
• 入稿時に指定した destination URLに1アクセスが発生する(click) … 1 点
• 負荷走行終了時、1つのスロット内の全ての広告が配信されていた場合、そのスロットにおける広告の表示回数の5倍が得点に加算される(公平性ボーナス)
レギュレーションを読む(2+)• なおスコア算出ルールはそれ単独だとあまり意味がない
• ベンチマークが送ってくるリクエストのパターンを計測して組合せて考えよう
• 配点が大きくてもリクエスト数がほとんどなければ意味がない
• 配点が小さくてもほとんどのリクエストがそれなら意味がある
• マイナス配点になってしまってもごく少数なら受け入れてもいいかも
• この意味もあって初期ベンチマークの走行とその記録は重要
• アクセスログをとっておいて分析しよう
レギュレーションを読む(3)• 失敗条項
• どういうケースで失格となるかをきちんと把握する
• 過去の例: 毎回異なるのできちんとチェックすること!
• 変更を要求するリクエストの内容が1秒後に参照リクエストの内容に反映されていなければ失格
• HTMLのDOM構造が変わっていたら失格
• JS/CSS/画像に変化があったら失格
• 画像がピクセル数において~%以上変わっていたら失格
• サーバ再起動後に再起動前の状態を再現できなければ失格
レギュレーションを読む(4)
• ベンチマーク走行の詳細を把握しておく
• 並列度を指定するオプションがないか? その値の範囲は?(予選・決勝)
• アクセス先IPアドレスはひとつだけ? 複数指定可能?(決勝)
• ベンチマークの走行時間は? 作業中と本番計測で違いは無いか?(決勝)
決勝の準備
• あまりない
• 予選でできなかったことがあったら復習しておく
• 特に作業手順や情報の共有まわり
• 前日よく寝る、当日余裕をもって集合する
• あんまり環境の準備に気合いを入れすぎない
• 精神の余裕が重要
ISUCONでやること(決勝編)
• 予選とほぼ同じ
• 終了時のみ異なるので注意
• 決勝は作業終了時の状態を使って主催者が別途計測を回し、そのスコアで順位を決定
• 作業終了時にきちんと動いている必要がある
Webサーバ• そもそもサーバを変更する
• Apache httpd -> Nginx など
• パラメータの変更
• プロセス・スレッド数設定、最大コネクション数設定
• レスポンス処理方法の変更
• 静的ファイル(js, css, 変化しないhtml)をWebサーバから返す
OS• ファイアウォールを切る! (ISUCON以外でやらないでね)
• SELinuxを切る! (石川さんごめんなさい ※業界の慣習)
• ほか、だいたい途中で必要になる系
• ソケット再利用間隔の設定など sysctl系
• プロセスがopenできるディスクリプタ数など limits.conf系
ISUCONアプリの再設計(1)
• 複数サーバをきちんとうまく使う
• CPU、メモリ、Disk I/O、ネットワーク帯域
• データの正規化/非正規化により計算量を減らす
• 無駄なデータベース問合せを減らす
• レスポンスを待たせてもいいリクエストのハンドラに処理をまとめる
ISUCONアプリの再設計(3)適切な分散処理構成の設計とデプロイ• ネットワーク帯域を稼ぐ(Webサーバを分散する)
• 分散できるCPU処理をできるだけ分散する
• 分散できない処理は適度にまとめる
• キャッシュしたコンテンツを即座に返す
• 表裏のネットワークがあるなら活用する
• 何度も返すコンテンツは確実にキャッシュする
• Failにならない程度にデータに手を入れる
• HTTPのプロトコルを知る
• keepalive, redirect, cookie, cache-control, ...
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
NginxとStarletを unix domain socketで繋ぐ
(TCP handshakeの削減)
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
Webサーバは2CPUの 2台で構成(3台にも可能)
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
リクエストの多い参照系の アプリケーション処理もここ
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
1CPUのサーバは通常は RedisでDBに専念
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
ただし初期化や更新系 処理だけはここに隔離 頻度が低いから問題なし
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
動画コンテンツの保存はNginxでWebDAV HTTP PUTだけで保存できるし
保存した内容をリクエストに対して 直接返せる
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect動画の投稿リクエストは遅くてもペナルティ無し
レスポンスを返す前に全NginxにPUTする レスポンスの直後から参照リクエストに応答できる
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
なお全サーバは実は同じ設定ファイルと コードで動作している
3台にリクエストを流す構成への変更が容易
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
リダイレクトしているレスポンスに 直接コンテンツを返してもOK
なのを確認して実施
server1
Redis
Starlet initialize post ads reports
Nginx(webdav)
server2
Starlet get ad
post count get redirect
server3
再設計例: ISUCON4決勝(after)
1cpu 2cpu 2cpu
Nginx(webdav) Nginx(webdav)
Starlet get ad
post count get redirect
+ Cache-Control !