技術勉強会『開発エンジニアが知っておくべきwebサービスの負荷対策』[TECH VALLEY#6] #tv6

2015年11月18日に開催された技術勉強会『開発エンジニアが知っておくべきwebサービスの負荷対策』に参加してきました。

geechs-magazine.com

進化の読めないシステムの負荷対策 @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」の成長と負荷対策

今日話すこと

DSPaspサービスの成長過程で起こったこと

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とも戦わなければいけない
  • 開発リソースは新機能に使いたい。

GunosyGunosyの高負荷アクセスを支える技術

  • 2年前にGo言語を導入
  • 日本だとGoogleの次に導入した会社では
  • 既にGoで書いた負債返している段階

RailsからSinatra

  • Railsを用いたシンプルなWebサーバ群
  • ユーザは数十万人程度

インフラ

出来る限りサーバを小さく、コストをかけないように

  • DBに対するIOから疑う
  • メモリを効率的に
  • CPUを使い切れてるか
  • 同時コネクション受け入れられているか

キャッシュ

  • ページキャッシュ
  • DBキャッシュ

フレームワーク

  • RailsのオーバヘッドをSinatraを組み合わせてカバー
  • 場所によってはRackアプリを直接書く

基本的な対応でも通常の負荷は対応可能

TVCMとGoの導入

  • TVCMの開始
  • 大幅なUI変更 → ユーザが見れる記事数が数倍に、通知の配信頻度も増加
  • Rails/SInatra→ 1台あたり200req/sec、札束で殴った(インフラエンジニアいない)

短期間・小リソースで性能を向上させる必要性

Goの特徴

Nginx-luaHaskell, node,jsと比較した

高パフォーマンス

  • 安定性
  • Goroutineとchannel
  • CPU使いきれる
  • 比較的省メモリ

** 独立性の高さ * 依存関係は全て1バイナリ * クロスコンパイル良い

安定運用の実績

  • Einhornと組み合わせて安全に再起動
  • GoogleSoundcloudによる実績
  • 最近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でやってみてるがコレジャナイ感

  • Gunosy: RabitMQやNSQueueというオープンソース使うのおすすめ。Dockerのリブチャンはプロセスまたいでアクセスできたかも

Q クエリ監視どうしてる?

  • Sansan スローログとAppの例外で頑張ってた。クエリのレビューはやってる。

Q Redshift高くない?予算の基準ある?

  • Sansan: 基準はないけど、名刺1枚あたりのコスト感でジャッジしてる。安定稼働に注力している。クオリティ、コスト、デリバリーの中ではコストが一番動かしやすい

Q どんなエンジニア求めてる?

  • SanSan: 全般的に求めてる。インフラからアプリから。
  • Gunosy: 全て、マネジメント含めて求めてる。Go書こうぜ!
  • ScaleOut: 一番緊急で欲しいのはデータマイニングエンジニア。オークションの最適価格決定したい。

Q 今の設計の正解をどのように導き出しているか

  • SanSan: 一人で考えない。チームでよく揉む。複雑な部分に違和感をもつ。
  • Gunosy: データフローをいかに構築するか。データの持ち方や配信を思考実験から。まずはサービスを作りきるところが大事では。
  • ScaleOut: 初期から大きく変えていない。問題が起こりつつあるログ転送にKafka使ったり、KVSは集約化した方が良いかもと思っている