
はじめに
こんにちは。MA部MA開発ブロックの平井です。
ZOZOTOWNでは、プッシュ通知・LINE・メール・サイト内お知らせなどを通じてキャンペーン配信をしています。 MA部ではそれらの配信を担うマーケティングオートメーション(MA)システムの開発を担当しています。
私たちは現在、マーケティングプラットフォーム「ZOZO Marketing Platform(ZMP)」の開発を進めています。 そのプロジェクトの一環として、リアルタイムマーケティングシステムのリプレイスを実施しました。
ZMPの詳細については、以下のテックブログをご参照ください。
本記事では、リプレイス後の新システムの概要と、安全に本番リリースをするために実施した「シミュレーション試験」についてご紹介します。
目次
リアルタイムマーケティングシステムのリプレイスについて
リアルタイムマーケティングシステムとは
リアルタイムマーケティングシステムでは、ユーザの行動や商品情報等データの変更を検知し、ユーザへリアルタイムでアクションを行います。 例えばある商品の値段が下がったとき、その商品情報をリアルタイムに検知し、その商品をお気に入りしているユーザに対して配信します。
リプレイスの目的
リプレイスの目的は大きく2つありました。
- システム課題の解決
- キャンペーン運用管理コストの低減
システム課題の解決
既存のシステムでは、JBoss Data Grid(JDG)というインメモリな分散キャッシュデータストアを使用していました。 また、JavaアプリケーションとJDGを同一のJVMで動かす構成になっていました。
上記の構成はパフォーマンスを最大化するための構成でした。また、コスト制約や運用方針に起因する以下のような課題が存在していました。
- スケーラビリティが低い
- ミドルウェアの制約でスケーラビリティに制限がある。
- システムメンテナンス性が低い
- リリース時にキャッシュの再ロードのためにメンテナンス作業が必要。
- システム耐障害性が低い
- キャッシュが壊れた際のメンテナンス対応に時間がかかる。また、JDGの情報がインターネット上に少なく、障害対応等が行いづらい。
- 開発コストが高い
- 知見の少ないフレームワークのため機能改修に時間がかかる。
既存システムで利用されていた技術や課題の詳細については以下テックブログを参照ください。
キャンペーン運用管理コストの低減
既存のシステムでは、キャンペーン周期などキャンペーンに関わるルールをExcelファイルで管理していました。 マーケターがキャンペーンのルールを変更したい場合は、エンジニアがExcelファイルを修正してリリース作業を行う必要があり、運用しづらい状況でした。 そこで、管理画面からキャンペーンを管理できるようにして、マーケターが運用できるようにする必要がありました。
リプレイス前のアーキテクチャ

リプレイス前はEC2上にモノリスな形でJavaアプリケーションが構築されていました。
リプレイス後のアーキテクチャ
上記課題を解決するリプレイス後のアーキテクチャは以下のとおりです。

既存システムはAWS上に構築されていましたが、新システムは他システムとの連携などを考慮してGoogle Cloud上に構築されています。 モジュール毎にアプリケーションが分かれていて各モジュールはPub/Sub経由で連携することで、スケーラビリティを実現しています。
各モジュールの説明
データ基盤連携がトリガーとなり、トリガー判定、セグメント抽出、最適化、配信処理という処理の順番で配信処理が動作します。
管理画面API
このAPIはマーケターが利用する管理画面からリクエストされます。キャンペーン情報がAPIを通じてデータベースに登録され、管理画面上でマーケター自身によって運用・管理できるようになりました。
アクセスログ集計
ユーザーのZOZOTOWNへのアクセスログを集計しています。そのデータは後続のセグメント抽出などで利用されます。
データ基盤連携
ZOZOTOWNの商品情報、在庫情報などを連携しています。ここでの在庫、価格更新がトリガーとなり後続の処理が動きます。
トリガー判定
ZOZOTOWN側でのデータ更新が各キャンペーンで定義されている条件に当てはまるかを判定しています。条件に当てはまった場合は後続の処理に続きます。
セグメント抽出
トリガー判定された情報を元に対象の会員を抽出します。キャンペーン毎に対象のセグメント情報が設定されています。
最適化
最後に、ユーザーにとってより良い訴求になるように時間帯やチャネルの最適化を行います。ここまでがリアルタイムマーケティングシステムの責務です。
配信ワークフロー基盤、配信基盤
最適化で生成された配信情報を元に、配信処理を行います。
メール配信を担当するメール配信基盤については以下テックブログを参照ください。
技術選定
アプリケーションインフラ
以下の理由からCloud Runをアプリケーションインフラに利用しています。
- 部内で利用実績がある。
- スケーラビリティが高いため。
データベース
以下の理由からAlloyDBをデータベースとして利用しています。
- 大規模テーブルに対するリアルタイム分析(OLAP)と在庫・価格変動の即時トラッキング(OLTP)を同時に行う、HTAP(ハイブリッド・トランザクション/アナリティカル・プロセッシング)を実現するため。
- 読み取りプールを構成でき、用途にあったインスタンスを構築できる。
- 既存システムでPostgreSQLを利用している部分があり、同じインタフェースを持っている。
言語
以下の理由からGoをアプリケーションの実装に利用しています。
- 全社的に推奨されている言語の中で、部内での利用実績がある。
- パフォーマンスが良く、高負荷システムに向いている。
シミュレーション試験について
実施背景
上記のシステムアーキテクチャで一通り開発が完了し、システムの信頼性やパフォーマンスが担保できているかを検証するために障害試験や各モジュールの負荷試験を行いました。 ただ、システム負荷や生成される配信情報はキャンペーン設定、実際の商品在庫データの変動に依存する部分が多く、より安定したリリースを実現するためには本番相当の設定での検証が必要でした。
そこで、本番相当の環境を構築し実際のZOZOTOWNの基盤データを連携することでより本番に近い形で検証するシミュレーション試験を実施しました。
実施するための準備
シミュレーション試験を実施するために以下を準備しました。
- 本番環境のアクセスログ、データ基盤連携Pub/Subトピックに、試験用のサブスクリプションを追加する。
- 本番同様のキャンペーンを設定する。
- テスト環境に本番相当スペックのインフラを構築する。
データ基盤連携システムは、ZOZOTOWN本体におけるデータベースの差分更新を検知し、その差分データをPub/Subメッセージとしてパブリッシュしています。
リアルタイムマーケティングシステムは、データ基盤連携がトリガーとなり後続の配信処理が動くため、データ基盤システムのPub/Subメッセージをサブスクライブすることで実際の配信処理を再現できます。
インフラに関しては、当初予想された本番環境で必要なスペックのリソースを構築しました。実際に処理を動かしていく中でスペックを調整しました。 リリース時はシミュレーション試験を行なっていた環境に構築されたインフラと同じスペックのものを本番環境に構築しました。
検証項目
シミュレーション試験では以下の項目を検証しました。システムパフォーマンス的な観点に加え、システムが意図した挙動をしているかという点で配信予定数も確認しました。
- 各種キャンペーンの配信予定数などが予測値と乖離がないこと。
- システム全体が負荷に耐えられていること。
- SLAを満たしていること。
- 致命的なバグが発生しないこと。
試験を実施した結果
本番に近い環境で以上の検証項目を確認する中で、実際の運用に役立つ多くの気づきを得ることができました。以下はその中でも特に重要だったポイントです。
データベース負荷トレンドの把握
午前中のキャンペーン配信が集中する時間帯に、システム負荷が高くなる傾向は当初から予測していました。本番相当の環境下での検証により、その傾向が確実なものとして裏付けられました。
以下の画像はデータベースのCPU使用率のグラフですが、特定の時間帯の負荷が高いことを確認できます。

この明確なトレンドをもとに、アイドル時間帯(負荷が低い時間帯)にはAlloyDBの一部読み取りインスタンスを自動で停止する運用を導入しました。これにより、不要なリソースの稼働を抑え、柔軟なリソース管理とコスト削減を実現しています。
特にAlloyDBの柔軟なインスタンス管理機能を活用することで、パフォーマンスを維持しながらも、無駄のない運用が可能となり、クラウドコストの最適化に大きく貢献しました。
BigQueryコストの把握
検証中に、BigQueryの利用コストが予想以上に高いことが判明しました。
特に、アーキテクチャ図の「配信ワークフロー」部分からわかるように、ワークフロー内で参照しているBigQueryのクエリがコストの主因となっていました。
幸いにも、既に運用としてクエリにクエリラベルを付与する仕組みが整備されていたため、これを活用して分析を実施しました。 クエリラベルの情報をもとにクエリごとのスキャン量を可視化することで、特にスキャン量が多くコストに影響しているクエリを特定し改善できました。
監視設定の精度向上
本番相当の負荷をかけることで、より本番運用を考慮した監視アラートの閾値を特定できました。 また、監視が不足しているケースが明らかになりました。 これを受けて、閾値を調整し、より実運用に即した監視体制を構築しました。
データマートのチューニングによるキャンペーン精度の向上
シミュレーション試験を通じて、実際の配信予定数を事前に確認できました。試験結果をもとに、ユーザーごとに最適なキャンペーン訴求が行えるよう、データマート生成ロジックなどのチューニングを実施しました。 この取り組みにより、配信精度の向上と無駄な配信の削減が実現し、より効果的なキャンペーン運用につながりました。
バグの事前発見
開発環境では再現できなかった以下のような本番特有のバグも、本番環境を再現することで発見できました。
- BQクエリにおけるUPDATE、DELETE、MERGE DML同時実行上限の超過
- 該当クエリはMERGE句を利用していましたが、上記DMLステートメントと競合しないWRITE_APPEND方式に変更した。
また、リアルタイムマーケティングシステムと連携する配信システム側でも修正すべき点が見つかり、 本番リリース前にクリティカルな問題を事前に対処できました。
リプレイスの結果
本番相当のシミュレーション試験を事前に実施したことで、大きな問題なくリリースを迎えることができました。
リプレイスした結果、前述した課題は以下のように解決できました。
- システム課題
- スケーラビリティ
- メインアプリケーションをCloud Run上に構築したことで、負荷に応じて自動でスケーリングされるようになり、ピーク時でも安定した配信が可能になった。
- システムメンテナンス性
- リリース作業時のメンテナンスが不要になった。
- システム耐障害性
- フルマネージドなクラウドサービスを利用しているため障害対応が容易になった。また、AlloyDBのリージョンインスタンスタイプを利用していて高可用性を担保できた。
- 開発コスト
- 部内で知見のあるGoを採用したことで、機能改修がスムーズに行えるようになった。
- スケーラビリティ
- キャンペーン運用管理コスト
- キャンペーンの情報をデータベースで管理するようにしたため、既存の管理画面からマーケター自身で運用可能になり、運用負荷が軽減された。
また、アーキテクチャの見直しと使用技術の刷新から、配信処理にかかる時間も大きく改善されました。
以下は、とあるキャンペーンの時間毎の配信数のグラフです。縦軸が配信数で横軸が時間、赤線がリプレイス前で青線がリプレイス後です。 グラフからわかる通りリプレイス後の方が短時間で全ての配信を処理できていて、ユーザーに対するより素早い訴求が可能となりました。

まとめ
今回のリアルタイムマーケティングシステムのリプレイスでは、技術的な刷新だけでなく、運用面・パフォーマンス面でも大きな改善を実現できました。
また、リリース前にシミュレーション試験を実施したことで安全にリリースできました。
ZOZOでは、一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。