Gunosy Tech Blog

Gunosy Tech Blogは株式会社Gunosyのエンジニアが知見を共有する技術ブログです。

広告配信用の画像変換・キャッシュ配信サービスを作った話

Gunosyでネットワーク広告系のプロダクトを扱っているeastです。今回は、弊社アドネットワークで配信されるクリエイティブ画像の画像変換・キャッシュ配信サービスを構築した話をします。

経緯

今までは無駄に高品質な画像を配信していた

弊社アドネットワークでは様々なクリエイティブ画像が管理画面から入稿され配信されていますが、画像のフォーマットやサイズ・品質は統一されていませんでした。

もちろん、画像容量や画像サイズの制限といった最低限の制約はあります。

しかし、無駄に画質の良い(容量の大きい)画像を配信していたり、配信先の端末サイズに対して明らかに大きすぎる画像を配信しているなど、無駄な部分が大きいと感じていました。

最新の画像フォーマットに対応させたい

最新というほどでもないですが、WebPのような次世代の画像フォーマットを採用した事例も増えてきているように思います。WebPに関しては、割と最近までSafariが対応してないという問題がありましたが、Safari 14からは正式にサポートされます。

また、AVIFといったさらに次世代のフォーマットも出てきているので、そういった最先端のフォーマットを手軽に試せると面白そうです。

画像変換・配信サービスを作ったよ

上に書いた経緯のような問題を解決するために、簡単な画像配信サービスを構築しました。商用のサービスで言うImageFluxの簡易版を作成したようなイメージですね。

構成図

全てAWS上に構築されており、超簡易的な構成図が以下になります。

f:id:eastresident:20210310163352p:plain

変換サーバー自体はGoで書かれており、画像周りの処理はImageMagickを使用しています。変換サーバーはEKS上にdeploymentとして設置されており、S3から画像を取得します。変換サーバーのPodにつながったLoadBalancerの前にはCloudFrontを置いておき、ここに変換済みの画像がキャッシュされます。

変換パラメーターに関して

以下は実際のURL例になります(いたずらしないでね)。

https://adnw-cdn-stg.gunosy.com/convert/BIKsLe95rpvUP8ufHwRS-smOeocgqbjYPfzpAw6HM?ext=png&format=webp&q=95&w=280&h=280

クエリパラメータの役割は以下のようになっています。

項目 役割
ext オリジナル画像のフォーマット
format 変換したいフォーマット
q 画像の品質
w 変換後の横幅
h 変換後の高さ

CDNでのキャッシュのされ方

構成図のところで説明したように、変換後の画像はCloudFrontにキャッシュして配信されます。このキャッシュは、ブラウザのAccept Header+URLのクエリパラメータごとに作成されるようにしました。

理由は、Accept Headerを見ることで、変換後の画像がブラウザで描画可能か否かを判定したいからですね。例えば、WebPに変換して配信する場合、format=webpを指定しますが、ブラウザがWebPに対応していない場合はフォーマット変換を無視する(あるいは別の無難なフォーマットに変換する)というような仕組みにしています。 これにより、同じURL(クエリパラメータ)でも、ブラウザによって異なるキャッシュ画像を返すことが出来ます。

何が良くなったか

この画像配信サービスを作って良くなったこと・今後良くなりそうなことは以下でしょうか

画像配信の転送量削減

今までは、クリエイティブによってはPNGの無駄に高画質な画像を配信してしまっていることもありましたが、今回の配信サービス導入後は、基本的にWebP or JPEGのフォーマットに変換した上で、品質と画像サイズもある程度調整して配信するようにしました。

元々の画像にもよりますが、1/10以上容量が削減出来たケースもあり、転送量を大きく削減することが出来ました。当然ですが、転送量の削減は転送料金の削減や画像表示の高速化にも繋がります。

管理画面で画像アップロードがシンプルに

今回作成したような配信サービスが存在しない場合、配信画像を最適化するには複数バージョンの画像を保持する必要があるかと思います。低画質用・高画質用・サムネイル用といった感じですね。

ですが、今回作成したような配信サービスがあれば、高画質なオリジナル画像さえ保持しておけば、クエリパラメータを変更するだけで低画質用やサムネイル用の画像も生成できるので無駄が少ないですね。

他のプロダクトでも流用できる

今回作成した画像配信サービスは、弊社アドネットワークで利用するために構築した物です。 ですが、配信サービス自体は基本的にS3にのみ依存しているため、他のプロダクトでも流用が可能です。

最後に

というわけで、弊社アドネットワーク用に画像変換・キャッシュ配信サービスを構築した話を紹介いたしました。

AWSで同じような画像配信サービスを構築した例はググればいくつか見つかりますが、Lambda@Edgeを活用した事例がほとんどですね。

Lambda@Edgeを使う利点も、もちろんあると思います。

例えばマルチリージョンで配信するような状況だと、Lambda@Edgeを使えば効率的なネットワーク経路で処理が実行されるので有利かもしれません。しかし、弊社アドネットワークは現状ほぼ日本国内にしか配信していません。

コンピューティングリソースやスケール性といったこと管理しなくていいといったサーバーレスの利点もありますが、今回の画像配信システムだと前段にCloudFrontを置いてキャッシュしているため、負荷もほとんど気にする必要がありません。

逆に以下のような欠点もあるため、今回Lambda@Edgeは採用しませんでした。

  • 普通のLambdaとは違ってnode.jsとpythonしか使えない

  • 状況によっては滅多に起動されないので、ウォームアップに時間がかかる可能性

  • Lambdaの制限を意識する必要がある

  • 使ったことがないので調査・検証に時間がかかる

機会があればLambda@Edgeも使ってみたいですね!