S3
初心者向けに網羅していく
コンセプト
インターネット用のストレージで、
世界のどこからでもファイルのサイズ・種類に関係なくウェブ越しにファイルの取得・保存ができる。
用語
バケット:ファイルを入れておく場所(ディレクトリではなくコンテナ)
オブジェクト:ファイルのこと
バケット
リージョン単位で作成
1ユーザーで1つ以上のバケットを作成できる
バケット単位で制限(書込み・参照権限とか)を付けられる
バケットとその中のオブジェクトへのアクセス履歴をロギング可能
用途の例
ストレージ
バックアップストレージ
クラウド未使用の企業がここからクラウド使い出すのは多い
アプリケーションのホスティング
サーバサイド側に動的コンテンツなければ、これが恐らく最安
CFと連携しないとアクセス回数分DL走るので、そういうのと組み合わせは必要
ストレージの種類
以下のストレージをアクセス頻度を考慮して使い分ける
標準ストレージ
標準 – 低頻度アクセス (S3 標準 – IA) ストレージ
1 ゾーン – 低頻度アクセス (S3 1 ゾーン – IA) ストレージ
料金(ストレージ使用料)
標準ストレージ
最初の 50 TB/月・・・0.025USD/GB
次の 450 TB/月・・・0.024USD/GB
500 TB /月を超える分
低頻度アクセス (S3 標準 – IA) ストレージ・・・0.019USD/GB
低頻度アクセス (S3 1 ゾーン – IA) ストレージ・・・0.0152USD/GB
Amazon Glacier ストレージ・・・0.005USD/GB
料金(リクエスト)
低頻度アクセス
データ取り出し・・・0.01USD/GB
S3 Select によって返されたデータ・・・0.01USD/GB
S3 Select によってスキャンされたデータ・・・0.00225USD/GB
PUT、COPY、POST の各リクエスト・・・リクエスト 1,000 件あたり 0.01USD
GET、SELECT および他のすべてのリクエスト・・・リクエスト 1,000 件あたり 0.001USD
低頻度アクセス (S3 1 ゾーン – IA)
データ取り出し・・・0.01USD/GB
S3 Select によって返されたデータ・・・0.01USD/GB
S3 Select によってスキャンされたデータ・・・0.00225USD/GB
PUT、COPY、POST の各リクエスト・・・リクエスト 1,000 件あたり 0.01USD
GET、SELECT および他のすべてのリクエスト・・・リクエスト 1,000 件あたり 0.001USD
上記以外
S3 Select によって返されたデータ・・・0.0008USD/GB
S3 Select によってスキャンされたデータ・・・0.00225USD/GB
PUT、COPY、POST、または LIST リクエスト・・・リクエスト 1,000 件あたり 0.0047USD
GET、SELECT および他のすべてのリクエスト・・・リクエスト 1,000 件あたり 0.00037USD
標準 – 低頻度アクセスまたは 1 ゾーン – 低頻度アクセスへのライフサイクル移行リクエスト
リクエスト 1,000 件あたり0.01USD
DELETEは無料
リソースへのアクセス許可
デフォルト
バケット、オブジェクト、関連サブリソース (lifecycle 設定や website 設定など) はプライベート(リソースを作成した AWS アカウントだけがリソースにアクセス可)
リソースベースのポリシー
バケットとオブジェクトに設定されるポリシー
ユーザーポリシー
アカウント内のユーザーに設定するポリシー
リソースポリシーとユーザーポリシーを組み合わせて使う
リソースアクセス管理の概念
アクセスポリシーのエレメント
プログラマブルに設定する場面で使うので覚える(マネジメントコンソールからイチイチポチポチするの時間の無駄)
リソース:バケットArnを指定、ディレクトリも指定可能 → 設定 アクション:オブジェクトの作成、更新、削除などの指定 → 設定 エフェクト:アクションの許可(Allow)・拒否(Deny)を指定
プリンシパル:アクセスポリシーを適応するアカウント・ユーザー → 設定 条件の指定:拡張子とかリクエスト元のIPアドレスとか細かい条件を追加できる → 設定 code:設定例.json
{
"Version": "2012-10-17",
"Id": "ExamplePolicy01",
"Statement": [
{
"Sid": "ExampleStatement01", // sidは被ってなければ何でも良い
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::Account-ID:user/Dave" // ← AWSアカウント、IAMユーザーを指定可能
// *を指定すると匿名アクセス可になるけど、基本使わない
// CFと連携させる場合はOAIを作ってここに設定する
},
"Action": [
"s3:GetObject",
"s3:GetBucketLocation",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::examplebucket/*", // ← グローバルサービスなので、リージョンと名前空間は指定しない
"arn:aws:s3:::examplebucket"
],
"Condition": {
"StringEquals": {
"s3:x-amz-acl": [
"public-read"
]
}
}
}
]
}
非 IAM ユーザー に対するバケット内のフォルダへのアクセス許可
モバイル端末ユーザーなどにもFacebookなどのOAuth認証をさせて、トークン使ってID発行&アクセス許可を与える方法がある
オブジェクトのライフサイクル
移行アクション
別のストレージクラスにオブジェクトを移行するタイミングを定義する
例えばログファイルが1ヶ月経ったら、Glacierに移行させるとかやると、保存金額が安くなるので効果的
有効期限アクション
有効期限を設定しておくと、期限切れしたオブジェクトを自動削除してくれる
一時領域に入りっぱなしのオブジェクトを削除するのに丁度良い。
制限事項としてMFA(多要素認証)が有効なバケットには設定できない
イベント通知
S3へオブジェクトを保存したり削除するとEventを発行して他の機能に通知が行える。
通知を行えるイベント
新しいオブジェクトの作成
オブジェクトの削除
低冗長化ストレージ (RRS) オブジェクト消失イベント
RRSって使ったことすらない
通知を行える相手
SQS
専用プログラムに通知したいならコレ
確実にアプリまで届く
SNS
一辺に色んな機能に通知して色々動かしたいならコレ
HTTP(S)エンドポイントを指定する場合は、そのサーバが生きてないといけないのでデータ消失する可能性はある
Lambda
ウイルススキャンとかチョットした処理をさせるならコレ
基本データ消失しないけど、重たい処理には向かない
使い分けは何で作るとお安く速く済ませられるかと耐障害性の強さどんなもんにんする?の世界なので合ったものを使う
通知の仕方
1. NotificationConfigurationの設定を用意する(cliとかで動的に作る)
2. 通知先サービスのポリシーにS3バケットからのアクセス許可を設定する
SQS(公式がxmlで乗ってるからそうしてるけど、jsonでも可)
code:s3のnotificatoin-configuration.xml
<NotificationConfiguration>
<QueueConfiguration>
<Id>optional-id-string</Id> // <- 一意な値で適当に入れる
<Queue>sqs-queue-arn</Queue> // <- 通知するSQSのArn aws-cli使って取ると動的に作れる
<Event>event-type</Event> // <- 通知したいイベントを設定
<Event>event-type</Event>
... // <- オプション(フォルダとか拡張子とか設定できる)
</QueueConfiguration>
...
</NotificationConfiguration>
上記に加えて、SQS側にアクセス権限を与えないといけない
(全部の設定が1ファイル)
code:queue-attributes.json
{
"Version": "2008-10-17",
"Id": "example-ID", // <- 一意な値で適当に入れる
"Statement": [
{
"Sid": "example-statement-ID", // <- 一意な値で適当に入れる
"Effect": "Allow",
"Principal": {
"AWS": "*" // <- 読みだす側の設定に合わせてちゃんと設定はする
},
"Action": [
"SQS:SendMessage"
],
"Resource": "SQS-ARN",
"Condition": {
"ArnLike": { "aws:SourceArn": "arn:aws:s3:*:*:bucket-name" }
}
}
]
}
SNS(公式がxmlで乗ってるからそうしてるけど、jsonでも可)
code:s3のnotificatoin-configuration.xml
<NotificationConfiguration>
<TopicConfiguration>
<Id>optional-id-string</Id> // <- 一意な値で適当に入れる
<Topic>sns-topic-arn</Topic> // <- 通知するSNSのArn aws-cli使って取ると動的に作れる
<Event>event-type</Event> // <- 通知したいイベントを設定
<Event>event-type</Event>
... // <- オプション(フォルダとか拡張子とか設定できる)
</TopicConfiguration>
...
</NotificationConfiguration>
上記に加えて、SNS側にアクセス権限を与えないといけない
(全部の設定が1ファイル)
code:topic-attributes.json
{
"Version": "2008-10-17",
"Id": "example-ID", // <- 一意な値で適当に入れる
"Statement": [
{
"Sid": "example-statement-ID", // <- 一意な値で適当に入れる
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": [
"SNS:Publish"
],
"Resource": "SNS-ARN",
"Condition": {
"ArnLike": { "aws:SourceArn": "arn:aws:s3:*:*:bucket-name" }
}
}
]
}
Lambda(公式がxmlで乗ってるからそうしてるけど、jsonでも可)
code:s3のnotificatoin-configuration.xml
<NotificationConfiguration>
<CloudFunctionConfiguration>
<Id>optional-id-string</Id> // <- 一意な値で適当に入れる
<Cloudcode>cloud-function-arn</Cloudcode> // <- 通知するLambdaのArn aws-cli使って取ると動的に作れる
<Event>event-type</Event> // <- 通知したいイベントを設定
<Event>event-type</Event>
... // <- オプション(フォルダとか拡張子とか設定できる)
</CloudFunctionConfiguration>
...
</NotificationConfiguration>
上記に加えて、Lambda側にアクセス権限を与えないといけない
(1ファンクションごとにパーミッションを1つずつ設定可)
code:bash
// removeとaddをセットで行う
aws lambda remove-permission --function-name ${FUNCTION_ID} \
--statement-id s3-put-event
aws lambda add-permission --function-name ${FUNCTION_ID}\
--statement-id s3-put-event --action "lambda:InvokeFunction"\
--principal s3.amazonaws.com --source-arn arn:aws:s3:::${BUCKET_NAME}
クロスリージョンレプリケーション
バケットを異なるリージョンにあるバケットを非同期コピーする仕組み
更新オブジェクトの条件は絞れる
使い所
地理的にAZ間のレプリケーションでは要件を満たさない場合
レイテンシーの最小化(ってもうちのシステムだと用なし)
異なる所有者のバケットにコピー
外部システム連携でS3を利用するシーンでお世話になりそう(マテビューみたいな感覚)
要件
バージョニング必須
レプリケーション元と先は異なるリージョン(この時点で関わるシステムで使いたい場面が想像できない)
レプリケート元から先へコピーするためのアクセス権限
パフォーマンス最適化
大量のGET
CFを使う
CFを使うことでダウンロード使用料金も抑えられる
TCPウィンドウスケーリング
S3側の受信バッファサイズを変えることによって、ネットワークスループットを上げる
TCP 選択的送達確認(SACK)
パケット損失が多いネットワーク環境において有効
SACKはパケットごとにデータ損失がないかを検証して、損失していればそのパケットのみを再送信する
SACK以外は全パケットを送信し終わってから、データ損失チェック、損失してれば全部送り直すため、しょっちゅうデータ損失するような環境だとオーバーヘッドが大きい
その他
プレフィックスをつけないといけない、みたいなのは数ヶ月前のアップデートでなくなったのでもう不要
モニタリング
CloudWatch
モニタリング監視値によって以下のイベントを飛ばせる
SNS
EC2 Auto Scaling
エラー処理
インターナルエラーが帰ってきた場合は、リトライする
SlowDown エラーを繰り返すアプリケーションを調整する
リクエストしすぎのやつ、頻繁に起きるならお問い合わせ必要
S3へのリクエストが失敗しすぎて、サポートに問い合わせしたい場合は、リクエストIDがわかると迅速
エラーが起きたらリクエストIDを取ってログに出しておくと良い
SQL
S3に保存してあるオブジェクト(JSON/CSV)に対してクエリを発行し、必要なデータを取って来る
RDBのSELECT文と同じ構文で書ける(サブクエリとジョインは今はできない)
リクエストごとに課金はされる
要件
s3:GetObjectの権限が必要
暗号化キー (SSE-C) で暗号化している場合は、https必須
SQL 式の最大長は 256 KB
結果は最大1 MB