メルマガバナー運用の新システム移行 〜短期間かつ安全に〜

ogp

はじめに

こんにちは、MA部MA基盤ブロックの齋藤(@kyoppii13)です。

ZOZOTOWNではキャンペーンやセール情報などをメールマガジン(以下、メルマガ)で配信しています。そして、そのメルマガの最下部にバナーを掲載しています。従来のメルマガバナー運用方法は、スプレッドシートでバナー掲載スケジュールを管理し、DBに対して直接クエリを実行するという手作業による運用でした。この運用方法だと、人的なミスが発生しやすく、掲載されるバナーがイメージしづらいという問題がありました。そこで、バナー管理のためのCMSを開発し、既存配信システムへのデータ連携によって従来のバナー運用方法における問題点を解決しました。

メルマガバナー運用の移行は、急いでいたこと、開発メンバーが限られていることから開発工数を極力抑える必要がありました。そこで、本記事ではメルマガバナー運用の配信を限られた開発工数で、かつ安全に新システムへ移行するために取り組んだ事例を紹介します。

メール配信システムの概要

本章では、運用を移行するメール配信システムの概要を説明します。

メルマガバナーとは

ZOZOTOWNではキャンペーンやセール情報などをメルマガで配信しています。そして、そのメルマガの最下部には各種キャンペーンやセール情報のバナーを掲載しています。下図はバナーの一例です。

footer banner

なお、バナーデータはDBに保存されており、バナー画像のURL・遷移先URL・表示優先度・掲載開始の日時・掲載終了の日時が含まれます。バナーは1つのメールに複数掲載されるため、表示優先度が設定されています。また、バナーはキャンペーンによって掲載期間がそれぞれ異なります。そのため、バナーごとに掲載期間が設定されています。

メール配信システム

メルマガは下図に示す構成のシステムにより配信しています。

mail flow

配信の流れは以下の通りです。

  1. 配信対象者とメールで使用するデータを抽出
  2. 抽出したデータをメールテンプレートへ埋め込み
  3. ユーザへメール配信

メール配信ごとに上記の処理を実行します。

それぞれの処理を順に説明します。

1. 配信対象者とメールで使用するデータを抽出

mail flow step 1

はじめに、DBから配信対象ユーザとバナーデータを含むメールで使用するデータ抽出します。配信システムではメルマガ配信時にバナー掲載期間を確認し、配信時点で対象となるバナーデータを抽出します。メルマガは内容によって対象者が異なるため、同時に配信対象者の抽出も行います。

配信メールの種類は大きく分けてパーソナライズとマスの2種類です。そして、種類によって配信システムが別れています。パーソナライズは、お気に入りなどの情報に基づいて特定のユーザに対して配信するメールです。一方、マス配信は一定の条件に基づく複数のユーザに対して一斉に配信するメールです。

ここで抽出したデータはメール配信サービスへと送られます。

2. 抽出したデータをメールテンプレートへ埋め込み

mail flow step 2

メール配信にはSaaSのメール配信サービスを利用しています。このサービスでは、1. で抽出した配信対象者とメールデータをメールテンプレートに埋め込んで配信されます。メールテンプレートはテンプレートエンジンのようにHTMLとデータの埋め込み位置を定義することで作成します。なお、作成したメールテンプレートはメール配信サービスへ事前にアップロードしておきます。

3. ユーザへメルマガ配信

mail flow step 3

  1. で組み立てたメルマガを配信対象のユーザに送信します。

従来の運用フローと問題点

本章では、従来の運用フローと、そこで生じた問題点を説明します。

従来の運用フロー

メルマガバナーの内容は月ごとに決定します。そのため、従来のメルマガバナーの運用は下記のフローで行われています。

  1. 施策担当者が施策立案
  2. 掲載スケジュール決定後、スプレッドシートに1か月分のスケジュールを記載
  3. デザイナーがバナー画像を作成しアップロード
  4. バナー担当部署がバナーを配信システムのDBに直接登録

なお、上記の「バナー担当部署」とは、バナー掲載の調整を担当する部署を指します。

問題点

既存の運用方法では下記の問題点が存在していました。

  • バナー担当部署で工数が発生する
  • 直接DBを操作するため、人的なミスが発生し得る
  • スプレッドシート管理のため、実際に掲載されるバナーがイメージしづらい

既存の運用方法は、手動でのDB操作が必要でした。しかし、DB操作をできる人は限られているため、運用負荷が一部のメンバーに集中していました。また、手動運用のため人的なミスの発生がありました。他にも、バナー画像のURL・掲載順・遷移先URLをスプレッドシート管理していたため、実際に配信されるフォーマットと同じ見た目での事前確認ができませんでした。

また、この運用だと掲載期間などの調整もすべてバナー担当部署を介す必要があり、調整に時間がかかります。その結果、調整が間に合わずに適切なバナーを配信できないことになれば、ユーザへの価値提供の機会を失うことになります。

バナー管理システムの導入

前述の課題を解決するために、バナー管理システム(Mail Banner Manager。以下、MBM)というアプリケーションを作成しました。システムのアーキテクチャを下図に示します。

mbm architecture

MBMはバナー管理アプリケーションとデータ連携アプリケーションの2つで構成されています。バナー管理アプリケーションはCMSツールで、メルマガバナー登録・管理が可能です。そして、データ連携アプリケーションは登録したバナーを2つの配信システムのDB(SQL ServerとIIAS)へ連携します。

このアプリケーションの開発は、限られた工数で行う必要がありました。なぜならば、開発リソースに既存のバナー担当部署のメンバーをアサインすることが難しいからです。もし、既存の運用を新しいメンバーが担当すると、DBを直接操作することにより人的ミスの起きる可能性が高まります。また、限りある開発リソースでは、メインのアプリケーション開発者は1人のみの状況でした。

また、スプレッドシート運用であったことから、バナー管理アプリケーションに当たる部分はAppSheetのようなスプレッドシートをDBとするNoCodeツールの利用も検討しました。しかし、画面設計の自由度が不足している点などから要件を満たせないと判断し、採用は見送りました。

バナー管理アプリケーションの仕組み

application architecture

新しいアプリケーションは、ECS上でSPAとして動作しています。バックエンドはRuby on Rails、フロントエンドはVue.jsを採用しています。

また、ECS上でFargate環境を使っている理由は、サーバレスなサービスであることと冗長構成にするのが容易であるためです。ECSではDockerコンテナをタスクという単位で動作させることができます。

なお、Ruby on Rails + Vue.jsという組み合わせは、以前にアサインされた別の社内ツールの開発でも同じ技術スタックを採用していたためです。開発に慣れていること、機能としても似ている部分があったため、リソースを再利用できることが選定理由です。

MBMでバナーを配信設定するまでの流れは以下の通りです。

  1. バナー情報の登録
  2. バナーの配信設定

1. バナー情報の登録

バナーの基本情報を登録します。

具体的には、バナー画像、遷移先URL、タイトル、施策種別を入力し登録します。なお、登録時は画像のサイズ・拡張子、遷移先URLのフォーマットのバリデーションチェックをします。

下図がその画面です。

create banner page

また、登録済みバナーは下図のように一覧で確認できます。検索機能もあり、任意のクエリに一致するバナーを表示できます。

banners page

2. バナーの配信設定

  1. で登録したバナーの掲載期間と掲載順の設定をします。

下図は配信登録の画面です。この画面で登録済みのバナーと掲載期間、掲載順を設定します。

banner schedule

なお、日ごとの登録以外に、下図のように日をまたいだ期間指定による登録も可能です。

banner schedules

また、ドラッグ操作によるバナーの並び替えや編集もできます。下図がその画面です。

banner schedule

最終的に配信設定したバナーは、カレンダー表示や日次で確認できます。下図がその画面です。

banner schedules

MBMの導入により、バナー担当部署を介す必要なく、施策担当者が自身でバナー登録をできるようになりました。また、視覚的にもわかりやすくバナーを事前確認できるようになりました。

データ連携の仕組み

従来の運用方法でも、バナーデータを直接DBに登録するインタフェースが存在していました。その部分をシステム化し、開発工数を抑えつつも要件を満たすようにしました。

既存のインタフェースを利用するためには、DBを直接参照する必要があります。しかし、アプリケーションからは直接参照させずデータ連携部分から参照するように分離することで、障害となり得る部分を分けました。

データは、MBMで登録されたバナーをDBに保存し、その後、バッチ処理で配信システムのDBに連携される仕組みです。データ連携のアーキテクチャを下図に示します。

db batch architecture

データ連携は1分間隔のバッチ処理で実行されます。そのバッチ処理では、MBMにバナー登録・更新があるかを確認し、配信システムDBにデータを連携します。

データ連携では、以下のポイントを考慮し、安定した連携を実現しました。

  1. データ連携処理の分離
  2. 冪等性の担保

それぞれのポイントを順に説明します。

1. データ連携処理の分離

データ連携はアプリケーションから切り分けています。これにより、柔軟性と安定性、安全性が得られます。

データ連携を別アプリケーションとして切り出すことで、バナー管理アプリケーションが配信システムのDBを直接参照しなくて済みます。その結果、配信システムと疎結合になります。将来的にはバナーを含む様々なデータを管理するツールになることが見込まれています。このような改修が発生した場合に疎結合であることで、もう一方のシステムに与える影響がより少なくなり、改修しやすくなります。

2. 冪等性の担保

冪等性の担保はデータ連携アプリケーションの処理内で実現しています。

具体的には、DBごとにトランザクション内でDELETE INSERTをするようにしています。

以下に連携処理の擬似コードを示します。

MBM・SQL Server(パーソナライズ配信用システム)・IIAS(マス配信用システム)からn日分のデータ取得
MBM・SQL Server(パーソナライズ配信用システム)・IIAS(マス配信用システム)それぞれのデータ件数を取得
MBM・SQL Server(パーソナライズ配信用システム)・IIAS(マス配信用システム)それぞれの最終更新日を取得

// パーソナライズメールでの連携処理
if MBMとSQL Serverのデータを比較し、データ数が異なる OR MBMの方が最終更新日が新しい
  トランザクション開始
    SQL ServerのDELETE処理
    SQL ServerのINSERT処理
  トランザクション終了
  
// マスメールでの連携処理
if MBMとIIASのデータを比較し、データ数が異なる OR MBMの方が最終更新日が新しい
  トランザクション開始
    IIASのDELETE処理
    IIASのINSERT処理
  トランザクション終了

データ連携ではMBMと配信システムのデータを比較し、MBMのデータに更新があった場合に配信システム側のデータをDELETE、その後INSERTし直すことでデータを入れ替えています。これにより、連携元と連携先の対応関係や連携状態を保持する必要がなくなります。また、DELETE INSERTを採用することで、対応関係と連携状態を持たずとも更新日時とデータ件数の2つを比較することで、データ連携済みであるかの判断が可能となります。

DELETE INSERTが途中で失敗した場合はロールバックされます。連携されていない場合はDELETE INSERTで一定期間のデータを入れ替えるため、連携に失敗しても次回以降の連携で成功すれば問題ありません。「複数回のバッチ処理で最終的に連携されていれば良い」という結果整合性を担保することにより、開発工数も抑えることができました。

このような工夫により、データ連携アプリケーションで状態を管理する必要がなくなります。その結果、障害発生時に考慮すべき点が減ります。例えば、逆に連携時刻をデータ連携アプリケーションで保持する場合、連携処理はできたが連携時刻の更新のみができていない状況になってしまうと、次の連携でも不必要に連携処理が実施されてしまいます。

また、データ連携はデータの更新がない場合はスキップしています。DELETE INSERTで連携の度にデータをすべて入れ替えても連携はできます。しかし、毎回すべてを入れ替えると、Lambdaの実行時間によるコストが発生したり連携先DBに負荷を与えかねません。

安全に移行作業を進めるための手順

本章では、安全に新システムへ移行するために取り組んだことを紹介します。

リリース当日は以下の手順でリリースを実施しました。

  1. 配信が停止されていることの確認
  2. 既存のバナーデータをアプリケーションテーブルにインポート
  3. 連携対象となる既存の配信システムのテーブルをリネームによってバックアップ
  4. 連携対象テーブルと同じスキーマの空テーブルを本番用のテーブル名にリネーム
  5. データ連携処理の開始

各手順のポイントを紹介します。

各手順のポイントを紹介します。

1. 配信が停止されていることの確認

リアルタイムにメールが配信される時間帯は1日のうちで決まった時間帯のみです。指定した時間帯でのみ、リアルタイム配信によるメールが配信されます。MBMの導入に伴い、このリアルタイム配信用システムが参照するDBを変更するので、配信を停止する必要がありました。リリース当日は、このリアルタイム配信が停止していることを最初に確認し、以降の作業を実施しました。

2. 既存のバナーデータをアプリケーションテーブルにインポート

データ連携の処理はMBMから配信システムに向かって一方向です。そのため、MBMの導入前に配信システムで保存されていたバナーデータは、MBMのDBへインポートする必要があります。インポートしない場合、既に配信システムに登録されているバナーデータをMBMで参照できなくなります。

また、インポートせずともMBMから1つずつ手動でバナー登録できますが、配信システムには数年分のバナーが登録されているため、時間がかかります。

そこで、インポート用のスクリプトを作成し、自動でインポートできるようにしました。こうすることで、スムーズかつ安全な移行作業を実現できます。さらに、手作業による工程を減らすことは、リリースが失敗した場合に同じ手順で再度リリースをしやすくできます。

3. 連携対象となる既存の配信システムのテーブルをリネームによってバックアップ

MBMを導入すると、データ連携アプリケーションによって既存のテーブルに対しDELETEINSERTの処理が実行されます。つまり、リリース作業の失敗や、導入後のシステム障害や操作ミスによりデータを破損してしまう可能性があります。そこで、運用されていたテーブルをリネームし、事前にバックアップを取得しておきます。バックアップを取ることで、障害が発生した場合にも、この時点までロールバックできるようになります。

4. 連携対象テーブルと同じスキーマの空テーブルを本番用のテーブル名にリネーム

MBM導入以前に運用されていたテーブルと同じスキーマの空テーブルをリリース前に作成し、当日はリネームのみ実施しました。テーブルは作成後にスキーマが正しいか照合する作業が必要です。そのため、リリース前に空テーブルを作成しておくことで、このような確認作業を事前に終わらせることが可能です。その結果、リリース当日の作業を減らすことができます。

そして、上記の目的で事前に用意していたテーブルをリリース時に配信システムで利用されていたテーブル名にリネームします。MBMリリース後は、ここでリネームした空テーブルに対し、データ連携をします。

5. データ連携処理の開始

データ連携アプリケーションは、リリースの前日までにデプロイ済みです。なお、デプロイ時点では、連携処理は停止しています。そして、リリースのタイミングでこの停止していた連携処理を開始します。これにより、MBMで登録したインポート分を含むバナーデータが作成した空テーブルに対して連携されます。

リネームによってバックアップしたことで、仮にリリース後に障害が発生した場合でも、データ連携処理を停止して再度リネームし直せばロールバックが完了します。ロールバック手順を簡単にすることで、何かあった場合にもすぐにロールバック可能なので、余計な心配をせずにリリースできます。

MBM導入後の運用フロー

MBM導入により、メルマガへのバナー掲載フローが下図のように変わりました。

new mail flow

MBM導入により、バナー担当部署が実施していた掲載枠の調整や、DBへの登録作業を施策担当者が自身で実施できるようになりました。

MBMの導入効果

MBMにより、前述の以下の問題を解決できました。

  • バナー担当部署で工数が発生する
    • バナー担当部署を通さず施策担当者が登録できるようになったことで、バナー担当部署のコストが0になった
  • 直接DBを操作するため、人的なミスが発生し得る
    • MBMで登録したバナーはデータ連携によって既存の配信システムDBに連携されるため、直接のDB操作が不要になった
    • その結果、DB操作時の人的なミスがなくなった
  • スプレッドシート管理のため、実際に掲載されるバナーがイメージしづらい
    • MBMの導入により、施策担当者が自身でバナー登録や掲載状況の確認ができるようになった
    • バナー掲載の調整かかるコストが低減し、バナー掲載枠を効率的に使えるようになった
    • その結果、これによって利益の最大化が見込まれる

その他にも、データ連携アプリケーションを分離し冪等にできました。これにより、ネットワーク障害で連携処理ができなかった場合でも、次回以降の処理で成功すれば回復できる結果整合性を担保できました。リリース後、連携先DBで障害発生したことがありましたが、自動で復旧したため特別な対応は不要でした。

メール配信システムのインタフェースは変更していないため、仮にMBM起因の障害が発生しアプリケーション上からバナー登録ができなくなった場合でも、手動のクエリ実行によってバナー登録は可能です。

将来の展望

今回はメルマガバナーの手動運用の課題を、MBMというツールの新規開発・導入によって解決しました。将来の展望としては以下の施策を考えています。

バナー配信システム部分のマイクロサービスとしての切り分け

パーソナライズ配信用システムやマス配信用システムはメールバナー施策以外にも様々なチャネルへキャンペーンの配信を担うシステムです。そのため、モノリシックなシステムとなっています。今回のバナーデータ登録までをアプリケーションによって解決するという方法も、短期間の開発期間において既存の配信システムに手を加えることが困難であることから考えた手段です。将来的にはバナー配信システムをマイクロサービスとして再構築し、バナー配信機能のサービス化をして、柔軟なバナー管理をできるようにしていきます。

管理ツールの統一化

今回は開発納期が短期間であったことから、独立したアプリケーションを作成しました。しかし、このように問題解決の度に新規でアプリケーションを開発していくと、管理コストが増えてしまいます。ZOZOTOWNではメール以外にも様々なチャネルを利用してコンテンツを配信しています。現在、配信に関する管理ツールが複数あります。このような管理ツールを統一化することで、管理コストを下げていきます。

まとめ

従来のバナー運用フローを改善するために、管理ツールを開発・導入する取り組みを紹介しました。そこでは、限られた工数の中で安全な移行を実現するためのアーキテクチャや移行作業にも触れました。本記事が皆様の参考になりましたら幸いです。

さいごに

ZOZOでは一緒にプロダクトを開発してくれるエンジニアを募集しています。ご興味のある方は下記リンクからぜひご応募ください!

corp.zozo.com

カテゴリー