O slideshow foi denunciado.
Utilizamos seu perfil e dados de atividades no LinkedIn para personalizar e exibir anúncios mais relevantes. Altere suas preferências de anúncios quando desejar.

Ameba広告の配信制御アーキテクチャを刷新した話 ~オレシカナイトvol.3~

3.767 visualizações

Publicada em

オレシカナイト vol.3 の登壇資料です。
さまざまな配信にまつわる設定を、実際の広告配信に反映させるための配信制御アーキテクチャを、初期ローンチ後1年半で刷新するにいたった経緯と、そこからの長い戦いの歴史を赤裸々に公開します。

Publicada em: Engenharia
  • Seja o primeiro a comentar

Ameba広告の配信制御アーキテクチャを刷新した話 ~オレシカナイトvol.3~

  1. 1. Ameba広告の配信制御 アーキテクチャを 刷新した話 オレシカナイト vol.3 2017-09-27
  2. 2. About me
  3. 3. About me • 駒原 雄祐 (こまはら ゆうすけ) • (株)サイバーエージェント (2010~) MDH アドテクノロジー局所属 • サーバサイドエンジニア • Ameba Infeed開発責任者(2015~)
  4. 4. About me • SIer出身 • サイバーエージェント入社後 • 課金プラットフォーム • コミュニティサービス • 2012年からAmebaの広告のお仕事 • 妻と娘(1歳)とチワワ(3歳)の3人と1匹暮らし
  5. 5. 今日のテーマ
  6. 6. Ameba広告の配信制御 アーキテクチャを刷新 した話
  7. 7. 配信制御?
  8. 8. ネット広告配信の流れ
  9. 9. 作成しているデータ1 • 静的なデータ(マスタデータなど) • 広告枠などの配信面の情報 • どのフォーマットの広告を何個返すか • 配信したくないNG業種や広告主 • 出稿側の情報 • 広告主、広告キャンペーン、配信先プレースメント、入札情報など • 広告のクリエイティブ情報(画像、テキスト、動画など) etc…
  10. 10. 作成しているデータ2 • 動的なデータ • 広告枠ごとに対する配信候補のインデック スなど (様々な条件で時々刻々と変わる)
  11. 11. 当初のアーキテクチャ
  12. 12. 3分間隔(当初)で 設定DBの有効なデータの 全量抽出 配信に適した形への加工 キャッシュサーバへの PUT
  13. 13. バッチサーバが作成した キャッシュデータを 世代別に保持
  14. 14. 定期的に最新世代のポーリング 世代が更新されたら キャッシュサーバの データを吸い上げ オンメモリで保持
  15. 15. 良いところ • シンプルな構成でランニングコストが低い • オンメモリで必要な全データをキャッシュするため低レイテンシ • RDBと配信が切り離されているため、RDBがボトルネックになる 心配がない • RDB側のスキーマ変更等による配信への影響もない • キャッシュ作成時に問題が起きても、次の世代の処理が成功すれば 大丈夫、という安心感
  16. 16. ちなみに この仕組みについて2016年に弊社公式エンジニ アブログで執筆したのでそちらもぜひご一読を https://ameblo.jp/principia-ca/entry-12145898865.html 当時は「A.J.A.」という ブランド名でやってまし たが、いろいろあって現 在は「Ameba Infeed」と いう名前でやってます
  17. 17. 運用を続けるうちに 課題が顕在化
  18. 18. データ量の増加
  19. 19. ビジネス拡大に伴って データ量が増大
  20. 20. 処理時間が長くなり 3分間隔のバッチが 3分では終わらなくなる 単一サーバのため スケールもできない
  21. 21. データ量増大により 容量を逼迫 スケールアップで凌ぐ日々
  22. 22. データ量増大により メモリ逼迫でGCコスト増大 吸い上げにも時間が かかるように
  23. 23. 結果
  24. 24. 当初3分間隔だったバッチ ↓ 10分間隔に
  25. 25. バッチ間隔が延びると・・・ • 配信設定の追加/変更や、ON/OFFなどが なかなか配信に反映されない • 予算切れになってもなかなか配信が止ま らない
  26. 26. アーキテクチャレベルで 刷新することを決断
  27. 27. アーキテクチャレベルで 刷新することを決断 この時点ではこんなに大変だ とは考えていなかった・・・
  28. 28. 刷新の方針(状態目標) • DBでのデータ更新から配信への反映は当初と同じ3 分以内を目標 • スケールしないポイントを作らない • 全データアドサーバ上でのオンメモリにはこだわら ない • ただしレイテンシの悪化は許容範囲内に抑える
  29. 29. それを踏まえた実装方針1 • 配信設定のデータソースはRDBのまま • データソースまで変えると改修範囲がシステム のほぼ全域に及んでしまう • オンラインでの既存データの移行が現実的でな い • 配信時にRDBを直接参照しない点は踏襲
  30. 30. それを踏まえた実装方針2 • 世代ごとに毎回全量を作成する方式をやめる • 静的なデータは随時差分更新に (時間あたりの更新対象は少ない) • 動的なデータは一定間隔で全量更新 (時間あたりの更新対象は多い) • アドサーバがキャッシュサーバを直接参照する方式から 、APIで配信データを提供する方式に
  31. 31. 刷新版アーキテクチャ (ver.1)
  32. 32. RDBはこれまでよりも 高い並列度のクエリを捌くため、 Read Replicaを立てて HAProxy + ELBで負荷分散 (ここは苦肉の策・・・)
  33. 33. キャッシュサーバに 配信制御に必要な静的データ、 動的データが格納される ここにデータが入ることが ひとまずのゴール
  34. 34. 配信制御APIがアドサーバ からのリクエストに対し キャッシュサーバを参照して レスポンスを返す
  35. 35. ジョブスケジューラが キャッシュに載せる データの種類と抽出条件 (例えば最終更新が5分以内の キャンペーンとか) をパラメータにAPIコール
  36. 36. ID Partitioner APIが指定された条件で DBに対し更新対象のデータのIDを 取得するためにSELECT。 取得したIDごとにメッセージを 作成しKinesisに流す
  37. 37. Synchronizer Workerが Kinesisからメッセージを取 り出して該当IDに対する キャッシュデータを作成。 キャッシュサーバにPUT
  38. 38. ポイント • 更新対象のデータ種別、条件を指定できるようにし、差分 更新を可能に • 現在の設定では最終更新から5分以内の条件で毎分起動 (エラー時のリトライも兼ねて) • IDの抽出と、それに対するキャッシュデータ生成とを分離 し、Kinesis Streamで非同期化することで並列化しやすく した
  39. 39. Kinesis Stream • AWSのフルマネージドなデータストリーミングサービス • 複数のConsumerアプリケーションに出力できる • シャード数を調整することで、スループットに応じたス ケーリングが設定できる • KCLというConsumer用のクライアントライブラリが提 供されている
  40. 40. 結果
  41. 41. 問題点1 • 並列度を上げた結果、RDBのレイヤーでRead Replica + HAProxyでもスループットが上がら ず、性能要件を満たせない • ある程度以上更新データが混み合うと急激 にスローダウンする
  42. 42. 問題点2 • Kinesis Stream(KCL?)の特性上、シャードと クライアントとが1:1に紐づいてしまう • 特定のクライアントノードでスローダウンが 発生したときに他のノードで補い合えない • 遅いクライアントが掴んでいるシャードに入 ったメッセージがどんどん遅れてしまう
  43. 43. 問題点2 - 図解
  44. 44. 問題点2 - 図解
  45. 45. 問題点2 - 図解 Shard 3に入ったメッセージだけ どんどん反映が遅れていく
  46. 46. 刷新後アーキテクチャ (ver.2)
  47. 47. RDBをMySQLから Amazon Auroraに • AuroraはAWSが提供するMySQL互換のハイ パフォーマンス、高可用なDBエンジン • 元のMySQLと比較して、同じ構成でのスルー プットが大きく改善して一気に解決 • アプリケーションには(既存のものも含めて) 一切手を入れなくてもよかった (素晴らしい)
  48. 48. RDBをMySQLから Amazon Auroraに • AWSが提供するMySQL互換のハイパフォー マンス、高可用なDBエンジン • 元のMySQLと比較して、同じ構成でのスルー プットが大きく改善して一気に解決 • アプリケーションには(既存のものも含めて) 一切手を入れなくてもよかった (素晴らしい) RDSでのMySQL → Aurora 移行もやりました。 興味ある方は懇親会で つかまえてください
  49. 49. 非同期化部分をKinesis Stream からSQSに • SQSはAWSが提供するフルマネージド なメッセージキューイングサービス • リソースの空いているコンシューマア プリケーションがSQSにメッセージを 取りに行くため、特定のデータが遅延 していくという心配がなく、均一に
  50. 50. 結果
  51. 51. 問題点 • 静的なデータの更新量が多い状況下では Synchronizer Workerが混み合い、更新対象の 多い動的なデータの定期的な更新が追いつか ない • それでも更新要求は一定間隔で送り続けるた め、ジョブがどんどん溜まってしまう
  52. 52. 刷新後アーキテクチャ (ver.3)
  53. 53. ver.2からの変更点 • Synchronizer Workerの後ろにさらにもう一段SQSと Worker(Indexer)を設け、動的なデータ(定期的に全量を洗い直すデ ータ)はそちらに流すようにした • Indexerは広告枠が生きている限り、インデックスデータを作成し たらまたIndexer用SQSにキューイングし、ループすることで繰り 返し処理を行う • Indexer用のSQSには30秒の遅延キューの設定を入れた (30秒+αの時間間隔で動的データが更新される)
  54. 54. 解決! • SQSの遅延キューの仕組みを利用し、動的デ ータが静的データの影響を受けずに一定間隔 (30秒+α)でデータがリフレッシュされる仕組 みが実現できた
  55. 55. 結果
  56. 56. 無事リリース
  57. 57. 配信制御のリプレース 無事完了
  58. 58. 目的は達成できたのか • DBでのデータ更新から配信への反映は当初と同じ3 分以内を目標 • スケールしないポイントを作らない • 全データアドサーバ上でのオンメモリにはこだわら ない • ただしレイテンシの悪化は許容範囲内に抑える
  59. 59. • DBでのデータ更新から配信への反映は当初と同じ3 分以内を目標 • スケールしないポイントを作らない • 全データアドサーバ上でのオンメモリにはこだわら ない • ただしレイテンシの悪化は許容範囲内に抑える 目的は達成できたのか データの更新量により上下するが 概ね2分以内で反映
  60. 60. • DBでのデータ更新から配信への反映は当初と同じ3 分以内を目標 • スケールしないポイントを作らない • 全データアドサーバ上でのオンメモリにはこだわら ない • ただしレイテンシの悪化は許容範囲内に抑える 目的は達成できたのかDB、キャッシュはもとより、各モ ジュールが分散並列処理できるよ うになったため、スケールアウト によるスケーリングが可能に
  61. 61. 目的は達成できたのか • DBでのデータ更新から配信への反映は当初と同じ3 分以内を目標 • スケールしないポイントを作らない • 全データアドサーバ上でのオンメモリにはこだわら ない • ただしレイテンシの悪化は許容範囲内に抑える 平均レイテンシ 約50ms→約65ms なんとか許容範囲と思える範囲内に 抑えることができた
  62. 62. リリース後
  63. 63. 2017年8月に完全移行 • 配信制御API • ピーク時70000qps程度 • レイテンシ3~4ms前後 • 配信への反映 • 概ね2分以内を維持
  64. 64. 今後の課題 • 配信制御APIのレスポンスをもう少し速くしたい • 1回の配信で何度も叩かれるAPIなので、1msの改善が全体では大 きくレイテンシの改善につながる • DSP(=Demand Side Platform)などレイテンシ要件が厳しいもの にも不安なく使えるようにしたい • インフラコストの削減 • システムが複雑化した分、インフラコストは膨らんでしまった
  65. 65. ご清聴ありがとうございました

×