Share
Embed
ABEMAのCM配信を支えるスケーラブルな分散カウンタの実装
CNDW2025にて、ABEMAのCM配信を支えるスケーラブルな分散カウンタについて、設計思想から具体的な実装までご紹介しました。
Honoka Toda
November 18, 2025
Transcript
76 slides
-
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
1 ABEMAのCM配信を 支えるスケーラブルな 分散カウンタの実装 2025 November 19 Honoka Toda -
AbemaTV, Inc. All Rights Reserved 戸田 朋花 Honoka Toda 株式会社CyberAgent
/ 株式会社AbemaTV CM配信システムのバックエンドの開発を担当 2 Profile hono0130__ hono0130 2025年未踏IT 曾川PMプロジェクトのクリエイター -
AbemaTV, Inc. All Rights Reserved ABEMA 無料 すべてのひとが楽しめる ⽣中継 ライブならではの臨場感
同時性 ⽇本のイマを捉え流⾏をつくる 報道 常に新鮮なニュース 利便性 時間と場所からの開放 ABOUT ABEMA -
AbemaTV, Inc. All Rights Reserved 6 1. CM配信における課題 2. カウンターの設計
3. Google Cloud上での実装 4. 様々な種類のカウンターの実装 5. さらなるスループットの向上 INDEX -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 8 ABEMAのCM配信はパーソナライズ可能 多種多様なイベントを処理しないといけない 候補A 0回視聴 候補B 1回視聴 候補A 30代女性 候補B 20代女性 候補C 20代男性 ユーザーの視聴履歴に基づく広告配信 ユーザーの属性に基づく広告配信 -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 9 目標インプレッションに近づけるように配信を制御する 広告A: 目標200 広告A: 実績50 広告配信サーバー カウント 現在の広告Aの実績は? 50 インプレッション=広告の表示回数 -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 10 目標インプレッションに近づけるように配信を制御する 広告A: 目標200 広告A: 実績50 広告配信サーバー カウント 50 広告Aを計150人に配信 現在の広告Aの実績は? -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 11 大量のインプレッションで処理が詰まると計測が遅れる 広告A: 目標200 広告A: 実績50 広告配信サーバー カウント 広告Aに+125 インプレッションが発火 処理が詰まると計測が遅れる +1 +1 +1 -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 12 計測が遅れた状態で配信制御すると実績と目標が乖離する 広告A: 目標200 広告A: 実績100 広告配信サーバー カウント 100 過小な実績を返却(本当は175) 現在の広告Aの実績は? -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 13 広告A: 目標200 広告配信サーバー カウント 広告Aを計100人に配信 広告A: 実績100 100 過小な実績を返却(本当は175) 現在の広告Aの実績は? 計測が遅れた状態で配信制御すると実績と目標が乖離する -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
合計250 目標オーバー💥 CM配信における課題 14 広告A: 目標200 広告A: 実績175 広告配信サーバー カウント 広告Aに+75 インプレッションが発火 計測が遅れた状態で配信制御すると実績と目標が乖離する -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 15 人気番組の生放送ではトラフィックがスパイクする 広告配信サーバーのあるサービスのRPS 広告配信サーバーにリクエストがくるのは広告配信前後だけ 人気番組の生放送時は広告前後で急激にスパイクする 1分で約200倍にスパイク -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
CM配信における課題 16 高スループット 多様で大量のイベントをリアルタイムに捌く必要がある 読み取りも書き込みもスケーラブル 高カーディナリティなデータも扱える -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
カウンターの設計 19 値の正確性を犠牲にする代わりに高速に書き込むレイヤー -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
カウンターの設計 20 定期的にデータを確定させて値を補正するレイヤー -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
カウンターの設計 21 ホットストレージとコールドストレージを使った読み取り -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 23 -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 25 ストリームはPub/Subを採用 複数サブスクリプションを作ればファンアウトできる ストリーム -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 27 ホットストレージはマネージドのValkey Cluster を利用 ホットストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 28 Valkey Cluster は in-memory key/value store の Valkey のクラスタ構成 in-memory store なので高スループット クラスタ構成では読み書きの水平スケールが可能 ホットストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 29 Valkey Cluster は key のハッシュ値でシャーディングする ノードが水平スケールし読み書きの負荷分散が可能 ホットストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 30 リードレプリカで読み取りのスケールが可能 リードレプリカを追加することで 読み取りの負荷を分散できる ホットストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 32 イベントストレージは BigQuery を利用 イベントストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 33 BigQuery は Partitioning によりスキャン範囲を減らせる Column1でPartitioningした例 カラムの値によってテーブルが 物理的に分割される クエリの際は該当するPartitionしか スキャンされない イベントストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 34 カウント時刻で Partitioning してクエリを効率化 スキャン範囲を絞って コストとパフォーマンス を最適化 イベントストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 35 BigQuery は Clustering によりデータの並び替えができる Column1でClusteringした例 レコードがカラムの値の順序で並び替えられて配置される スキャン範囲の最適化や集約の効率化が可能になる イベントストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 36 カウンターのキーで Clustering してクエリを効率化 イベントストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 38 コールドストレージは Spanner を利用 コールドストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 39 Spanner は Google Cloud で利用できる分散 RDB 処理性能やストレージの増減が簡単にできる マネージドサービスなのでメンテナンス不要 コールドストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 40 Spanner は比較的小規模から利用可能で低コストに使える 最小単位の100Unitではコンピュート料金月$85 簡単にデプロイできるオートスケーラーがある 同じSLAの場合CloudSQLで最低月$480、AlloyDBで$581 オートスケールを活用すれば比較的安価に利用できる 全て東京リージョン - Spanner は Standard Edition で 100 unitsの場合 - CloudSQL は Enterprise Plus Edition で HA 構成有効、db-perf-optimized-N-2 が 1 ノードの場合 - AlloyDB は 2vCPU で HA 構成が有効の場合 参考 コールドストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 41 Spanner では主キーの順でレコードが物理配置される Primary key1と Primary key2の 複合主キーの場合 コールドストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 42 カウンターのキーとカウント時刻を主キーにすることで 時間範囲のクエリを効率的に行うことが可能 コールドストレージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実装 44 ライターと補正バッチはGKE上のPod / CronJob コンピュート -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
Google Cloud 上での実践 46 • カウンター • 時系列カウンター • ユニークカウンター カウンターの種類として以下を設計 -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 48 カウンターはKeyに対して値を数え上げる カウンター クライアント keyがuser1の カウント値は? 1 keyがuser1:20250101の カウント値は? 5 カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 49 Valkey 上では String 型によって表現できる カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 50 INCRBY でカウントアップし、GETで値を取得 カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 52 時系列カウンターは時間範囲での取得が可能なカウンター カウンター クライアント keyがcampaign1の 直近1分のカウント値は? 13 時系列カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 53 Valkey では Sorted Set 型を使うと範囲取得が可能になる $ ZRANGEBYSCORE key1 1 10 member1 member2 member3 時系列カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 54 Score を UNIX タイムスタンプ、Memberをカウント値 にすれば範囲取得が可能 しかし、このままだと カウント値を インクリメントできない… 時系列カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 55 Hash型は1つの key に複数の key value を持たせられる型 時系列カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 56 書き込み時に Hash を利用することでインクリメント可能 時系列カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 57 Hash で書き込んで定期的に Sorted Set に変換することで 時系列カウンターを実現可能! 時系列カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 58 Valkey の Functions 機能を使うことで高速に変換できる Functions は Valkey に事前に関数を登録すると その関数を呼び出すことで指定の処理ができる機能 ノード上で実行されるので、同じノードに存在しているデータのみ取り扱える 時系列カウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 60 ユニークカウンターはユニーク数を数えるカウンター ユニークユーザーの計測等に活用できる カウンター クライアント keyがcampaign1の ユニークな値の数は? 3 ユニークカウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 61 ユニーク数を愚直に数えるには全ての値を持つ必要がある カーディナリティが高い場合にデータ量が大きくなる カウンター クライアント key1にvalue5を登録 value1 value4 +value5 key1にvalue4を登録 value1 value4 value5 既にあるので 何も行わない ユニークカウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 62 ユニーク数は HyperLogLog で効率的に表現できる HyperLogLogとは 集合のカーディナリティを推定できる確率的データ構造 データ量が小さく済む代わりに誤差が発生する ユニークカウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
様々な種類のカウンターの実装 63 Valkey の HyperLogLog 型を利用するだけで実装可能 ユニークカウンター -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 65 Valkey は同じキーの書き込みに対してはスケールできない 特定のキーへの書き込みが集中する場合 複数ノードでの負荷分散ができないため 単一ノードの性能以上はでない -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 66 異なる Key に分割して書き込んで 後からそれをマージできれば書き込みがスケールするはず key1をkey1:1とkey1:2に分割 -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 67 CRDT (Conflict-free Replicated Data Type)とは 「コンフリクトの生じないデータ型」 複数の場所で同じデータに対して更新が独立に行われても それらの変更をコンフリクトせずにマージ可能な型 これを活用することで結果整合性を持たせられる -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 68 加算のみ可能なカウンターは GCounter と呼ばれ 代表的なCRDTである -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 69 GCounterは加算しかしないので単調増加する ノード間で状態が異なる場合は最大値をとってマージ -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 70 データ構造を工夫すれば Valkey 上でGCounterを表現可能 Keyのハッシュ値でシャーディングするので Keyのサフィックスに 論理的なパーティションをつけて ノード間で分散させる -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 71 イベントは 1 つの論理パーティションにのみ書き込める -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 72 定期的に各パーティションの値をマージする 1. 全てのパーティションの値を取得する -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 73 定期的に各パーティションの値をマージする 2. 各パーティションについて 最大の値で上書きする -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 74 クライアントはどれかの論理パーティションからGETし 各カウンターの値を足し合わせれば最終的な値が得られる -
AbemaTV, Inc. All Rights Reserved AbemaTV, Inc. All Rights Reserved
さらなるスループットの向上 75 GCounterとしてキーを分割することで Valkey 単体性能を超えた性能を出すことができる! GCounterで学ぶ、CRDTによるスケーラブルな書き込み処理と結果整合性 | CyberAgent Developers Blog 以前ブログでも解説しているのでよかったら読んでください🙏