Hatak::Techlog

Verba volant, scripta manent.

YAPC::Asia Tokyo 2011 (1日目) に行ってきた

Perl のおまつり、 YAPC::Asia に参加しています。
昨年はプライベートでドタバタしていたので、2 年ぶりの参加でした。前回に比べて参加者も多く、それでいてスムーズなイベント進行と素敵なトークの数々でとても楽しい時間を過ごしています。 ひとまず 1 日目を振り返りつつ、聞いたトークをまとめておこうと思いました。

振り返ると、インフラ寄りな内容を選んでいたこともありますが、今日は Perl に限らない話も多かったように思います。それだけ広い知識と経験が必要で、いろんな所でいろんなひとが挑戦していることがわかってわくわくしましたが!


Perl 5.16 and beyond

今回のスペシャルゲスト、 Perl5 開発リーダーの Jesse Vincent (@obra) さんの講演。Perl5 の開発プロセスがどのように変化してきたか、そして今後の Perl5 がどうなっていくのかというお話でした。 (英語のセッションだったので内容を頭の中で理解するのが追いつかずメモ取りきれなかったので間違えていたら指摘をお願いします。。)

Pumpking

Perl5 の開発体制が整ってきたのでリリーススパンが早くなってきた。

  • VCS を Git に変えた
  • リリースをコミッタの持ち回りに
  • 約 1 年で 5.12 → 5.14 そして Perl 開発マネージャーとしての仕事についての説明。
  • Perl5 の方向性を決める
  • 開発メンバーにタスクを振る
  • 仕様に関する文書をまとめる つまり “You make Perl”

Vision

“New version should not break old environment” と “Perl should run everywhere”

  • 互換性を重視しつつ、進化は続ける
  • use でバージョンを指定した場合はその指定されたバージョンの挙動に合わせる – 古い文法には極力沿うようにする – 指定されたバージョンよりも新しい機能は動かないようにする

そして機能をシンプルにして、仕様を明確化させる。

  • Core の機能をモジュールとして分割する – “traditional” と “bootstrappable” の 2 種類のエディションに
  • 別の言語でも再実装できるように – 生き残るために

Webアプリケーション高速化

※講演資料 YAPC::Asia 2011 / 高速化のはなしとか ライブドアの mala (@bulkneets) さんの講演。すべてを聞いたあとの「気持よく書ける範囲で最適化」というまとめに納得しました。先回りしてキャッシュしておく戦略は難しそうですが、効果は大きそうなのでやってみたいと思っています。

はじめに

  • チューニングについてのスタンス – 努力だけでどうにもならないときは、卑怯な手段を使う – バレなきゃイカサマではない
  • 方法はいろいろ – 頑張って高速化する「努力」 – そもそも処理しない「Hack」 – SSD など「財力」
  • どの方法を選ぶかはケースバイケース – 適切な手段を選ぶことは必要 – ハードウェアはすごく早くはならない

一般的な方法

  • ボトルネックを見つけてチューニング – リソースやスロークエリ等の監視 – プロファイリング — Devel::NYTProf / Devel::KYTProf — 計測用のスクリプトを作成しておく —- Shell::Perl が便利 — stopwatch で時間計測 —- benchmark だと CPU 時間を計測する —- 1 req の処理時間を測って感覚を把握できるようにする
  • キャッシュや静的生成 – バックエンドに飛んだら負け — PSGI でも 数千 req/sec しかさばけない — Nginx などの静的レスポンスなら 数万 req/sec – 状況に応じてキャッシュを選択する — データ量・更新頻度・揮発性 — データ型サポート — 複数処理で使いまわすか
  • コード – テクニックを抑えておく — 必要なデータはまとめて引いておく — 遅延評価 — MySQL では “WHERE IN” / “BULK UPDATE” の活用 — memcached では “get_multi” を使ってプロトコルオーバヘッド減らす

あまり真似されない方法

Bloom Filter

  • KVS / MySQL への問い合わせ前に大雑把なクエリを間引く – 精度はデータ量とのトレードオフ – <a href=”http://fallabs.com/blog-ja/promenade.cgi?id=70
  • 存在しないキーを大量に問い合わせるケースで有効 – ブックマークのカウンタ – ブラウジング履歴調べる – 富豪的クエリ
  • memcached への問い合わせなどでネガティブキャッシュを減らせる
  • 使うのは CPU – パラメータにも依るが 数万 qps 処理できる – ハッシュよりは遅く、リモートの DB よりは早い

Cache warmup

  • よく使われるデータを先に載せておく – MySQL innodb – memcached
  • ユーザがページを表示した瞬間に id を Q4M に入れる – worker が先回りしてキャッシュに入れる
  • ライトスルー方式との違い – 参照されそうなときに乗るのでヒットしやすい – キャッシュ生成がレスポンス生成より遅いと重くなる

Varnish + ESI

  • 最近流行りの構成は Nginx + Standalone PSGI でいい
  • Varnish が使えるポイント – 高速化 – vcl で書ける – ESI が使える — Akamai が開発した SSI のような仕組み
  • ESI を使うとパーツごとにキャッシュできる – 利点 — フロントとバックエンド間の転送量節約できる – 問題点 (主に v2) — Varnish が Contents-Length 返してくれない — Varnish が ETag みてくれない — メモリが足りなくなくなると重くなる

新はてなダイアリーの裏側

はてなの大西 (@yasuhiro_onishi) さんの講演。はてなダイアリーが “Hatena Blog” にリニューアルを解説するセッションでした。主に表示に関わる仕様変更をユーザの行動に影響しないようにするため、様々な工夫をされているのですね。。

技術的な話

  • 外部ドメイン化 / JS フリー化 – 従来ははてな共通ドメイン・ログインクッキー – 利点 — どのサービスでもログイン状態になれる — 編集 / 閲覧の区別がない – 欠点 — XSS 脆弱性に弱いので自由に JS 書けない
  • クロスドメイン通信 – ヘッダを iframe 化することでログイン時のメニューを表示
  • フィードバックシステム – iframe で表示するヘッダに設置する – 運営への意見をフィードバックする際に、ユーザがどのページにいるかを一緒に送れる
  • アクセスコントロール – ユーザの自由な認証設定に応じていきたい — 一方で認証の仕組みが複雑になってしまう – ブログごとに閲覧用 cookie を発行することで対応
  • はてな記法++ – ブラケットを [.. から < ..> に変更 — タグとして解釈可能となり style 属性付与ができたりする
  • キャッシュ戦略 – なるべく外側でキャッシュする – キャッシュに依存しない作りにする – 基本はページまるごとキャッシュ

Webアプリでパスワード保護はどこまでやればいいか

安全なWebアプリケーションの作り方」の著者、徳丸浩 (@ockeghem) さんの講演。同本の 5.1 章を解説する流れで説明されていましたが、RainbowTable などの説明がとてもわかり易かったです。

本日のテーマ

単に HASH 化しただけでは元に戻せるのか? - クラックは 2 種類 – オンラインクラック : リモートからのパスワード試行 – オフラインクラック : 情報を盗み、攻撃者の手元で平文パスワードを求める - パスワードだけ保護する理由とは? – パスが漏れてれば他の個人情報も漏れている – パスワードを使いまわす利用者もいる – パスワード保護は運営者の義務

オンラインクラック

  • パターン – 総あたり攻撃 : 時間かかるのであまりやらない – 辞書攻撃 : 辞書のものを順にパスワードとして試行 – その他のバリエーション — ジョーアカウント探索 : ID と pass を同じにしているものを総あたりで試行 — 逆総当り攻撃 : パスワード固定でユーザを変える —- 普通の総当りに比べて成功確率高い —- Twitter のような ユーザ ID がわかっているようなものは特に
  • 対策 – 強いパスワードを付けてもらう – アカウントロックが基本 – ジョーアカウントは登録時にチェック – 逆総あたり対策として、辞書のものは NG にする

オフラインクラック

  • なぜ暗号化ではなくハッシュなの? – 暗号化は鍵管理が難しいが、ハッシュは鍵管理が不要
  • ハッシュは安全? – 一般的にはハッシュ値から平文を「復元する」ことはできない – パスワードの場合は特別な事情がある — 短い文字列 — 文字種限られている
  • ハッシュから平文に戻す方法 – 総当たり攻撃・辞書攻撃 — オフライン型のパスワードクラックツール —- GPU 高速化に伴ってかなり高速にできるようになった – RainbowTable — 逆引き表 + 還元関数でチェーンを作る —- 単純な逆引き表は膨大なデータ量 —- 圧縮するために還元関数を使う — チェーンの「先頭」と「末尾」だけ保存すればいい — 探索はハッシュに還元関数をかけていって「末尾」と一致するかどうかを見ればいい —- 一致したらその「先頭」がパスワード — どのアルゴリズムでも実現できる —- アルゴリズム特有の脆弱性を使っていない – Salt — ハッシュの元データに追加する文字列 —- 見かけのパスワードの長さを長くする — ユーザごとにソルトを変えることでパスワードが同じでも異なるハッシュ値を得られる – Streching — ハッシュの計算を繰り返ことで、ハッシュ計算を遅くする — メリット/デメリットある

パスワードの暗号化は本当に無理か

  • HSM (Hardware Security Module) ならばいける – 復号化機能を無効にできればよい

Perl で構築された中規模サイトの DC 引っ越し記録

※講演資料 <a href=”http://dl.dropbox.com/u/224433/YAPC2011/index.html KAYAC の sfujiwara (@sfujiwara) さんの講演。”こえ部” をレンタルサーバから自社インフラに移設した時のまとめを紹介されていました。アップロードデータのあるサービスで新しいファイルを旧環境でケアしてあげる方法は難しそうですが、Nginx の効率のよい使い方などは参考になりました。

こえ部 & システム概要

  • 音声投稿共有サイト
  • 機能 – flash + kamaitachi でブラウザからその場で録音 – メール添付 – “こえ部 Live!” は Red5 + AnyEvent
  • ユーザ数 42万
  • 100万 PV/day
  • UU 20,000 人
  • Traffic – Outgoing : Max 70 Mbps – Inbound : Max 25 Mbps
  • もともとレンタルサーバを組み合わせてやっていた
  • サーバ増設 + SPOF整理しながら自社インフラに移設 – 同時に KVM 環境に移行

旧システムと新システムのアーキテクチャ

  • HAProxy – App サーバの local に HAProxy — 3306 : MySQL master — 3307 : MySQL slave — 同様に KyotoTycoon も設定
  • 今も残っている SPOF – MySQL master — MHA を試すとか? – NFS

止めずに移行するための準備と仕掛け

  • 段階的に切り替えたかった
  • 手順 – 新サーバ群立ち上げ — 合わせてチューニング —- mk-duplicate-key-checker — ファイル書き込みの job は新旧それぞれで別々の worker が処理 — 旧環境にないファイルは Nginx の error_page を使って内部で reverse proxy – DC 間に VPN — OpenVPN で構築 — 100 Mbps 回線で RTT 3-4 ms / スループット 60Mbps – データ・トラフィックを VPN 経由で移す – サービス IP を DNS で切り替え — サービス停止は 1 時間くらいで

実際の移行作業顛末

  • 4 日に分けて処理して無事終了
  • ユーザクレームは作業に関係しない箇所のみ – ユーザにとってのメンテナンスは「不満だった部分が解消される」という期待になる

Mobage オープンプラットフォームの事件簿

DeNA の zigorou (@zigorou) さんの講演。モバゲーオープンプラットフォームの障害事例とその対処法についてのお話でした。大規模サービスの障害事例はとても参考になります。「原因究明」「失敗防止」「知識配布」という項目でまとめているのもわかりやすかったですし、これらの障害報告会を社内で定期的に行なって共有する体制を作っているのはとても良いことだと思いました。

DeadLock 多発事件

  • ある API が突然 DeadLoak が多発するようになった – もともと Transaction が比較的長い処理だった
  • 原因究明 – 特定の UPDATE 文が原因 — 件数カウントのために TRIGGER で summary 作っていた部分 – 対象データセットに Group という概念があった — 特定のデータ群をカテゴライズしていた — 特定の Group に集中してしまうと DEADLOCK になってしまう
  • 失敗防止 – Trigger ではなく Queue として扱う — Queue から 100 件とりだして UPDATE 文つくる
  • 知識配布 – アプリに人気が偏るとデータが集中する — 設計やモデリングで予見できた障害かもしれない – Queue のときは Index 不要なのではらない

INSERT vs DELETE

  • ある API の古いデータを消そうとしたが DELETE が INSERT に追いつかない
  • 原因処理 – PURGE 処理 — master で全力で DELETE すると slave 遅延する — よくやるのは DB 負荷にかかわらず一律の weight 入れる – Loop::Sustainable — 適切な weight をいれてくれる – SET SQL_LOG_BIN = 0 – もっと発想を豊かに — おかわり作戦 — 余計なデータを PURGE した新しい系統にいれる
  • 失敗防止 – 極力速く DELETE できる schema を — DELETE していくのはほぼ無理 — 構造考えて PARTITIONING をするべき – ダメなら消し込んでデータ入れ替え
  • 知識配布 – おかわり作戦 — DB 運用すると発生する Flagmentation の対策にも鳴る

有名人問題

  • 有名人ユーザでレスポンス低下したりする
  • 原因究明 – 取得件数が異常に多い — TemporaryTable が作られている
  • 失敗防止 – SQL_CALC_FOUND_ROWS / TemporaryTable は重い — ユーザを順次取得してやってみる – Iterator::GroupedRows

まとめ

  • 失敗から得られることは大きい
  • スピンアウトで新しいものできる
  • 分業大事
  • 失敗に対して常に問題

Mobageソーシャルゲームにおける大規模サーバ運用 with Perl

DeNA の riywo (@riywo) さんの講演。DeNA の内製 SNG の運営におけるチューニングのお話でした。台数が増えると起きてくる問題や、人気が出てイベントなどでアクセスが集中すると起きる問題など、そのアプローチが参考になりました。DevOps 的な問題点についても、規模は小さいながらも同じような状況を見ている立場としてとても共感できるものでした。

Application Tuning

  • アプリケーション台数は多い – それぞれからつなぐ先を減らすほうが良い
  • 2 つの接続インターフェイスの改善 – Resolving Module — DNS での名前解決で失敗するとサービスに影響が出る — application が MyDNS の中身をまるごとキャッシュ —- アプリで dns weight みてバランシング —- DNS 全滅した場合でもローカルキャッシュでしばらく動く – Handler Socket — ユーザデータをキャッシュせず直接 DB に取りに行く — アプリケーション CPU の負荷が下がり高速化した —- memcached の consistent hash の計算で意外と使ってた
  • 現在のアプリへの “追加” は簡単にできる – インパクトが大きな箇所のところだけ置き換えればいい – チューニングしたいところだけピンポイントで入れられる

Database Tuning

  • 一気に成長することで問題が顕在化
  • DB 分割を繰り返してきた – 多くの場合は DB 容量の問題が大きく影響 – database handle を追加して切り替え — config で同じところを見続けるようにしておく — メンテナンスで指し先を切り替える
  • 怪盗ロワイヤルのイベント – 同じお宝を奪い合うにしてみた – ユーザを探す所が重くなった — レベルが近い順に探していくため — レベルのカラム構造を変えて、ざっくりの level-class をつけるようにした – Lock wait timeout 発生 – DeadLock 起きにくくする — ロックを取得する順番を決める – イベントをすることで既存機能に影響することがある

DevOps

  • イベント開始がシェアされてなかった – シェアされてても全部の問題が予測できるわけではないけど。。。
  • それぞれの視点で問題を考えてアプローチする – Dev – Ops
  • ちょっとしたプロジェクトマネジメントとして考えている

LT もレベルが高く面白い発表ばかりだったのですが、聞くことに専念していたのでメモとってませんでした。。。 そして前夜祭のメモまとめてないことに気づいたのであとでまとめます。

2 日目につづく。