本記事は、当社オウンドメディア「Doors」に移転しました。
約5秒後に自動的にリダイレクトします。
こんにちは。マーケティングプラットフォーム本部 開発部の井上です。
ブレインパッドは、デジタルマーケティングの分野に力を入れて取り組んでおり、私が所属する開発部では、Webマーケティングの施策やインターネット広告の運用を支援するWebサービスを開発しています。
当社は、Webサービスのシステム基盤を構築するためにクラウドサービスを積極的に活用しており、Amazon Web Services(AWS)をはじめとして、最近では Google Cloud Platform ( GCP )も利用しています。
そこで、今回は Google App Engine ( GAE )や Google BigQuery といった GCP のマネージド・サービスを活用し、Webサービスの開発について、紹介したいと思います。
<目次>
- ■ GCP への移行
- ■ 新たな広告サービス基盤を構築
- ■ GAE と GCS を利用したデータ取得と公開の仕組み
- ■ Cloud PubSub と App Engine Cron Service を利用した分散バッチ環境の構築
- ■ BigQuery を利用したレポーティング環境の構築
- ■ まとめ
■ GCP への移行
私は、当社が提供・開発する運用型広告最適化ツール「L2Mixer」のシステム基盤をオンプレミス環境から GCP へ移行したことがきっかけで、 GCP を利用するようになりました。
L2Mixerの GCP への移行にあたっては、システム構成を極力変えない方針で移行したため、 GCP のIaaSである Google Compute Engine ( GCE )の利用が中心となっています。
GCE はライブマイグレーションにより、ホストメンテナンス時にはVMインスタンスを実行したまま別の物理ホストへの移動が行われるため、メンテナンスによるVMインスタンスの停止が発生しないことや仮想CPUやメモリをカスタマイズできるなど、非常に柔軟で高性能な仮想マシンです。一方、ミドルウェアのインストールやセキュリティアップデートなどは自分たちで行う必要があります。
そのため、現在、 GCP のマネージド・サービスを活用し、クラウドに即したアーキテクチャへの変更に取り組んでいます。
■ 新たな広告サービス基盤を構築
広告サービスの開発には、 Google やYahoo!、Facebookといった広告プラットフォームとのAPI連携、広告データ(テキスト、画像、動画)やレポートデータ(広告のインプレッションやクリック、コンバージョンなどの実績)といった大規模なデータを取り扱うことがあります。
当社では Google AdWords やYahoo!スポンサードサーチ、Yahoo!ディスプレイアドネットワーク(YDN)といったインターネット広告の運用を支援するサービスとして、L2Mixerを開発・運用してきた長年の実績があり、これまでに培ってきた開発や運用のノウハウを活かした、新たな広告サービス基盤の構築にも取り組んでいます。
当社の広告サービス基盤の構築には、 GCP のマネージド・サービスを活用しており、主に以下のサービスを利用しています。
- Google App Engine ( GAE )
- Cloud SQL
- Google Cloud Storage ( GCS )
- Google BigQuery
- Google Cloud Pub/Sub
これらをどのように利用しているかを解説していこうと思います。
■ GAE と GCS を利用したデータ取得と公開の仕組み
当社の広告サービス基盤では、広告プラットフォームから取得した広告データやレポートデータを Cloud SQL や GCS に保存しています。これらのデータを外部のWebサービスから利用できるようにするために、REST APIをGAE/Pyで開発しています。
大まかな仕組みは、
- 広告プラットフォームから広告データやレポートデータを取得してDBとストレージに保存するバッチ処理を、 GCE 上で実行。
- 広告データのうち、画像や動画といったバイナリデータは GCS に保存。
- 外部のWebサービス向けに、広告データを取得するためのREST APIをGAE 上に構築。
- 画像や動画データは、公開URLを GCS に設定し、URLにアクセスして画像や動画データを取得。
となります。
GAE を使う利点は、
- Google によるフルマネージドサービスであり、インフラストラクチャに関わる作業はすべて Google に任せられること。
- サービスのデプロイやバージョン管理が簡単であること。
- オートスケーリングの機能によりリクエスト数に応じてインスタンスの増減を自動的にさせること。
といった点です。
セキュリティ対策のため、Webサービスの常時SSL化が当たり前となりつつある中で、最近、 GAE ではマネージドなSSLを無料で利用できるようになったことも利点です。
広告サービス基盤の開発では、CircleCIを使ってテストやビルド、デプロイのプロセスを自動化していますが、 GAE へのデプロイは gcloud コマンド一発で済むため、デプロイの設定もシンプルに書けます。
また、 GAE はPythonやGoなどさまざまな開発言語をサポートしていますが、個人的には、最近 Standard Environment でJava8が正式サポートされたことがトピックです。
広告サービス基盤には、広告データやレポートデータの取得といったバッチ処理をJava8で実装しており、バッチ処理は GCE 上で実行しているため、バッチ処理の実行環境として GAE の利用も考えています。
■ Cloud PubSub と App Engine Cron Service を利用した分散バッチ環境の構築
当社の広告サービス基盤では、広告データやレポートデータの取得といった時間がかかる処理は、バッチ処理で実行しています。
バッチ処理は、確実なスケジューリングと、ジョブの件数が増加してもスケールすることが重要ですが、これらを満たす環境を自分たちですべて構築するのは、大変な作業です。
広告サービス基盤では、 GCP が提供するマネージド・サービスを利用して、バッチ処理のスケジューリングと分散実行の環境を構築しています。
- App Engine Cron Service
- Google Cloud Pub/Sub
GAE には、ジョブ実行の要求メッセージを Pub/Sub へパブリッシュするためのアプリケーションをデプロイし、 App Engine Cron Service を利用して定期的に実行します。
一方でバックエンドには、ジョブ実行の要求メッセージを Pub/Sub からサブスクライブし、ジョブを実行するアプリケーションをデプロイします。
App Engine Cron Service により実行されるアプリケーションと、ジョブを実行するアプリケーションは Pub/Sub によって分離されているため、例えば、メンテナンスなどでバックエンドのアプリケーションが停止している最中に、要求メッセージがパブリッシュされたとしても、要求メッセージは Pub/Sub にキューイングされます。バックエンドのアプリケーションを再開すればジョブは実行される仕組みとなっています。
また、バックエンドのインスタンスを増やすことにより、より多くのジョブを実行させることも可能です。
GCP にはVMインスタンスをグループ化してオートスケーリングさせる機能も備わっているため、オートスケーリング機能を利用して、ジョブの件数に応じてインスタンスを増減させる仕組みも考えています。
■ BigQuery を利用したレポーティング環境の構築
インターネット広告を運用しているユーザー(広告主や広告代理店)にとって、広告プラットフォームから提供されるレポートデータを解析することは、重要な業務の一つです。
広告プラットフォームから提供されるレポートの種類は多岐にわたり、大規模な広告主や大手広告代理店が扱うレポートデータは、数十億行、数TBオーダーのデータとなることもあります。
GCP には、これらの大量データを解析するための基盤として Google BigQuery が提供されており、当社の広告サービス基盤でも BigQuery を活用しています。
インターネット広告のレポートデータは日別や時間別といった軸で取得することができるため、 BigQuery の日付分割テーブルを利用して、レポートデータを保存しています。
広告のレポートは一定期間で集計することが多いため、日付分割テーブルにレポートデータを保存しておくことにより、クエリの対象範囲を特定のパーティションに限定することができます。
日付分割テーブルを作成すると、_PARTITIONTIME という疑似列が暗黙的に作成されるため、_PARTITIONTIME 疑似列を使用して、クエリの実行中にスキャンされるパーティションの数を制限することができます。
クエリサンプル
SELECT
report_date,
SUM(impressions) AS impressions,
SUM(clicks) AS clicks,
SUM(conversions) AS conversions,
SUM(cost)
FROM
mydataset.reports
WHERE
_PARTITIONTIME BETWEEN TIMESTAMP('2017-10-01')
AND TIMESTAMP('2017-10-31')
GROUP BY
report_date
ORDER GY
report_date
;
BigQuery の日付分割テーブルにデータをロードする方法には、
- ストリーミングインサートを使って、データを行単位でインサート。
- ローカルまたは Google Cloud Storage 上に保存されたデータ(CSVやJSONといったフォーマット)を、ジョブで読み込む。
といった方法がありますが、当社の広告サービス基盤ではジョブでレポートデータをロードしています。
大まかな仕組みは
- 広告プラットフォームから取得したレポートデータを、日単位で GCS に保存。
- GCS に保存したレポートデータを外部データソースとして、 BigQuery に外部テーブルを作成。
- クエリを利用して、外部テーブルから日付分割テーブルのパーティションにレポートデータを読み込む。
となります。
外部テーブルの作成例
bq mk --external_table_definition=reportsSchema.json@CSV=gs://mybucket/reports/20171001.csv.gz mydataset.external_reports_20171001
外部テーブルから日付分割テーブルにデータをロードするクエリ
bq query --allow_large_results --replace --noflatten_results --destination_table='mydataset.reports$20171001' "SELECT * FROM mydataset.external_reports_20171001"
BigQuery にデータをロードする方法は、クエリ以外には読み込みジョブやコピージョブを利用する方法もあります。
読み込みジョブやコピージョブは、データロードにかかる料金が無料で、クエリを利用するよりも簡単にデータをロードできますが、1日の実行回数に制限があります。(読み込みジョブは50,000回/日、コピージョブは10,000回/日)
当社の広告サービス基盤では、複数の広告主や広告代理店のアカウントを扱うため、アカウントの単位でデータセットとテーブルを分けています。そのため、アカウント数が数千の単位になると、読み込みジョブやコピージョブを利用した方法では、1日の実行回数に引っかかってしまうという懸念がありました。
クエリを利用した方法の場合には、1日の実行回数に制限がないため、広告サービス基盤では、外部テーブルとクエリを利用した方法で、データをロードしています。
■ まとめ
今回は GCP のマネージド・サービスを活用したWebサービスの開発について説明させていただきました。
L2Mixerをオンプレミス環境から GCP に移行したことにより、さまざまなメリットがありましたが、私は、エンジニアがいろいろなアイデアをすぐに試せるようになったことが一番のメリットだと感じています。
何かを試したいときにさくっと環境を構築し、そこでアイデア(プロトタイプで実装したアプリケーションなど)を試してみて、不要になったらすぐに環境をなくすことができます。 GAE をはじめとしてマネージド・サービスには無料利用枠もあるので、ちょっとしたことを試す分にはお金のことも殆ど気にすることはありません。
GCP が提供するマネージド・サービスには、DataProc(SparkとHadoopのマネージド・サービス)やDataFlow(ETL、バッチ処理、継続的な計算処理などデータ処理のサービス)といった広告サービス基盤を構築する上で有用なサービスがまだまだあるため、今後はこれらのマネージド・サービスの活用にも、積極的に取り組んでいきたいと考えています。
「L2Mixer]」の GCP 移行については、TechTargetジャパンでも紹介されています。あわせてご覧ください。
「Google Cloud Platform」へ移行した企業に、使って分かった魅力を聞いた:ブレインパッドに聞くGCP活用のコツ(1/2 ページ) - TechTargetジャパン クラウド
ブレインパッドでは、今回ご紹介したような最新の技術を使って、自社のWebサービスを一緒に開発していただけるエンジニアを募集しています。ご応募をお待ちしています!
http://www.brainpad.co.jp/recruit/