by shigemk2

当面は技術的なことしか書かない

アドテクを支えるScala - Ad Generationの場合 #adtech_scala

ScaleOut出向

Scala歴1年半くらい

Ad Generation開発

  • medibaでScalaを採用した理由
  • Ad GenerationでどのようにScalaを使っているのか
  • sprayを使ったrtb-engen
  • sparkを使ったrtb-engen-log
  • scalaを使ってみて

medibaでScalaを採用した理由

scalaのことには触れられていない

  • GitHubを見るに2011年くらいから
  • Liftを使ったアドサーバーのプロトタイプ(当時のリードエンジニアがScala推し)
  • medibaadでは配信サーバでPlay 集計でspark

Ad Generationについて

SSP Ad Generation DSP ScaleOut DMP ScaleOut

Ad Platfor上に構築されたSSP スマホに注力 RTB関連

  • SDK⇔adserver⇔rtb-engine⇔DSP
  • rtb-engineでオークションをして、一番高い広告が表示される
  • RTBサーバ 集計サーバ

  • fluentd

  • HDFS
  • mesos
  • rtb-engine-log

どのようにScalaが使われているか

  • rtb-engine
  • DSPからの入札をオークションするサーバ
  • rtb-engine-log
  • アクセス数、DSP通信、オークション状況(入札、落札)の集計

rtb-engine

  • spray 1.2.1(akkaベース)
  • アドサーバと枠データ、オークション結果をやりとりする
  • DSPとの入札、応札をやりとり
  • DSPからのレスポンスをまってオークションする
  • 集計画面用のAPI(Angular JS)

  • 現状10台

  • 70億オークション/月
  • 250億bid リクエスト/月
  • 70億x3-4DSP
  • ピーク時
  • 対アドサーバ 4900qps 20000qps

rtb-engineで投げ先を選択する

ピーク時にさばけない * チューニング * configの見直し * コードの見直し

  • akkaの設定とsprayの設定
  • 似たような設定項目が複数ある(サーバサイド、クライアントサイドでいろいろ設定がある)
  • APIレイヤが細かい

  • コードの見直し

  • ブロックする場所をFuture
  • 用途ごとにスレッドプールを割り当て(ログ出力用、など)
  • 良い性能に落ち着いた

rtb-engine-log

  • spark1.0.0(分散コンピューティング用のフレームワーク Scalaだけで動かしている)
  • mesos上で動かしている(Hadoop使っていなくって、sparkと相性が良い)
  • 7種類のログを集計
  • 10分毎、1時間毎、1日毎に集計
  • 入力はHDFS 出力はDB

構成

masterとslaveの構成 cronスクリプトでキックすると、問い合わせして、zookeeperに登録されているサーバに処理を渡してそれぞれでタスクを実行するという形

  • 6cpu 20GB/台x4台
  • master2台 slave4台
  • 500M - 1.5G x 7 x 10 / hourくらいサマる
  • 12 - 40s/job 1ジョブだいたい12秒から40秒

感想

  • sparkを使った感想は概ね良好
  • 集計自体よりもI/Oがネック
  • 程よいサイズで
  • 手軽に試せるし、身構えず書ける
  • spark-shellが試しやすい
  • コレクションを操作するのと変わらず書ける

Scalaを使ってみて

  • 並列処理、並行処理を使いやすい
  • アドサーバやRTBサーバには向いている

  • 用途を選ばない言語

  • なんでもそつなくこなせる
  • 配信も集計も1つの言語で
  • 変更とかしやすくていろいろ楽

  • やっぱりJavaやJVMを知っておいた方がいい

  • Javaの資産を使って書くのがいい
  • スレッドまわり JVMのパラメータなどが分かっていないと難しい

  • チューニングを勉強したい

  • 売上向上につながる柔軟で速やかな分析→調査中

Dynalystが広告配信で使っている技術(Spray×Akka×Kamon×Zabbix) #adtech_scala

Dynalystの立ち上げと、Scalaをゴニョゴニョ

AMoAd DSP など

Dynalyst

ダイナミックリターゲティング

ユーザーの趣味嗜好に適した広告配信を行う国内初のスマートフォンに特化したダイナミックリターゲティング広告

Scala Usage

Scalaが9割がた

  • Spray
  • Akka
  • Monitor

SprayやAkkaを知らない人も、公式ドキュメントやサンプルコードが豊富なので、そのあたりを参考に

計測などはsprayでやっている

裏でakkaがいて、ログをredshiftにロードしている

ロードされたやつをまたakkaに突っ込む

Spray

ドキュメントが良かったこと、テストコードが書きやすいなどが理由

Sprayって何

省略

Concurrency

16コアのスペックに対して、並行処理で効率よく使われている

Future[T]

sprayの実装はFutureでやっている

いろいろなモジュールがある

spray-routingを使うと見やすく書ける

Application Layer

  • Spray Router
  • Bidding Business Logic
  • External Resources
  • Global Dispatcher

レイヤーごとに最適な細かい設定を用意する

http://lampwww.epfl.ch/~phaller/doc/FuturesAsync_ScalaDays2014.pdf

http://akka.io/community/

Futureのテスト(Specs2)

Abstract Future

implicitやモナドはかんがえなくてだいじょうぶ

http://eed3si9n.com/ja/the-abstract-future

モナドやFutureの細かい話はいたしません

Monad is a structure that represents computations defined as sequences of steps

akka

デーモンを常駐している

Typesafe console

Kamon

Summary

  • Future Directive on Spray
  • Abstract Future
  • Akka master/worker pattern(パターンを利用してスケール)
  • Monitoring Akka with Kamon(Akkaの内部をモニタリング)

トライアンドエラーでScalaをごにょごにょしたらいいんじゃないのだろうか

  • ハードルは高い
  • バッドプラクティスが多いとアレ
  • トライアンドエラーを繰り返してアレする

アドテク×Scala×パフォーマンスチューニング #adtech_scala

パフォーマンス改善の心構えと勘所

Demand Side Scienceの紹介

http://demand-side-science.jp/blog/

DSPの開発をやっていた

SSPに対して入札を行う仕組み

オプトグループに参入 unisを開発

ロジックを使って動的に広告を生成

ベンチャーマインドとオプトグループ、サイエンスを軸にする

みんながハッピーになれる世界を目指して

構成

RDMS NOSQL ログストレージなど

JSのチューニングは割愛

パフォーマンス・チューニング概論

システムの課題を解消

  • 高負荷時のアプリケーション挙動
  • レイテンシー(応答時間)が悪化
  • バッチ処理の所要時間が目標を超過
  • 開発ツールの動作が遅い

インフラコストの削減

  • アドテク分野では重要 コストが肥大しがち
  • 大量トラフィック、厳しい応答性能 データベース

目的を見失ってはいけない

  • インフラを増やすだけでいっていうわけではない
  • 目的を達成したらある程度手を引く

  • メトリクスの測定

  • ボトルネックの特定
  • 仮設を立てて調整

プログラムの処理にかかる時間の80%はコード全体の20%の部分を占める パレートの法則

ボトルネックの傾向はDBになりがち

正しい実装さえしていればI/Oバウンドが問題になるのではないか

I/Oって何

メモリ ディスク ネットワーク

パケット転送が一番遅い→CPU命令1回に1秒かかるのならば、パケット転送は5年かかる(日本と西海岸)

  • 100万回のシークが発生すると、2.5hくらいかかる
  • 10GBのファイル1個で1回のシークで済む

JVMパフォーマンストライアングル

http://mogproject.blogspot.jp/2012/06/performance-triangle-for-jvm.html

要件定義

性能要件について関係者の合意を得る

  • 想定ユーザーID数
  • ブラウザ数
  • 広告配信量
  • 目標応答時間
  • 増加計画
  • トラッカー受信量
  • ユニーク数の集計は必要か
  • 売上計画(シーズンにあわせたい)

これらのアーキテクチャの設計に重要

方式設計

  • アーキテクチャ
  • フレームワーク

  • 並行プログラミングモデルの設計

  • ブロッキングをいかに減らすか

環境設計

  • データベース設計(ルックアップ回数)
  • メモリ使用量
  • DB単体の性能

環境構築 プログラミング

時期尚早な最適化は諸悪の根源 vs 効率性は無視できない

  • 線形より悪いアルゴリズムはできるだけ避ける
  • 推測しないで計測する

sbt-jmh

アノテーションをつけて計測する

スループットが表示される(大きければよい)

Scala最適化の例

  • Scalaコレクションを正しく使う
  • 関数呼び出しよりも再帰を使う

ScalaBlitz

http://scala-blitz.github.io/

システムテスト

性能テスト

  • 単体負荷テスト
  • シナリオ負荷テスト
  • エージングテスト(連続稼働)

シンプルなベンチマークツール

Gatling

Scalaで書かれたテストツール

JMeterの時代は終わった(GUIでシナリオを作るのはつらい)

テストとチューニング→運用

ログ出力 異常検知 トレンド可視化

これらをやっていくのが安定稼働への第一歩

本番環境でGCログは出そうぜ

JVMの運用

標準出力/入力はログにとっておく

http://www.slf4j.org/

可視化

最後に

それでも行き詰まったら、C++

アドテク×Scala meetupに登壇してなんかしゃべりました #adtech_scala

こういうタイトルのプレゼンをしました。

タイトルの通りですが、

  1. 大学は文系
  2. 卒業後は居酒屋フリーター
  3. 独学で勉強
  4. ベンチャーでLL
  5. ソシャゲでLL
  6. 急にScala

という流れでしゃべりました。

20分のトーク、会社名を背負ったトーク、パネルディスカッションなど、初めてのことが多すぎて、準備をしたわりに「まあ」の回数がやたら多くてものすごく緊張して言いたいことが伝わったのかどうかすごぶる謎なプレゼンとなってしまいました。

ただ、プレゼンで言いたかったのは、大学卒業して就活失敗してフリーターになっても意外となんとかなるものだし、LLばっかりやってていきなりコンパイル言語の会社に入社しても意外となんとかなるという小並感です。

ピンポイントでScalaをやればいいんじゃないかという意見もありますが、僕はピンポイントでなにかをやるより応用力が欲しいという気持ちがすごくあって、だからHaskellやったりアセンブラやったりして言語やプログラミングに対する理解を深めていきたいというのがあります。

ただ、LLメインでやってきたエンジニアにとってこれが最速のScala習得方法かといえば、それはよくわかりません。

わりと一般的な話をすると、やったことがなかったらどうしたらいいかというと、とにかくやればいいんだと思いました。

とりあえず、「まあ」禁止。