技術勉強会『開発エンジニアが知っておくべきwebサービスの負荷対策』[TECH VALLEY#6] #tv6
2015年11月18日に開催された技術勉強会『開発エンジニアが知っておくべきwebサービスの負荷対策』に参加してきました。
進化の読めないシステムの負荷対策 @Sansan社
サービスの目的
運用しているサービス
- Sansan 3000社利用
- Eight ユーザ数100万人
Eightの裏側にある名刺データ変換の負荷対策について
- 名刺のデータ化: 30万枚/日
- 400万タスク/日
- 累計名刺データ数1億万枚以上
- 600万PV/日
- 1億6000万PV/月
- 常に1600人が同時に利用
- ひとつのタスクは5秒で終わる
インフラ
- Rails
- S3
- RDS
- Redis
- Redshift
- CloudSearch
20 Servers/3RDS & 15 databases
システム課題
依頼枚数が増えていく
増えるタスク 各種処理のスケール
UI応答性能の維持、向上
スケーラビリティの確保
DBシャーディング 失敗 データはかなりの両たまることはわかっていた 蓄積したデータは特定の項目
シャーディングうまくいくはず → いかなかった
リリース後
1年でスロークエリ出始める
シャーディングいやだ
- 項目で検索、集計したい
- 1億のテーブルスキーマ変更辛い
データ化中のデータ
- 頻繁に参照、更新したい
データ化完了のデータ
- 検索、集計したい
ただしいストレージ選択
- データ化RDS
- 検索にはCloudSearch
- 集計はRedshift
十分な情報集まらないなら作りこみしない
データ状態の変化と使われ方
RDBで億行は十分捌ける
microservicesして良かった
データ化は複数の工程
工程をワークフロー化
SimpleWorkflow
利点
- ソフトウェアを小さくできる
- 拡張、保守
- DBを意味のある物理的に分割
スケーラビリティの確保でだいじなこと
- とり得る手法は複数。何を選択するか
- 大事なことは複雑にしないこと
UI性能維持、向上
やったこと: モニタリング、改善
普段やってること
- スロークエリ監視の改善
- サービス魚頭性能のモニタリング
クエリの把握
ORMの発行クエリなんだっけ
クエリ正しいか?
- N + 1
- インデックス
重たい複雑なクエリを分割
- ID取得とデータ取得にわけるとか
ネクストキーロック
- 更新対象行のみがロックされるわけではない
複合インデックスの順番
インデックス効いているかチェック
スロークエリ
- 0.5sで監視
- 1日で見た時の総処理時間が大きい物を優先
サービス応答性能のモニタリング
New Relic
- 応答性能の異常検知
- 異常時の詳細情報
- 傾向の把握
これから
- 無駄な通信の排除したい
- 画面をシンプルに
- キャッシュ
- 画面の部分更新
まとめ
- 正しく把握、設計、実装
- 小さくシンプルに
- SQLコツコツチューニング
- サービス応答性能
Supership社 DSP 「ScaleOut」の成長と負荷対策
今日話すこと
DSPとは
- 広告枠をオークション形式で購入する広告配信プラットフォーム
- リクエストがとんでもなく多い
- レスポンス速度の制約→0.1秒以内にレスポンス
- ピークタイムは20~24時
インフラ
- 配信にRDBは基本的に使わない
- KVSを利用するのが一般的
インフラの変化
- 全てオンプレ
- 当初 配信サーバ48台
- 現在 配信サーバ500台 + 集計サーバ150台
リクエスト数
- 当初 8億/month
- 現在 2000億強/month
- 売上数十億/year
システム構成は当時と大して変わらない
- 初期設計大事
- 社長が元yahooでトラフィックさばいてた経験が生きた
サーバの熱問題
- サーバ自作してた
- 排熱性悪くcpuクロック悪化
- サーバどうやって冷やすかを議論
- 結論: 自作しない
オンプレだとサーバ急に足せない
- 急なリクエスト増
- 優先順位をつけて、売上に貢献しない処理から削る
- 自分たちでサーバ負荷を減らす方法を用意しておく。SSPによっては管理画面からリクエストを止める
- 優先順位が低い枠からオークションに参加する確率を下げる
- ほぼ買えない枠や買っても広告効果を期待できない枠はCPU時間の無駄
- 60msを超えたら処理を打ち切る
- ほとんど配信されない案件にはペナルティを与える
- 案件を無駄に登録出来ないように
- 事前に案件の脚切りを行う
- 特定のユーザは極力同じサーバで処理→キャッシュヒット率をあげる
- 配信時の価格決定に必要な計算をシンプルに
集計系も時間かかる
- Hadoop150台
- Resource Managerで優先度に応じてqueueを分ける
- 集計基盤に、サンプリングされたデータが入るテーブルも用意する
- 概算だけ分かれば良いケースも
- uu数を計算するためのサンプリングを用意する
- ユーザをn個の集合に分割
まとめ
なぜ負荷対策重要?
- 怠るとサービス止まる
- 利用者が増えると負荷は勝手に上がるので定期的に対策が必要
- 重要なのは対策に開発リソースを一定量以上とられないこと
競争力激しい
- googleやFBとも戦わなければいけない
- 開発リソースは新機能に使いたい。
Gunosy社 Gunosyの高負荷アクセスを支える技術
- 2年前にGo言語を導入
- 日本だとGoogleの次に導入した会社では
- 既にGoで書いた負債返している段階
RailsからSinatra
- Railsを用いたシンプルなWebサーバ群
- ユーザは数十万人程度
インフラ
出来る限りサーバを小さく、コストをかけないように
- DBに対するIOから疑う
- メモリを効率的に
- CPUを使い切れてるか
- 同時コネクション受け入れられているか
キャッシュ
- ページキャッシュ
- DBキャッシュ
基本的な対応でも通常の負荷は対応可能
TVCMとGoの導入
短期間・小リソースで性能を向上させる必要性
Goの特徴
Nginx-lua、Haskell, node,jsと比較した
高パフォーマンス
- 安定性
- Goroutineとchannel
- CPU使いきれる
- 比較的省メモリ
** 独立性の高さ * 依存関係は全て1バイナリ * クロスコンパイル良い
安定運用の実績
- Einhornと組み合わせて安全に再起動
- GoogleやSoundcloudによる実績
- 最近Githubのライブラリ急増
ひとつ上を行く負荷対策
プロセスキャッシュ
- DBにアクセスをしないAPIが作れる
- データフローに不整合が起きないように設計
ChannelをQueueとした非同期処理
- Channelのキャパシティを利用
- 直列化と処理効率の両立が可能に
Goとプロセスキャッシュについて
syncパッケージで競合防げる
GoroutineとChannelによる簡易MessageQueue
時間のかかる処理を非同期に、かつ直列に流していく
似非microservices
GunosyをPlatform化
- 予測できない負荷
- 機能ごとのに求められる要件が大きく変わる
- 画面単位(機能単位ごと)で分割することに
Opsworkでの効率化
負荷対策大切なこと
目標設定大事 ボトルネックを見極めること ツールを見極めること→問題に突き当たる前に調査しておこう
まとめ
適切な技術を選び適切にスケールさせていこう
質疑応答
Q. Opsworks使ってて、コード乖離したときにどうしてるか、新機能デプロイ時に設定どう変えているか
- ピーク時がわかっているのでそのタイミングにスタンバイさせている。CustomJsonにすべて設定持たせている
Q.シングルページアプリケーションにした方が良いのでは
- Sansan: 今後の項目によっては考えていく。入力のパフォーマンスあげることは課題
Q シンプルなクエリであればRDSでも捌ける クエリのリファクタリングをしたのか、そもそも設計段階でシンプルだったのか
- Sansan 最初からシンプルなクエリだった。AR使っているので非正規化もけっこうある
Q RailsをGOに移行するの大変じゃない?
- Gunosy nginxの後ろにRailsとGO置いてた。少しずつ変えていたがE2Eテストあるのが理想。UIがないところはGoおすすめ。UIがあるならRailsやDjungoなど。Sessionの共有ちょっと大変だった。
Q Channellを使った通知だとプロセス間通信難しくない?Redisでやってみてるがコレジャナイ感
Q クエリ監視どうしてる?
- Sansan スローログとAppの例外で頑張ってた。クエリのレビューはやってる。
Q Redshift高くない?予算の基準ある?
- Sansan: 基準はないけど、名刺1枚あたりのコスト感でジャッジしてる。安定稼働に注力している。クオリティ、コスト、デリバリーの中ではコストが一番動かしやすい
Q どんなエンジニア求めてる?
- SanSan: 全般的に求めてる。インフラからアプリから。
- Gunosy: 全て、マネジメント含めて求めてる。Go書こうぜ!
- ScaleOut: 一番緊急で欲しいのはデータマイニングエンジニア。オークションの最適価格決定したい。
Q 今の設計の正解をどのように導き出しているか
- SanSan: 一人で考えない。チームでよく揉む。複雑な部分に違和感をもつ。
- Gunosy: データフローをいかに構築するか。データの持ち方や配信を思考実験から。まずはサービスを作りきるところが大事では。
- ScaleOut: 初期から大きく変えていない。問題が起こりつつあるログ転送にKafka使ったり、KVSは集約化した方が良いかもと思っている