Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
SmartNews AdServer
解体新書 / ポストモーテム
@tamtam180 SmartNews, Inc.
公開用に何枚かスライドを削除しています。
一部画像の削除、およびモザイクを入れています。
自己紹介
• 名前: たむたむ
• 職業: ソフトウェアエンジニア
• Twitter: @tamtam180
• 趣味: オンラインゲーム, セクシーなサービスを作る事
• OSS-Contribute: TokyoTyrant, Hadoo...
自己紹介
• スクエニを退職したら2chにスレッド立てられて晒された
• こんな事が書かれていた
• 豆腐ハンバーグ美味しいし、
貧乏じゃねーし、
余計なお世話だ
自己紹介
• 広告の事、何もやったことない
広告用語は略語が多い
アジェンダ
• 初期の開発スケジュール
• 使っている技術
• アドサーバが持っている機能
• 広告処理概要, 要素技術, 思想
• 事件簿
• 2016 に向けて
アジェンダ
• 初期の開発スケジュール
• 使っている技術
• アドサーバが持っている機能
• 広告処理概要, 要素技術, 思想
• 事件簿
• 2016 に向けて
初期の開発スケジュール
• 08/15 API仕様確定
• 08/22 iOS SDK提供開始
• 08/29 Android SDK提供開始
• 09/12 Web SDK 提供開始
• 09/15 Adサーバ リリース
• 09/25 An...
複数のアドバイザ
• 思想も設計も既に決まっているのに
後は走るだけなのに
–外部からアドバイザが次々とやってくる
–「思想や設計を説明してくれ」
Initial Commit
テスト
アジェンダ
• 初期の開発スケジュール
• 使っている技術
• アドサーバが持っている機能
• 広告処理概要, 要素技術, 思想
• 事件簿
• 2016 に向けて
使っている技術
• Scala
使っている技術
• Scala
• Java
使っている技術 – Java -
• Scala
• Java(1.8)
• Jetty (Embedded)
• Spring Framework (DI)
• Jackson
• SLF4j / Logback
• FastUtil
• K...
使っている技術 – Middle Ware -
• NewRelic
• JMX with DataDog
• MySQL
• Redis
• DynamoDB
• Fluentd
• Kinesis
使っている技術 – AWS -
• EC2
• S3
• CloudFront -> Akamai
• RDS
• DynamoDB
• ElastiCache(Redis)
• Redshift
• Kinesis
• Route53
Lam...
Kernel Parameter
kernel.sysrq =	0
kernel.core_uses_pid =	1
kernel.sem =	250	256000	100	1024
kernel.msgmnb =	65536
kernel.m...
rc.local
#!/bin/bash
touch	/var/lock/subsys/local
for	path	in	/proc/sys/net/ipv4/conf/*
do
nic=$(basename "$path")
if	[[	$...
アジェンダ
• 初期の開発スケジュール
• 使っている技術
• アドサーバが持っている機能
• 広告処理概要, 要素技術, 思想
• 事件簿
• 2016 に向けて
アドサーバが持っている機能
• Filters
• Beacon Endpoint
• Budget Control
• Frequency Control
• Auction
• Bloom Filter
• Ad Allocation (M...
アジェンダ
• 初期の開発スケジュール
• 使っている技術
• アドサーバが持っている機能
• 広告処理概要, 要素技術, 思想
• 事件簿
• 2016 に向けて
広告処理概要
SDK AdServerELB
CDN S3
Dispatcher
Transform
Filter
JSON
Image
Redis MySQL
Dynamo
DB
Auction
Allocation(最適化問題)
Seria...
初期バージョン設計思想
• なるべく通信はしない
• データはなるべくオンメモリ
• リフレクションは使わない
• 各種処理は計算量O(1), O(LogN)で実装する
• ログ基盤に割くリソースはないので、フロントであ
る程度頑張る
アドサーバが扱うデータの種類
広告処理概要 - データの種類 -
• アドサーバが扱うデータの種類
– ユーザー主体の情報
– キャンペーン主体の情報
– メディア主体の情報
– マスタ情報
– 速報値カウンタ
広告処理概要 - オンメモリ -
AdServer
Redis
Pubsub
MySQL
Master
MySQL
Slave
管理画面
Pub
1.	Sub
2.	起動時に一気にLoad
6.	キャッシュ更新
キャンペーン情報
OnMemor...
レプリケーション遅延対策
広告処理概要 - レプリケーション遅延対策 -
AdServer
Redis
Pubsub
MySQL
Master
MySQL
Slave
管理画面
1.	Update
3.	Pub(ID,	LastTimestamp)
Sub
4.	Tim...
速報値カウンタ
広告処理概要 – 速報値カウンタ -
AdServer
Redis
速報値情報
OnMemory
SDK
Beacon
LogFile Fluentd
S3
Kinesis
Redis
WriterCounter
ReadCounter
予算消...
広告識別子
広告識別子
• 払い出した広告には1件ずつユニークなIDを割り当てている
• UUIDは使っていない
• OTS (One Time Signature)
– 120Bit
– Base64URIしたもの
• ASCII: 20文字
• サーバ...
広告識別子
Name Bit Description
Version 4 OTS Version
Timestamp 41 2012/12/10 00:00:00	起点のミリ秒
NodeId 24 サーバのID
RedisId 8 格納先Red...
広告識別子とメタ情報
OTS
Redis
Hash
Key Field
Hash OTS
META
Value
RES
IMP
VIMP
CLICK
CONV
Time
Time
Time
Time
Time
Object
Impression Smoothing
Impression Smoothing
ベース
Device * Channel * DayOfWeek
/ Per Minute
xxx	IMP
プラン
ScoreXScoreX
Remain
Counter
Base
Debt
Assis...
IMP売り商品
• Standardのアドサーバは2つの広告を扱って
いる
–IMP売りの商品(純広告)
–パフォーマンス広告(運用型広告)
• これを1回のリクエストで返す必要がある
純広告と運用型広告の処理
Channel Channel Channel Channel
純広告
運用型広告
Smoothing
Allocation(最適化問題)
AuctionAuction
Allocation(最適化問題)
Merge
Impression Smoothing
アジェンダ
• 初期の開発スケジュール
• 使っている技術
• アドサーバが持っている機能
• 広告処理概要, 要素技術, 思想
• 事件簿
• 2016 に向けて
注意事項
• ここから、とても残念な発表の連続です。
• 前提として、
–リリーススケジュールが過酷
–大量の機能リリースが必要
• だったという事を念頭にお願いします。
Release頻度
16
34 34
19 20
12
21
13
18
25 25
15 14
16
7
12
2014.11
• 基本機能は実装
– iOS, Android, WebSDKは実装済み
– Budget Control
– Auction
– Frequency Control
– Rehearsal Mode
– Restrict M...
パフォーマンス事件簿 File.1
パフォーマンス障害
• ピークタイムでELBから外れてしまう
• Monitor競合がとても多い事を観測
Java Blocking
• MersenneTwisterがMTSafeじゃなかった
• JavaのPropertiesをオンライン処理で参照してブロック
– getPropertyがsynchronized
• SecureRandomが...
Java Blocking
• 暗号化ライブラリがスレッドブロッカー
– Cipherのインスタンスはスレッドセーフではないので毎
回生成する必要がある
– ただし、Instance化する時にsynchronizedが存在する
– Generi...
Java Blocking
• getClass().get**Name()がBlockする
– OpenJDKのソースを追っていくとBlockする箇所がある
集団食中毒 事件
集団食中毒事件
• みんなでランチに豚カツを食べに行った
• 夕方に体調を崩して早退
• 家で壮大に吐く
• 他にも被害者多数
IAAS事件簿
CDN障害
• クリエイティブ画像が表示されない障害が発生
– CloudFrontの障害
– この年はCloudFrontの障害が多かった
• SLA100%のCDNへ移行
AWS
• ElastiCache
– 自動snapshot取得中にtimeoutが頻発
– Server側に存在しない接続情報が大量に残っていてTCPレベ
ルでACKを返さなくなる
• AMI(EC2)
– 2015.09のAMIで頻繁にイン...
iOSクラッシュ事件
iOSクラッシュ
• 前回、広告を取得した件数よりも、
今回、広告を取得した件数が小さい場合にクラッシュす
る
• 急遽、求人広告を作ってフィラーとして配信する
パフォーマンス事件簿 File.2
パフォーマンス事件 File.2
パフォーマンス事件 File.2
• 2015年4月28日
• 最近、日に日に負荷が高くなっている。
• ゴールデンウィークが危ない
パフォーマンス事件 File.2
パフォーマンス事件 File.2
• 現象
–GC時間が増加している
–FULL GCが10秒に1回くらい発生していた
• 対処
–速報値カウンタのTimeline取得をO(N+LogN)から
O(1)に
–大量のインスタンス生成箇所をつぶした
パフォーマンス事件 File.2
パフォーマンス事件簿 File.3
パフォーマンス事件 File.3
• 2015年5月8日
• GCがやばい
• Class Unloadingが多い
• チューニングしないと!!
パフォーマンス事件 File.3
パフォーマンス事件 File.3
• 現象
– FullGCが多い
– ClassUnloadingが何故か多い
• 対処
– GC抑止のためにパラメータチューニング
– レキシカルスコープを参照しているLambda式
の排除
パフォーマンス事件 File.3
• GCパラメータ(before)
-Xmx****m
-Xms****m
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70
パフォーマンス事件 File.3
• GCパラメータ(after)
-Xmx****m	-Xms****m	-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=70	-XX:Ne...
パフォーマンス事件 File.3
パフォーマンス事件簿 File.4
パフォーマンス事件 File.4
• 現象
– バックグラウンド処理が遅い
• 対処
– 各種実装の最適化
•一部処理の並列化
•不要なデータの読み込みを回避
•通信の回数を減らす
パフォーマンス事件 File.4
パフォーマンス事件 File.4
パフォーマンス事件 File.4
パフォーマンス事件 File.4
アラート通知事件 File.番外編
アラート通知
• 全台バランサから外れていた
• 数時間気づかなかった
• そもそもアラートが来ない
• 何故?
• PagerDutyに登録している電話番号間違ってた
サービスインする
前の話です
アラート通知
• 一時期、毎朝7時のピークで障害が発生した。
• 好きな着メロだったのに嫌いになった。
パフォーマンス事件簿 File.5
パフォーマンス事件 File.5
• 現象
– 速報値を扱っているRedisの通信帯域がつらい
• 対処
– アーキテクチャの変更
パフォーマンス事件 File.5
AdServer
Scan
Timeline	Summary
ToCache
RedisAdServerAdServer
パフォーマンス事件 File.5
• スケールしないもの(Redis)と直接通信をすると
アドサーバがスケールしなくなる
• 速報値を扱うプロセスを用意し、アドサーバは
それと通信をする。
パフォーマンス事件 File.5
AdServer
Scan
Timeline	Summary
ToCache
RedisAdServerAdServer
Process
Summaried Data
パフォーマンス事件 File.5
パフォーマンス事件 File.5
確率計算ミス File.番外編
確率計算ミス
• 確率計算ミス
– 70%で配信したいところが、確率計算をする度にサイコロ(乱
数)を振っていた
– 1回の広告取得で3チャンネルを同時に取得する
– 1回の広告で70%にしないといけない設定だった
– 各チャンネルで70%の判...
確率計算ミス
サービスIN前
です
パフォーマンス事件簿 File.6
パフォーマンス事件 File.6
• 現象
– OTSに紐付くMeta情報が日々肥大化している
• 対処
– Serializerを変更
パフォーマンス事件 File.6
• 今まではデバッガビリティのためにJSONで保
存
• KryoのTagFieldSerializerを使用
• BooleanフラグをOTS側に移動
パフォーマンス事件 File.6
• 空間効率が1/3
• SerdeのCPU処理負荷が1/2
パフォーマンス事件簿 File.7
パフォーマンス事件 File.7
• 現象
– オンメモリのキャッシュがObject生成しすぎ
– そもそもObject生成が多すぎ
– GCが荒ぶっている
• 対処
– データ構造、および処理を大幅改修
パフォーマンス事件 File.7
• リクエストの度に大量にオブジェクトを生成し
ている箇所がある
• キャッシュからのコピーが大量に発生しており、
1リクエスト中のフットプリントが大きい
• 時系列情報をナイーブに持たないでサマライズ
• H...
パフォーマンス事件 File.7
パフォーマンス事件 File.7
パフォーマンス事件 File.7
パフォーマンス事件 File.7
Kryoの前方互換性問題
Kryoの前方互換性問題
• KryoのTagFieldSerializerは前方互換性が無い
– TicketにあるPRも問題を解消できない
Kryoの前方互換性問題
• サーバの更新中に発生する
• 更新中は古いサーバと新しいサーバが混在する
• 新しいサーバが広告を払い出す
• 古いサーバがビーコンを受け取る
• 古いサーバは古い定義のまま新しいバイナリを
受け取る
Kryoの前方互換性問題
• TagFieldSerializer
–Tagの順番に処理していない(Field名でソートし
ている)
–知らないTagIDを読み込むとエラーが出る
Kryoの前方互換性問題
• 改善版
–Tagの順番でソートしてSerializeする
–UnknownなTagを読み込んだら処理を中断す
る
–SKIPしてはいけない
レプリケーション事件簿
レプリケーション事件簿
• レプリケーション遅延
– レポートテーブルが同居していて、しかも巨大なトラン
ザクションが発行されていた
– 30分以上遅延することがあった
– リロードが失敗する事が多発
レプリケーション事件簿
• クエリを修正
• そもそも、レポートDB分離
• キャパシティプランニングを楽にするためにAuroraへ
gRPC事件
gRPC
• サーバ間通信でgRPCを採用した
–ProtoBuf Beta
–Netty Beta
• ELBを通すとNettyの不具合を踏む
• 異常系の不具合をたくさん踏む
アジェンダ
• 初期の開発スケジュール
• 使っている技術
• アドサーバが持っている機能
• 広告処理概要, 要素技術, 思想
• 事件簿
• 2016 に向けて
次のステージへ
• スケールできる土台は一通り作った
• Stream処理、オンライン処理への準備も出来
つつある
今の構成
AdServer
ELB
Redis MySQL
Dynamo
DB
LogFile Fluentd
S3
Kinesis
Provider
HA-PROXY CONSUL
CPU	BOUND
MEM	BOUND
RedShift
B...
最後に
• 意外と広告は面白い
– ソフトウェアエンジニアリング, 大量のログ, 機械学習, 最適
化問題, 大規模トランザクション
– 実時間で実現する必要がある
• 技術だけでなく、ビジネスも楽しもう
• もしかしたら、誰でも出来るかもしれ...
SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム
Upcoming SlideShare
Loading in …5
×

SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム

27,698 views

Published on

広告システムを全く知らなかった私が約2ヶ月弱の開発期間で初期バージョンをローンチ、アーキテクチャも日々変更していき、あれから1年が経過しました。 SmartNews Adsは一般的な広告配信サーバとは異なる特徴をいくつか持っています。今回は運用型広告と純広告型の配信サーバのアーキテクチャを中心に、個人の裁量でどのように設計し、何を採択し、どのように変更していったのかを可能な限り公開し、発生した障害(課題)も晒しながらポストモーテムをします。

Published in: Technology
  • Be the first to comment

SmartNews TechNight Vol5 : SmartNews AdServer 解体新書 / ポストモーテム

  1. 1. SmartNews AdServer 解体新書 / ポストモーテム @tamtam180 SmartNews, Inc.
  2. 2. 公開用に何枚かスライドを削除しています。 一部画像の削除、およびモザイクを入れています。
  3. 3. 自己紹介 • 名前: たむたむ • 職業: ソフトウェアエンジニア • Twitter: @tamtam180 • 趣味: オンラインゲーム, セクシーなサービスを作る事 • OSS-Contribute: TokyoTyrant, Hadoop, Hive, ArangoDB, PipelineDB • SIer (2年) • Square Enix (約6年) – PlayOnline, FF-XIV • Freelance (2年) • SmartNews (いまここ)
  4. 4. 自己紹介 • スクエニを退職したら2chにスレッド立てられて晒された • こんな事が書かれていた • 豆腐ハンバーグ美味しいし、 貧乏じゃねーし、 余計なお世話だ
  5. 5. 自己紹介 • 広告の事、何もやったことない
  6. 6. 広告用語は略語が多い
  7. 7. アジェンダ • 初期の開発スケジュール • 使っている技術 • アドサーバが持っている機能 • 広告処理概要, 要素技術, 思想 • 事件簿 • 2016 に向けて
  8. 8. アジェンダ • 初期の開発スケジュール • 使っている技術 • アドサーバが持っている機能 • 広告処理概要, 要素技術, 思想 • 事件簿 • 2016 に向けて
  9. 9. 初期の開発スケジュール • 08/15 API仕様確定 • 08/22 iOS SDK提供開始 • 08/29 Android SDK提供開始 • 09/12 Web SDK 提供開始 • 09/15 Adサーバ リリース • 09/25 Android版テスト配信(public test) • 10/08 Web版テスト配信 • 10/15 iOS版テスト配信(public test) • 10/27 iOS Submit • 10/28 Android Release • 11/04 Standard Ad配信開始 • 11/16 Premium Ad配信開始 • 12/01 正式リリース & セールススタート というスケジュール表が 8月20日に 投稿されていた
  10. 10. 複数のアドバイザ • 思想も設計も既に決まっているのに 後は走るだけなのに –外部からアドバイザが次々とやってくる –「思想や設計を説明してくれ」
  11. 11. Initial Commit
  12. 12. テスト
  13. 13. アジェンダ • 初期の開発スケジュール • 使っている技術 • アドサーバが持っている機能 • 広告処理概要, 要素技術, 思想 • 事件簿 • 2016 に向けて
  14. 14. 使っている技術 • Scala
  15. 15. 使っている技術 • Scala • Java
  16. 16. 使っている技術 – Java - • Scala • Java(1.8) • Jetty (Embedded) • Spring Framework (DI) • Jackson • SLF4j / Logback • FastUtil • Kryo • Trie4j • MyBatis • Flyway • Nashorn • gRPC / ProtoBuf • Guava
  17. 17. 使っている技術 – Middle Ware - • NewRelic • JMX with DataDog • MySQL • Redis • DynamoDB • Fluentd • Kinesis
  18. 18. 使っている技術 – AWS - • EC2 • S3 • CloudFront -> Akamai • RDS • DynamoDB • ElastiCache(Redis) • Redshift • Kinesis • Route53 Lambda EC2 Container Service CodeDeploy CloudWatch EMR Device Farm SNS CloudSearch Elastic Transcoder SQS
  19. 19. Kernel Parameter kernel.sysrq = 0 kernel.core_uses_pid = 1 kernel.sem = 250 256000 100 1024 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 # auto configure by kernel #fs.file-max = 524280 #kernel.threads-max = 500000 net.ipv4.ip_local_port_range = 10000 65535 net.ipv4.ip_forward = 0 net.ipv4.tcp_syncookies = 1 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 net.ipv4.tcp_wmem = 4096 16384 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_fin_timeout = 5 net.ipv4.tcp_keepalive_time = 10 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.tcp_keepalive_intvl = 4 net.ipv4.tcp_max_syn_backlog=8192 net.core.somaxconn = 65535 net.core.netdev_max_backlog = 65535 net.ipv4.tcp_max_syn_backlog = 65535 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2 net.core.rmem_default = 87380 net.core.rmem_max = 16777216 net.core.wmem_default = 16384 net.core.wmem_max = 16777216 net.core.netdev_max_backlog = 16384 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 0 net.ipv4.tcp_window_scaling = 0 net.ipv4.tcp_timestamps = 0 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.tcp_no_metrics_save = 1 net.ipv4.tcp_ecn = 0
  20. 20. rc.local #!/bin/bash touch /var/lock/subsys/local for path in /proc/sys/net/ipv4/conf/* do nic=$(basename "$path") if [[ $nic == eth* ]]; then /sbin/ifconfig $nic txqueuelen 10000 /sbin/ethtool-K $nic rx off tx off sg off tso off ufo off gso off gro off lro off fi done
  21. 21. アジェンダ • 初期の開発スケジュール • 使っている技術 • アドサーバが持っている機能 • 広告処理概要, 要素技術, 思想 • 事件簿 • 2016 に向けて
  22. 22. アドサーバが持っている機能 • Filters • Beacon Endpoint • Budget Control • Frequency Control • Auction • Bloom Filter • Ad Allocation (Minimum Cost Flow) • Optimizer • Impression Smoother • Web Tracking • Preflight Mode • Rehearsal Mode • Restrict Mode • SelfServe Delivery • Admin API
  23. 23. アジェンダ • 初期の開発スケジュール • 使っている技術 • アドサーバが持っている機能 • 広告処理概要, 要素技術, 思想 • 事件簿 • 2016 に向けて
  24. 24. 広告処理概要 SDK AdServerELB CDN S3 Dispatcher Transform Filter JSON Image Redis MySQL Dynamo DB Auction Allocation(最適化問題) Serializer
  25. 25. 初期バージョン設計思想 • なるべく通信はしない • データはなるべくオンメモリ • リフレクションは使わない • 各種処理は計算量O(1), O(LogN)で実装する • ログ基盤に割くリソースはないので、フロントであ る程度頑張る
  26. 26. アドサーバが扱うデータの種類
  27. 27. 広告処理概要 - データの種類 - • アドサーバが扱うデータの種類 – ユーザー主体の情報 – キャンペーン主体の情報 – メディア主体の情報 – マスタ情報 – 速報値カウンタ
  28. 28. 広告処理概要 - オンメモリ - AdServer Redis Pubsub MySQL Master MySQL Slave 管理画面 Pub 1. Sub 2. 起動時に一気にLoad 6. キャッシュ更新 キャンペーン情報 OnMemory 各種情報はオンメモリで Queue 4. Latch 5. Load 3. キャッシュ更新
  29. 29. レプリケーション遅延対策
  30. 30. 広告処理概要 - レプリケーション遅延対策 - AdServer Redis Pubsub MySQL Master MySQL Slave 管理画面 1. Update 3. Pub(ID, LastTimestamp) Sub 4. Timetamp比較 6. キャッシュ更新 キャンペーン情報 OnMemory キャンペーン Table 最終更新時間 Table 2. Update5. Retry 各種情報はオンメモリで
  31. 31. 速報値カウンタ
  32. 32. 広告処理概要 – 速報値カウンタ - AdServer Redis 速報値情報 OnMemory SDK Beacon LogFile Fluentd S3 Kinesis Redis WriterCounter ReadCounter 予算消化情報 時系列カウンタ
  33. 33. 広告識別子
  34. 34. 広告識別子 • 払い出した広告には1件ずつユニークなIDを割り当てている • UUIDは使っていない • OTS (One Time Signature) – 120Bit – Base64URIしたもの • ASCII: 20文字 • サーバ間で協調する事無く、ユニークなIDを生成できる
  35. 35. 広告識別子 Name Bit Description Version 4 OTS Version Timestamp 41 2012/12/10 00:00:00 起点のミリ秒 NodeId 24 サーバのID RedisId 8 格納先RedisのID Sequence 19 ラウンドロビンカウンタ BitOptions 8 各種フラグ Reserved 16 予約
  36. 36. 広告識別子とメタ情報 OTS Redis Hash Key Field Hash OTS META Value RES IMP VIMP CLICK CONV Time Time Time Time Time Object
  37. 37. Impression Smoothing
  38. 38. Impression Smoothing ベース Device * Channel * DayOfWeek / Per Minute xxx IMP プラン ScoreXScoreX Remain Counter Base Debt Assist Prediction MixedScore Allocation
  39. 39. IMP売り商品 • Standardのアドサーバは2つの広告を扱って いる –IMP売りの商品(純広告) –パフォーマンス広告(運用型広告) • これを1回のリクエストで返す必要がある
  40. 40. 純広告と運用型広告の処理 Channel Channel Channel Channel 純広告 運用型広告 Smoothing Allocation(最適化問題) AuctionAuction Allocation(最適化問題) Merge
  41. 41. Impression Smoothing
  42. 42. アジェンダ • 初期の開発スケジュール • 使っている技術 • アドサーバが持っている機能 • 広告処理概要, 要素技術, 思想 • 事件簿 • 2016 に向けて
  43. 43. 注意事項 • ここから、とても残念な発表の連続です。 • 前提として、 –リリーススケジュールが過酷 –大量の機能リリースが必要 • だったという事を念頭にお願いします。
  44. 44. Release頻度 16 34 34 19 20 12 21 13 18 25 25 15 14 16 7 12
  45. 45. 2014.11 • 基本機能は実装 – iOS, Android, WebSDKは実装済み – Budget Control – Auction – Frequency Control – Rehearsal Mode – Restrict Mode – Naive Allocation – TrackingTool – WebTag
  46. 46. パフォーマンス事件簿 File.1
  47. 47. パフォーマンス障害 • ピークタイムでELBから外れてしまう • Monitor競合がとても多い事を観測
  48. 48. Java Blocking • MersenneTwisterがMTSafeじゃなかった • JavaのPropertiesをオンライン処理で参照してブロック – getPropertyがsynchronized • SecureRandomが刺さる – nextBytesがsynchronized • NewRelicの@Traceが多いと時々刺さる
  49. 49. Java Blocking • 暗号化ライブラリがスレッドブロッカー – Cipherのインスタンスはスレッドセーフではないので毎 回生成する必要がある – ただし、Instance化する時にsynchronizedが存在する – GenericObjectPoolを使った • GenericObjectPoolもsynchornizedなコードが多い – ThreadLocalを使うようにして回避
  50. 50. Java Blocking • getClass().get**Name()がBlockする – OpenJDKのソースを追っていくとBlockする箇所がある
  51. 51. 集団食中毒 事件
  52. 52. 集団食中毒事件 • みんなでランチに豚カツを食べに行った • 夕方に体調を崩して早退 • 家で壮大に吐く • 他にも被害者多数
  53. 53. IAAS事件簿
  54. 54. CDN障害 • クリエイティブ画像が表示されない障害が発生 – CloudFrontの障害 – この年はCloudFrontの障害が多かった • SLA100%のCDNへ移行
  55. 55. AWS • ElastiCache – 自動snapshot取得中にtimeoutが頻発 – Server側に存在しない接続情報が大量に残っていてTCPレベ ルでACKを返さなくなる • AMI(EC2) – 2015.09のAMIで頻繁にインスタンスチェックが失敗する
  56. 56. iOSクラッシュ事件
  57. 57. iOSクラッシュ • 前回、広告を取得した件数よりも、 今回、広告を取得した件数が小さい場合にクラッシュす る • 急遽、求人広告を作ってフィラーとして配信する
  58. 58. パフォーマンス事件簿 File.2
  59. 59. パフォーマンス事件 File.2
  60. 60. パフォーマンス事件 File.2 • 2015年4月28日 • 最近、日に日に負荷が高くなっている。 • ゴールデンウィークが危ない
  61. 61. パフォーマンス事件 File.2
  62. 62. パフォーマンス事件 File.2 • 現象 –GC時間が増加している –FULL GCが10秒に1回くらい発生していた • 対処 –速報値カウンタのTimeline取得をO(N+LogN)から O(1)に –大量のインスタンス生成箇所をつぶした
  63. 63. パフォーマンス事件 File.2
  64. 64. パフォーマンス事件簿 File.3
  65. 65. パフォーマンス事件 File.3 • 2015年5月8日 • GCがやばい • Class Unloadingが多い • チューニングしないと!!
  66. 66. パフォーマンス事件 File.3
  67. 67. パフォーマンス事件 File.3 • 現象 – FullGCが多い – ClassUnloadingが何故か多い • 対処 – GC抑止のためにパラメータチューニング – レキシカルスコープを参照しているLambda式 の排除
  68. 68. パフォーマンス事件 File.3 • GCパラメータ(before) -Xmx****m -Xms****m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70
  69. 69. パフォーマンス事件 File.3 • GCパラメータ(after) -Xmx****m -Xms****m -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -XX:NewRatio=1 -XX:SurvivorRatio=2 -XX:TargetSurvivorRatio=90 -XX:MaxTenuringThreshold=15 -XX:+DisableExplicitGC -Xloggc:/data/logs/_gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1024m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+TraceGen0Time -XX:+TraceGen1Time
  70. 70. パフォーマンス事件 File.3
  71. 71. パフォーマンス事件簿 File.4
  72. 72. パフォーマンス事件 File.4 • 現象 – バックグラウンド処理が遅い • 対処 – 各種実装の最適化 •一部処理の並列化 •不要なデータの読み込みを回避 •通信の回数を減らす
  73. 73. パフォーマンス事件 File.4
  74. 74. パフォーマンス事件 File.4
  75. 75. パフォーマンス事件 File.4
  76. 76. パフォーマンス事件 File.4
  77. 77. アラート通知事件 File.番外編
  78. 78. アラート通知 • 全台バランサから外れていた • 数時間気づかなかった • そもそもアラートが来ない • 何故? • PagerDutyに登録している電話番号間違ってた サービスインする 前の話です
  79. 79. アラート通知 • 一時期、毎朝7時のピークで障害が発生した。 • 好きな着メロだったのに嫌いになった。
  80. 80. パフォーマンス事件簿 File.5
  81. 81. パフォーマンス事件 File.5 • 現象 – 速報値を扱っているRedisの通信帯域がつらい • 対処 – アーキテクチャの変更
  82. 82. パフォーマンス事件 File.5 AdServer Scan Timeline Summary ToCache RedisAdServerAdServer
  83. 83. パフォーマンス事件 File.5 • スケールしないもの(Redis)と直接通信をすると アドサーバがスケールしなくなる • 速報値を扱うプロセスを用意し、アドサーバは それと通信をする。
  84. 84. パフォーマンス事件 File.5 AdServer Scan Timeline Summary ToCache RedisAdServerAdServer Process Summaried Data
  85. 85. パフォーマンス事件 File.5
  86. 86. パフォーマンス事件 File.5
  87. 87. 確率計算ミス File.番外編
  88. 88. 確率計算ミス • 確率計算ミス – 70%で配信したいところが、確率計算をする度にサイコロ(乱 数)を振っていた – 1回の広告取得で3チャンネルを同時に取得する – 1回の広告で70%にしないといけない設定だった – 各チャンネルで70%の判定をしていた – 70% * 70% * 70% = 34.3% – しかも、オペレーション担当に体感30%くらいなんですけど?と 言われて発覚した
  89. 89. 確率計算ミス サービスIN前 です
  90. 90. パフォーマンス事件簿 File.6
  91. 91. パフォーマンス事件 File.6 • 現象 – OTSに紐付くMeta情報が日々肥大化している • 対処 – Serializerを変更
  92. 92. パフォーマンス事件 File.6 • 今まではデバッガビリティのためにJSONで保 存 • KryoのTagFieldSerializerを使用 • BooleanフラグをOTS側に移動
  93. 93. パフォーマンス事件 File.6 • 空間効率が1/3 • SerdeのCPU処理負荷が1/2
  94. 94. パフォーマンス事件簿 File.7
  95. 95. パフォーマンス事件 File.7 • 現象 – オンメモリのキャッシュがObject生成しすぎ – そもそもObject生成が多すぎ – GCが荒ぶっている • 対処 – データ構造、および処理を大幅改修
  96. 96. パフォーマンス事件 File.7 • リクエストの度に大量にオブジェクトを生成し ている箇所がある • キャッシュからのコピーが大量に発生しており、 1リクエスト中のフットプリントが大きい • 時系列情報をナイーブに持たないでサマライズ • HistogramのBin構造を最適化
  97. 97. パフォーマンス事件 File.7
  98. 98. パフォーマンス事件 File.7
  99. 99. パフォーマンス事件 File.7
  100. 100. パフォーマンス事件 File.7
  101. 101. Kryoの前方互換性問題
  102. 102. Kryoの前方互換性問題 • KryoのTagFieldSerializerは前方互換性が無い – TicketにあるPRも問題を解消できない
  103. 103. Kryoの前方互換性問題 • サーバの更新中に発生する • 更新中は古いサーバと新しいサーバが混在する • 新しいサーバが広告を払い出す • 古いサーバがビーコンを受け取る • 古いサーバは古い定義のまま新しいバイナリを 受け取る
  104. 104. Kryoの前方互換性問題 • TagFieldSerializer –Tagの順番に処理していない(Field名でソートし ている) –知らないTagIDを読み込むとエラーが出る
  105. 105. Kryoの前方互換性問題 • 改善版 –Tagの順番でソートしてSerializeする –UnknownなTagを読み込んだら処理を中断す る –SKIPしてはいけない
  106. 106. レプリケーション事件簿
  107. 107. レプリケーション事件簿 • レプリケーション遅延 – レポートテーブルが同居していて、しかも巨大なトラン ザクションが発行されていた – 30分以上遅延することがあった – リロードが失敗する事が多発
  108. 108. レプリケーション事件簿 • クエリを修正 • そもそも、レポートDB分離 • キャパシティプランニングを楽にするためにAuroraへ
  109. 109. gRPC事件
  110. 110. gRPC • サーバ間通信でgRPCを採用した –ProtoBuf Beta –Netty Beta • ELBを通すとNettyの不具合を踏む • 異常系の不具合をたくさん踏む
  111. 111. アジェンダ • 初期の開発スケジュール • 使っている技術 • アドサーバが持っている機能 • 広告処理概要, 要素技術, 思想 • 事件簿 • 2016 に向けて
  112. 112. 次のステージへ • スケールできる土台は一通り作った • Stream処理、オンライン処理への準備も出来 つつある
  113. 113. 今の構成 AdServer ELB Redis MySQL Dynamo DB LogFile Fluentd S3 Kinesis Provider HA-PROXY CONSUL CPU BOUND MEM BOUND RedShift BQ Hive Presto Pipeline DB Realtime Report DMP Batch AdHoc
  114. 114. 最後に • 意外と広告は面白い – ソフトウェアエンジニアリング, 大量のログ, 機械学習, 最適 化問題, 大規模トランザクション – 実時間で実現する必要がある • 技術だけでなく、ビジネスも楽しもう • もしかしたら、誰でも出来るかもしれない • 誰でも出来る事は、誰にも出来ないレベルまで昇華しよう • イノベーションは個人の裁量から生まれる

×