GMO SSPのCloud(Google Cloud Platform)移行の失敗と成功のまとめ


この記事はGMOアドマーケティング Advent Calendar 202219日目の記事です。

こんにちはGMOアドマーケティングのy.yです。
今回は2022/12/06, 07に開催されたGMO Developers Dayで発表をした
「GMO SSP」のクラウド移行(GCP)、失敗と成功をまとめてみた!』の内容になります。
時間の関係上で発表できなかった内容も少しだけ追加しています。





SSPというのは広告をリアルタイムにWebコンテンツに配信するシステムです。
接続しているDSPやアドネットワークの広告の中で、一番単価が高く
ユーザーにマッチした広告をリアルタイムに配信します。


GMOSSPというのはGMOアドマーケティングにて提供している
インターネット広告を配信するSSPプロダクトです。

GMOSSPは自社運営にてコンテンツ集客に特化した
広告配信DSPの「ReeMo」と国内最大級の広告在庫を保有する「AkaNe」を中心に、
複数のDSP・アドネットワーク事業者の広告を組合せる事で
メディア様のインプレッション価値の最大化をサポートしています。

GMOSSPの特徴としては、複数枠の一括表示が可能ですでに多数の媒体社様での導入実績があります。


GCPはGoogleが提供しているクラウドコンピューティングサービスで、
Google検索やYouTube、GmailなどのGoogleの様々なサービスがGCPで稼働しています。


GMOSSPがGCPに移行することになった理由としては、移行前の環境では
オートスケールやオートヒーリングの対応ができなかった為です。

マネージドサービスを利用してのインフラ運用工数削減、
GCPを利用している自社プロダクトとの通信で発生する
ネットワーク費用の削減やレイテンシの向上が理由となります。


広告配信はユーザーがWebサイトを表示し、広告リクエストを受け、表示までのわずかな時間(数10ms)で
最適な広告を選択し配信する役割で高トラフィックなシステムです。

アクセスログはSSPの収益に直結するため損失することは禁物となっています。


・管理画面
広告配信を行うにあたりさまざまな設定や広告収益を確認する各種レポートの確認ができます。

・バッチ
広告配信のアクセスログ集計や広告配信状況の通知など広告配信に関する定期実行処理を行っています。

・API
GMOSSP内部で使用するGMOSSP関連のサービスから呼び出されるAPIとなっています。


GMOSSPをGCPへ移行するための方針

案1はリスクを抑えるため、時間をかけ現状のシステム構成のままGCPに移行するシフトから、
システムをクラウドへ最適化しリフトでの移行を考えました。

案2はリスクはあるが移行時間を抑えるため、初めからクラウドへ最適化しての移行を考えました。


要望として下記のようなものがありました。

・クラウド環境に移行するにあたりインフラ運用工数削減と
 開発に集中したいためマネージドサービスを使いたい。

・コンテナを利用できる別のコンピューティングサービスや、
 GCP以外のクラウドへの移行を容易にするためコンテナを採用したい。

・ランタイム、ミドルウェア、コンテナ管理、OS、仮想マシン、ハードウェア等の運用を可能な限り、
 GCPに任せて開発に集中したい。

・移行前のコストと同等レベルに抑えたい。

・期日を守り移行前の環境から撤退しGCPに移行したい。


要件を踏まえてシフトだけ先に行い、決められた期間内に旧環境から撤退し
GCPに移行する方法もありましたが、マネージドサービスへ早期に移行し
開発に集中したかったため、リフトアンドシフトでの移行はしないで
クラウドに最適化し移行する方針となりました。


移行先に使用するマネージドサービスは複数ありますが
そもそもマネージドサービスとは運用管理の改善と経費削減のため、
プロセスや機能の維持と需要予測の責任をアウトソーシングする手法です。


移行するためにどういった技術を使うか、必要な要件を考えたところ上記の選定基準となりました。


各GMOSSPのコンポーネントで選定基準を考えた結果上記のようになりました。


Compute EngineというのはCPUのコア数、メモリ数を柔軟に選定でき
ライブマイグレーションが標準装備されています。

Compute Engineはマネージドサービスではないので、
何かしらの要因でマネージドサービスに移行できなかった時だけ使用することにし、
基本的には使用しない方針としました。

ライブマイグレーションとはサーバを止めずに、別のサーバにデータを移行する技術で
ダウンタイムなしにメンテナンスができるものです。


Kubernetes Engineはコンテナ管理ツールのデファクトスタンダードで、
コンテナの配置、コンテナ間通信、複数コンテナへアプリケーションのdeployを
自動化してくれたり、複数コンテナを管理してくれ
てマイクロサービスを運用するのに非常に相性のよいものとなっています。

GMOSSP視点ではマイクロサービス化しやすく、外部サービスなどでサイドカーコンテナが必要になった時に、
第一選択となりますが運用面で手間がかかりそうでした。


Cloud Runはサーバーレスのコンテナ環境を提供する、
スケール可能なフルマネージドサービスとなっていて開発に集中できます。

Cloud Runの課金についてはリクエストが処理されている時のみCPUが割り当てられるリクエストベースと、
インスタンスの全期間に対してCPUが常に割り当てられるインスタンスベースというものがあり
リクエストベースは、リクエストが処理されている時のみCPUが割り当てられて、
リクエストベースで課金されるものになります。

インスタンスベースは、インスタンスの全期間に対して課金されCPUも常に割り当てられるものとなっており、
サービスの用途にあった課金制を選ぶことができ
用途としてはWebサイト、API、データを処理するアプリケーションだったりWebhookなどに向いています。

GMOSSP視点では、瞬間的にリクエスト数が増加する広告配信で、
インスタンスの起動時間が早くてフルマネージドな点が向いています。

サイドカーコンテナを使用する場合には向いていません。


App Engineはインフラ管理不要でアプリケーション開発に集中できるフルマネージドサービスです。
App Engineの環境にはフレキシブルとスタンダードというものがあり
フレキシブル環境ではインスタンスの起動時が遅いですがコンテナを利用できます。

スタンダード環境では瞬時にインスタンスが立ち上がりますがコンテナを利用できません。
App Engineの用途としてはWebアプリケーションやモバイルアプリのバックエンドなどに向いています。

GMOSSP視点では、瞬間的にリクエスト数が増加する広告配信で
インスタンスの起動時間が遅いため、あまり向いていません。


検討した結果Cloud Runを選定しました。


結果として要件要望を満たしているCloud Runが全てのコンポーネントで最適でした。


広告配信の選定理由
コンテナを利用できるApp Engineのフレキシブルは、インスタンスの起動時間が遅いため
広告配信の急激なトラフィック増しには相性がよくないため、選択しませんでした。
GKEに関してはpodの管理などあり、開発のみに集中できないのとチーム内ではkubernetesの運用経験がなく、
サイドカーコンテナも使う必要が直近でなかったため選択しませんでした。

管理画面の選定理由
送信元IPを固定して、外部サービスへアクセスする必要があったため、
送信元IPを固定できないApp Engineは候補として除外しました。
GKEは広告配信と同じ理由で選択しませんでした。


バッチの選定理由
管理画面と同様Cloud Runは1時間以内に処理を終わらせないと、タイムアウトで強制終了となってしまいますが
GMO SSPで長時間動くバッチはないので問題ありませんでした。


APIの選定理由
APIは必須条件がそこまで厳しくなかったので、
その他コンポーネントと統一する形でCloud Runを選定しました。


移行前の構成図
GMOSSPの各コンポーネントがDBに接続しバッチでログ集計と、
広告のクリエティブ画像を解析するシンプルな構成となっています。
枠で囲んだ部分で、ログ集計や画像の解析をしていて、その部分だけGCPをもともと利用していました。
画像の解析にはVisonAPIを使用していて、広告の自動審査をしています。


初めに、DBを移行しました。
旧環境のMariaDB Galera ClusterとGCPに新たに立てるMariaDBのインスタンスで
MasterMaste構成で移行することにしました。
この時点ではまだ、CloudSQLには移行していません。


API、バッチ、管理画面の移行はCloud Runで構築、HTTPS LoadBarancerを設定し
それぞれ順次移行し、旧環境から撤退しました。


広告配信用のCloud Runを構築して旧環境の広告配信サーバを撤退しました。
トラフィック量が非常に多いので移行時のリスクを考慮し、
旧環境から広告配信のCloud Runに数%ずつトラフィックを切り替え様子を見ながら移行しました。


最後のフェーズ
GCEに構築されたMariaDBのデータをCloudSQLにデータ移行しDBを切り替えました。


広告配信、管理画面、API、バッチはCloud Runに移行し、
枠でかこった部分はDBの負荷を抑えるためにMemorystoreの導入をしました。
もう一点は旧環境のバッチで広告配信のログ集計を行っていたものをクラウドネイティブ化したものとなります。


ログ集計まわりについて広告配信のアクセスログは、SSPの収益に直結するため、損失してはダメなものになります。

移行前の環境では、アクセスログをバッチでparseしBigQueryにLoadしていましたが、
移行後はLoggingからGCSにログシンクし、GCSにログが置かれたことをトリガーに
DataflowをキックしBigQueryにログをロードする構成となりました。


広告配信で発生したものとなりますがConnection refusedや、Connection timed outが大量に発生してしまい
Cloud Runのインスタンスが上限の1000程度急に立ち上がってしまいました。

考えられる原因としては、状況的にサーバーレスVPCコネクタへの接続数に上限がありそうな動きをしていて、
Googleのサポートの方に協力してもらい対策をしました。

対策内容としてCloudSQLインスタンスのスペックアップ、PHPからDBに接続する際の
持続的データベース接続の導入、DBへの負荷を下げるためMemorystoreの導入、
Cloud Runへの同時接続数、Apacheスレッド数などの調整を行いました。

以上の対策を行ったことにより、移行当初に発生していたDBエラーを改善することができました。


広告配信で通信エラー
原因としてGMOSSPと社内の別広告サービスが移行前までは、同一ネットワーク環境で動いていて、
内部通信で完結していましたがGMOSSPがGCPに移行したことによりインターネットから、
別広告サービスのLBを経由し接続するようになったため、レイテンシが遅くなってしまったのが原因でした。

解決策としてはLBを経由しないで、社内の別広告サービスにCloudDNSを
内部DNSとして使用し別ルートで接続するようにしました。


Cloud Runが無限ループ
原因としては、Cloud Runのバッチの中に無限ループになってしまうバグがありました。
オンプレではプロセスをkillして無限ループを強制的に止めることができましたが、
Cloud Runでの無限ループを止める方法としては3つありました。

1つ目
Cloud Runで使用しているサービスアカウントに対してBigQueryの実行権限をIAMから削除

2つ目
Cloud Runのサービス自体を削除

3つ目
Cloud Runへのリクエストから1時間経過するのを待ってタイムアウトするまで待つ

サービスアカウントの権限変更とサービスの削除は、影響範囲的にやりたくなかったので
タイムアウトするまで待ちました。

今回、無限ループの中でBigQueryへのリクエストが実行されてしまいましたが
同じクエリが実行されていて、キャッシュが効いていたので
費用がめちゃくちゃかかったということはありませんでした。


広告配信で使用するファイルをCDN経由でGCSから取得して
コスト削減しようと思い、対応しましたがGCSの費用が増加してしまいました。

GCSのgetオペレーションが、急激に増えてしまったのが原因でした。

対策としては、CDNの設定に不手際があったため設定を見直して対応しました。


Cloud Runからの配信だとリソース使用量でコストがかかってしまうため改善策として、
AkamaiのDataStreamというサービスを使用して、ビーコンのCloud Storageへの転送を考え実装しましたが

DataStreamでは、60秒毎に転送される仕様とのことを事前に確認していたが
実際には複数のエッジサーバーから転送されるため、秒単位でファイルが転送されたり、
数日単位の遅れで転送されたり、ということが多発し、ビーコンとしての要件が満たせなかったので
最終的にGCPにおける大規模なログをBigQueryに流し込むのに最適な、Dataflowを使うことになりました。


Cloud Runのネットワークコストが高額になってしまいました。

原因としては移行前のネットワークコストは一定量が定額でしたが
Cloud Runでは、リソース使用量のCPU、メモリ、ネットワークなど単価が高く
利用量によって、都度課金されてしまうため高額になってしまいました。

解決策として売上貢献が少ない外部サービスへのリクエストを停止
停止することによりなぜコストが下がるのかというと、
SSPというサービスの特性上、外部サービスへ大量のリクエストを行っているので
GCP環境では、ネットワークコストが多くかかってしまった為です。

リクエスト停止したことと、Cloud RunのCPUの割り当て方法をリクエストベースから、
インスタンスベースに変更したことによりCPUのコストも下げることができました。

もう一点は、広告配信に関わる静的ファイルをCloud Runから配信していて、
コストがかかるようになってしまいましたが、
GCSに静的ファイルを置きCloud CDNを利用するようにしたことで
ネットワークコストを削減することができました。


コスト削減のイメージ
売上の低い外部サービスへのリクエストを停止し、対応前後のコストを比較したところ
約80%くらいの削減となりました。


現在残っている移行後の課題としては特定の時間帯ではないですが、
広告配信で急にレイテンシが遅くなったり

トラフィックが急激に上がるわけでもないのにインスタンス数が急激に増加したりすることがあり
広告配信の処理速度によって、CPUやメモリのコストが大きく変わってくるので、
今まで以上にパフォーマンスを考慮しての開発が現在の課題となっています。


今後に関しては広告配信でサイドカーを使った開発があるかもしれないので、
GKEに移行するかもしれないということと、まだ具体的には考えられていませんが
SpotVMを利用してコスト削減とセキュリティ面をより強化していきたいです。


GCPに移行してよかったこととしては下記になります。

・マネージドサービスに移行したことにより運用コストが削減できたこと
・全てではないですがLAMP環境がクラウドネイティブ化されたことによりモダンな環境になったこと
・旧環境では状況によってインスタンスを都度追加していましたが、
 Cloud Runに移行したことによってオートスケールされるようになり運用面で楽になったこと
・ロギングでログが集約されて確認が楽になったこと


移行して大量にエラー発生してしまったことや、想定していたコストより
だいぶ上がってしまったことなど反省点はたくさんありますが、
マネージドサービスに移行したことによりインフラ運用工数削減やオートスケール、
Loggingでログが集約され運用面でだいぶ楽になり開発に集中できるようになりました。

年初からの円安によるコスト増しは想定外でしたが、コスト面や運用面で改善できる余地はたくさんあるので
引き続き対策を考え、より安定した環境に整えていきたいと考えています。





明日は@mSpringさんによる「SHAPで自然言語処理モデルネガポジ判定の中身を覗いてみる」です。
引き続き、GMOアドマーケティング Advent Calendar 2022 をお楽しみください!
■学生インターン募集中!
https://note.gmo-ap.jp/n/nc42c8a60afaf
■エンジニア採用ページはこちら!
https://note.gmo-ap.jp/n/n02cbeb6edb0d
■GMOアドパートナーズ 公式noteはこちら!
https://note.gmo-ap.jp/