CloudinaryをやめてGCPで独自システムを構築した話
はじめに
Cloudinaryをやめる理由
私は現在プリ小説という小説投稿サイトの開発をしています。
毎月多くのユーザー様にご利用いただいており、小説の投稿数もどんどん増えています。
それに伴い画像のアップロードも増えてきて、Cloudinaryの料金が高くなってきました。
現在契約しているプランに収まりきらず、毎月割高な超過料金を支払っている状況です。
元々画像のリサイズ機能ぐらいしか利用しておらず、サイズも2~3種類程度で、ちょっと便利なCDNぐらいの機能しか活用できてないので、自前で構築することにしました。
構成図
Cloudinaryだった頃の構成図は以下の通りです。
GCPで構築した後の構成図は以下の通りです。
(間にCDNとかロードバランサーとか色々あるけど、簡略化しています。)
処理の流れ
画像のアップロード
ユーザーの画像アップロードをトリガーにCloud Functionsが起動し、Cloud TasksにTaskを登録します。
画像のリサイズ
Cloud Tasksから変換用のCloud Functionsにリクエストが送られ、画像のリサイズ処理を行います。
変換後は、別のCloud Storageに保存します。
同じStorageに保存すると、無駄なトリガーが発生してしまうためです。
間にCloud Tasksを挟むことで、リクエストの負荷をコントロールしたり、リトライ処理、重複処理の排除など様々なメリットがあります。
毎月2千万ほどリクエストがあるので、負荷コントロールは特に重要です。
高機能ながら、Cloud Tasksは100万回あたり$0.4という安価な料金設定なのでありがたいです。
画像の配信
画像の配信は、Cloud StorageのURLを直接参照することで行います。
アップロードされた画像の変換が終わっていない場合は、変換前の画像を配信します。
WebはAngular、アプリはFlutterで開発しているので両フレームワークには画像がエラーの時に呼び出されるメソッドがあるので、それを利用しています。
このシステムが導入される前の画像は、変換前の画像を配信しつつ、非同期でCloud Tasksにリクエストを送るようにしました。
コスト削減効果
新システムの導入により、月額で約50万円のコスト削減ができる試算です。この大幅な削減は、Cloudinaryの高額な超過料金を避けられたことが主な要因です。GCPの各サービスを効率的に利用することで、高機能を維持しながらもコストを抑えることができました。
システムのパフォーマンスと技術詳細
高速な画像処理
新システムでは、画像の平均変換時間を1秒未満に抑えることができました。これは、以下の技術選択によって実現しています:
- Cloud Functions v2の利用: 最新のv2を採用することで、1インスタンスあたりの処理能力が向上し、効率的なスケーリングが可能になりました。
- sharpライブラリの採用: ImageMagickよりも高速な画像処理ライブラリであるsharpを利用することで、処理速度を大幅に向上させました。
- 並列処理:複数枚のリサイズが必要な場合は、画像のリサイズ処理を並列化することで、処理時間を短縮。
スケーラビリティ
Cloud Functionsのv2を利用し、1インスタンスで処理できる量を増やしたことで、トラフィックの増加に対しても綺麗にスケールする構成を実現しました。これにより、ピーク時のパフォーマンスも安定して維持できています。
自動的なリトライ
Cloud Tasksを利用することで、リトライ処理を自動化しました。
メモリ不足やネットワークエラー、スケールアップの遅延など、様々な理由で処理が失敗することがありますが、Cloud Tasksは200が返ってくるまでリトライを繰り返します。
リトライ頻度やその度にどのくらい時間を増やすかなど設置することで、間隔を開けながらリトライを行うことができます。
移行プロセスと段階的リリース
システムの移行とリリースには、以下のアプローチを採用しました:
- Firebase Remote Configの活用: システムをいつでも停止できるよう、Firebase Remote Configを利用しました。これにより、問題が発生した際の迅速な対応が可能になりました。
- 段階的なユーザー拡大: リリース後、対象ユーザーを少しずつ広げていきました。この過程で、Cloud Functionsのスペックを調整し、最適なパフォーマンスを追求しました。
まとめ
CloudinaryからGCPに移行することで、高機能な画像処理システムを構築し、コストを大幅に削減できました。
綺麗にインスタンスがスケールしているログを管理画面から見ると、とても満足しています。
Discussion