Slide 1

Slide 1 text

高速な広告配信サーバの作り方 のコツ GUNOSY  inc.   印南 聡志

Slide 2

Slide 2 text

自己紹介 •  印南聡志(いんなみ さとし)   •  Gunosyのアドエンジニア  (3年目)   –  Gunosyのアド配信サーバ周り全般担当   •  言語   –  Go   –  Python   •  マイブーム   –  AJINOMOTOの冷凍餃子   –  大食い(視るだけ)   •  参照   –  Blog:NO  AD  NO  LIFE(hBp://inchom.hatenadiary.jp/)   –  Github:hBps://github.com/satoshi03  

Slide 3

Slide 3 text

広告配信サーバって?

Slide 4

Slide 4 text

配信サーバ   (API) バッチサーバ 広告情報   (キャッシュ) とても簡単な仕組み 広告情報   (元データ) ELB 広告   リクエスト

Slide 5

Slide 5 text

    広告配信による収益の最大化 目的

Slide 6

Slide 6 text

収益   広告選択   応答性能 可用性

Slide 7

Slide 7 text

高速な広告配信サーバって?

Slide 8

Slide 8 text

50ms  or  die 某社

Slide 9

Slide 9 text

リプレース時の要求性能     1リクエストの応答時間:  50ms  以内   リクエスト数:                                            10,000req/sec  

Slide 10

Slide 10 text

リプレース後のサーバ性能は?

Slide 11

Slide 11 text

5ms

Slide 12

Slide 12 text

    1リクエストの応答時間:  5ms   リクエスト数:                                            10,000req/sec  以上  

Slide 13

Slide 13 text

(あたり前だけど忘れがちな)   広告配信サーバを高速化するコツ

Slide 14

Slide 14 text

1. ボトルネックをつくらない

Slide 15

Slide 15 text

配信サーバ Redis これまでの問題 リクエスト増

Slide 16

Slide 16 text

中央の共有DBを作らない

Slide 17

Slide 17 text

配信サーバ LevelDB S3 バッチサーバ ダウンロード アップロード

Slide 18

Slide 18 text

共有DBが必要な場合は   Writeを集約

Slide 19

Slide 19 text

配信サーバ Redis  Master Redis  Slave Redis  Slave READ WRITE Sync バッチサーバ (ログ集約)

Slide 20

Slide 20 text

プロセスキャッシュを導入

Slide 21

Slide 21 text

配信サーバ Redis  Master Redis  Slave Redis  Slave READ WRITE Sync 取得したデータを 一定期間保持

Slide 22

Slide 22 text

2.  APIサーバは薄く

Slide 23

Slide 23 text

これまでの問題 •  APIサーバ側で複雑な入札ロジックを実装   – 複数の入札ロジック   – 逐次スコアを計算   – 複雑なバリデーション   •  Python  (tornado)  製  

Slide 24

Slide 24 text

対応 •  API側   – Golangで実装   – やることを極限まで削減   •  広告候補の取得   •  簡単なバリデーション   •  バッチ側で複雑な処理を一括で計算   – Python  

Slide 25

Slide 25 text

3. 応答性能を常時計測

Slide 26

Slide 26 text

問題   •  様々な性能劣化の原因   – 機能追加/改修   – データの増加   – アクセス傾向の変化  

Slide 27

Slide 27 text

負荷試験をかけて性能劣化を防止


Slide 28

Slide 28 text

LOCUST •  Python製の分散負荷計測ツール   – テストのシナリオをPythonで記述   – Web  UI  の管理画面   – 管理が容易  

Slide 29

Slide 29 text

LOCUST  構成 ・・・ Locust  slave Locust  master 広告配信 サーバ ・・・ シナリオに応じてリクエストを 生成 Slaveを管理

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

4. コードのチューニング

Slide 32

Slide 32 text

問題       実際に実行すると処理速度が遅い…    

Slide 33

Slide 33 text

pprof •  Goのプロファイラ   – 関数ごとのCPU処理時間を計測   – グラフ描画   •  重い処理を視覚的に発見しやすい  

Slide 34

Slide 34 text

見つかった問題 •  様々な原因   – ライブラリ内の実装   – 入札時の広告の探索範囲が広い   – バリデーションのコスト   – データキャストのコスト   – オブジェクト生成のコスト   – DB接続時のコスト   – ログ出力コスト  

Slide 35

Slide 35 text

対策を全部うってもダメな場合…

Slide 36

Slide 36 text

5.  金で解決

Slide 37

Slide 37 text

金で解決の例 •  Redis  をやめる   – DynamoDB   – AeroSpike   •  スケールアップで対応   – 4xlargeインスタンス…  

Slide 38

Slide 38 text

まとめ •  広告配信サーバの高速化のコツ   1. ボトルネックをつくらない   2.  APIサーバを薄く   3. 応答性能を計測   4. コードのチューニング   5. 金で解決