S3で色々お試しして遊んでみる(VPCエンドポイント&静的Webホスティング性能編)


はじめに

S3。単なるマネージドでサーバレスなバックエンドストレージなだけでなく(いや、それだけでも充分すごいんだけど)、暗号化できたり、セキュアアクセスができたり、ファイルの中身にクエリ発行できたり、ウェブサイトのホスティングができたり、イベントトリガになったり、なんだか色々できてすごいぞ!

これを使い倒さずに、毎回「とりあえずバケット作っておくか」な使い方をしているだけではもったいない!

ということで今回は、色々ある機能の内、VPCエンドポイントと静的Webホスティングの機能について触れてみる(いずれもさわりだけなので、たいした検証にはなっていないのだが……)。

VPCエンドポイント

VPCエンドポイントの詳細は公式を見てもらうと良い。
要するに、S3のAPIはインターネットに口を向けているので、何も考えずにVPCからaws cliを実行したりすると、インターネットを通ってしまう。内部通信をしたいのに!というときに利用するものである。VPCエンドポイントは色々なAWSサービスに対応しているが、S3とDynamoDBは追加料金不要(ほかのサービスはPrivateLinkを利用するためそこそこのお金がかかる)!これは是非使っておこう。

Terraformでの設定

マネージメントコンソール画面ではなくていきなりIaCのことを言い出すのは結構アレではあるが、実際やってみると、画面で設定するのも大して変わらないので、さっさと自動化出来てしまった方が手っ取り早い。

予めVPCとルートテーブルは作成済みで、データリソースで参照できるようにしていることが前提だ。

resource "aws_vpc_endpoint" "s3" {
  vpc_id       = data.aws_vpc.my.id
  service_name = "com.amazonaws.ap-northeast-1.s3"
}

resource "aws_vpc_endpoint_route_table_association" "s3" {
  route_table_id  = data.aws_route_table.my.id
  vpc_endpoint_id = aws_vpc_endpoint.s3.id
}

これだけでOK!簡単!

性能差を確認する

さて、インターネット通信を内部に閉じるのだから、おそらくレイテンシも解消されるのであろう。
一石二鳥だ!

と思い、上記のVPCエンドポイント作成後にVPC内のLambdaからboto3でのアクセスとインターネット経由でのアクセスを両方試してみた。boto3でのアクセスは、VPCエンドポイントを作る前はエラーになっていたので、おそらくVPCエンドポイントを通っているのだろう。

余談ではあるが、VPC内のLambdaは起動時にENIを作成するため、以下のページにあるようにIAMポリシにパーミッションを追加する必要があるので要注意だ。

【AWS公式】VPC 内のリソースにアクセスするための Lambda 関数の設定

さて、これでVPCから起動したLambdaで測定ができるぞ。
以下は、VPCエンドポイントへのアクセス後、静的WebホスティングしたS3へアクセスするという順序で20回計測した結果の平均だ。

VPCエンドポイント 静的Webサイトホスティング
329.4msec 63.8msec

……あれ?なんかインターネットを経由する静的Webサイトホスティングの方が早いぞ?
もしかして、順序がいけないのだろうか。2回目のアクセスはどこかのキャッシュが機能してしまって早いとかか(そんな話は聞いたことが無いが)?

ということで、VPCエンドポイントのアクセス2回、静的WebホスティングしたS3へアクセス2回を1回のLambda関数内で実行して、それぞれの2回目のアクセスを20回計測して平均を取った。

VPCエンドポイント 静的Webサイトホスティング
154.9msec 45.0msec

うーむ、どちらも2回目の方が早くなった。謎……。
一石二鳥にはならないようだ。

静的Webサイトホスティング

静的Webサイトホスティングは、名前の通り、S3に静的コンテンツを突っ込んで置いたらWebサーバを立てなくてもHTTPリクエストに応答してコンテンツを返してくれる機能だ。ちょっとしたコンテンツならこれでサーバレスに賄えてしまう。便利!

ここではサクッとホスティング機能を設定することだけ書いているが、商用で運用する場合はアクセスログの記録やアクセス制御をちゃんとやろう。

マネージメントコンソールでの設定

マネコン画面では以下の画面から設定が可能。簡単!

Terraformでの設定

以下のようにaws_s3のリソースを設定すれば良い。簡単!

resource "aws_s3_bucket" "my" {
  bucket = local.bucket_name
  acl    = "public-read"

  website {
    index_document = "index.html"
    error_document = "error.html"
  }
}

なお、簡単ではあるが、バケットにオブジェクトを格納する場合は、オブジェクトも acl = "public-read" にしておく必要があるので注意しよう。

静的Webサイトホスティングの素性能

さて、では静的Webサイトホスティングはどこまで自動でスケールしてくれるのだろうか?
ひとまず、Locustを使って計測してみる。

ちなみに、Locustはt3.xlargeなEC2上でワーカーノードを3つ動かしている。
この状態で、200ユーザを起動し、150ミリ秒のウェイトを挟んでトラフィックを投げ込んでいる。
コンテンツサイズは一律で50KB程度。



ご覧の通り、1100~1200rpsあたりでもまだまだResponse Timesが延びることなく安定して線形にスループットが延びている。ワーカーノードを増やせばまだまだ延ばせそうだ。

ちょっとしたトラフィックを捌くのであれば、CloudFrontを使うまでもなくそこそこに性能が出せるように思える。
S3すごい!