ファイルをダウンロードするアプリケーションをオンプレからAWSへ移行してみた

これまでに担当させていただいたオンプレミス環境からクラウド環境への移行案件で、ファイルをダウンロードさせる際に、特に有効だった設計についてご紹介したいと思います。
2021.06.01

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

データアナリティクス事業本部の藤川です。
今日からGoogleフォトが容量無制限の保存に対して課金されるようになりました。
私自身いつから「クラウド」という言葉を使い始めたかよく覚えていませんが、2010年には既に優れたクラウドサービスが数多く登場していました。 (2006年8月に、当時Google社CEOのエリック・シュミット氏が発した「クラウド・コンピューティング」が最初のようです)

その後、企業のクラウドサービス活用が急速に進んでいることは言うまでもありません。
一方で、AWS OutpostsのようにAWSのサービスをオンプレミス環境で稼働させるサービスが登場しています。

企業のクラウドサービス利用状況について見てみると、実は、まだまだクラウドサービス化が進む余地は残されていることに気付きます。 もちろん、業種によっては、クラウド化できない業務がある等、それぞれの事情もあるでしょう。

今回は、これまでに担当させていただいたオンプレミス環境からクラウド環境への移行案件で、特に有効だった設計についてご紹介したいと思います。

ファイル・ダウンロード・アプリケーション

IaaSでファイル・ダウンロード・アプリケーション

ファイルをダウンロードするアプリケーションを構築する場合、オンプレミスでは、アプリケーションサーバファイルサーバを構築していました。 これらをAWSで構築する場合、EC2S3を使用するでしょう。

アプリケーションサーバはユーザからのリクエストを受け、ファイルサーバにファイルを取りに行きます。 アプリケーションサーバは、ファイルをユーザにダウンロードさせます。

従来のアプリケーション設計では、ファイルサイズに相当するデータがアプリケーションサーバを通過します。
また、ファイルを転送している間は、アプリケーションサーバが他の処理を捌くことができず、無駄なリソースを消費することになります。
複数ユーザが同時にファイルダウンロードした場合は、さらにアプリケーションサーバに負荷が掛かります。

on-premises-download-file

AWSネイティブなファイル・ダウンロード・アプリケーション

AWSネイティブにファイルをダウンロードするアプリケーションを構築する場合、無駄なファイル転送処理を他に任せてしまうことが重要です。 ファイルはEC2を通過せず、ユーザはS3から直接ダウンロードできる設計にするべきです。 また、EC2をサーバレスアーキテクチャに置き換えることで、使った分だけAWS利用料が発生するようにできます。

アプリケーションサーバAPI Gateway + Lambdaで、ファイルサーバS3で構築したものが次の図です。図の左側は、非公開バケット(図の右側)に置いてある画像ファイルを一覧表示するための仕組みです。図の右側が、ファイルIDやファイル・パス等、S3に置いてあるファイルを一意に特定できる情報からS3 presigned URLを発行する仕組みです。

このように構築することで、API GatewayやLambdaをファイルが通過しません。ファイル転送はS3だけで完結するため、S3にしか負荷が掛かりません。
また、API GatewayやLambdaはS3 presigned URLを発行するだけです。リソースが拘束されず、複数同時アクセスにも十分耐えられますし、AWS利用料も比較的安価に抑えられます。

aws-download-file

この図の通りにサンプルコードを作成しました。AWS SAMを採用したので、コードで簡単に構築できますし、非常に少ないコード量で済みます。
使用方法等の詳細については、こちらにあるREADME.mdをご参照ください。

git clone https://github.com/cm-fujikawa/s3-download-file.git

さいごに

ここでは、サンプル実装をご紹介したため、ユーザ認証やファイルID化、ファイル・パスの難読化等各種対策までできませんでした。
実際の運用では、ユーザ認証やファイルID化が必須だと思います。CognitoやDynamoDBを使用すれば、こういった課題も解決できると考えます。

aws-download-file-ext