【アップデート】S3ライフサイクル移行ルール変更:デフォルトの最小オブジェクトサイズの導入でコスト最適化を実現できるようになりました
こんにちは!AWS事業本部のおつまみです。
みなさん、S3のライフサイクル管理を実施していますか?私は実施しています。
S3 のライフサイクル管理は、オブジェクトがライフサイクル全体にわたってコスト効率に優れた方法で保存されるように管理するための機能です。この機能によって、データの保存コストを最適化し、長期保存データの管理を自動化できるようになりますね。
S3 ライフサイクル管理は、ライフサイクルルールと呼ばれるルールによって制御され、特定の条件に基づいてオブジェクトに対するアクションを定義します。主なアクションには以下があります。
- 移行(Transition): オブジェクトを別のストレージクラス(例:Standard から Glacier)に移動させる
- 有効期限(Expiration): 指定した期間後にオブジェクトを自動的に削除する
今回1.移行に関するルールでアップデートがありました。
今回はそのアップデート情報についてご紹介したいと思います!
いきなり結論
- 2024 年 9 月のアップデート前のデフォルトの動作では、128 KB 未満のオブジェクトは S3 Glacier Flexible Retrieval および S3 Glacier Deep Archive ストレージクラスにのみ移行できた。
- 2024 年 9 月のアップデート以降、デフォルトの動作により、128 KB 未満のオブジェクトはどのストレージ クラスにも移行されなくなる。最小オブジェクトのサイズのカスタマイズも可能になった。
- 既存のライフサイクルルールには適用されない。
これまで
2024年9月のアップデート以前、S3のライフサイクルルールには既に特定のオブジェクトサイズに関する制限が存在していました。主な制限は以下の通りです。
-
128 KiB未満のオブジェクトの移行制限:
以下の移行では、Amazon S3は128 KiB未満のオブジェクトを移行しませんでした。- S3 StandardまたはS3 Standard-IAストレージクラスからS3 Intelligent-TieringまたはS3 Glacier Instant Retrievalへの移行。
- S3 Standardストレージクラスから S3 Standard-IAまたはS3 One Zone-IAへの移行。
-
128 KB未満のオブジェクトの移行可能なストレージクラス:
- 128 KB未満のオブジェクトは、S3 Glacier Flexible Retrieval およびS3 Glacier Deep Archiveストレージクラスにのみ移行可能でした。
これらの制限は、小さなオブジェクトの不要な移行を部分的に防いでいましたが、すべてのストレージクラスや移行パターンに一貫して適用されているわけではありませんでした。
そのため、ユーザーによっては小さなオブジェクトの移行による予期せぬコスト発生のリスクがありました。
移行コストを計算してみた
例えば、1 KBの小さなオブジェクトを大量に保存しているユーザーが、コスト削減のためにこれらのオブジェクトをS3 Glacierにライフサイクルルールで移行するよう設定した場合を考えてみます。
移行コストの計算:
- S3 Glacier Deep Archiveへの移行リクエスト料金(バージニア北部リージョン): 1,000 件のリクエストあたり$0.05
- 1,000,000個の1 KBオブジェクトを移行する場合: 移行コスト = (1,000,000 / 1,000) * 0.05 = $50
一方、これらのオブジェクトのS3 Standard上での保管し続ける場合のコスト(バージニア北部リージョン):
- S3 Standard料金: $0.023 per GB/月
- 1,000,000個の1 KBオブジェクト = 約1 GB 月間保管コスト = 1 * 0.023 = 0.023 = $0.023
この例だと、移行コスト($50)が月間の保管コスト($0.023)を大幅に上回っていまることになります。
さらに、S3 Glacierでの保管料金($0.004 per GB/月)や、将来的な取り出しコストも考慮する必要があります。
このように、小さなオブジェクトを大量に保有するユーザーが、サイズを考慮せずにS3 GlacierおよびS3 Glacier Deep Archiveストレージクラスへの移行のためライフサイクルルールを設定した場合、予想外の高額な移行コストが発生する可能性がありました。
AWSマネジメントコンソールでライフサイクルルールを設定する際にも、このような注意喚起が表示されますね。
したがって、ユーザーはデータ特性を十分に理解し、オブジェクトサイズとその分布を考慮したうえでライフサイクルルールを慎重に設定する必要がありました。
これから
2024年9月のアップデート以降、Amazon S3のライフサイクルルールのデフォルト動作が大きく変更されました。この変更により、128 KB未満のオブジェクトはどのストレージクラスにも自動的に移行されなくなります。
新しいデフォルト設定の詳細をみてみましょう。
新しいデフォルト設定の詳細
-
適用範囲:
- すべてのストレージクラスへの移行に適用されます。
- これまで対象外であったS3 Glacier Flexible Retrieval、S3 Glacier Deep Archiveを含むすべてのクラスが対象となります。
-
最小オブジェクトサイズ:
- デフォルトで128 KBに設定されます。
- これより小さいオブジェクトは自動的に移行されません。
-
カスタマイズ可能:
- 必要に応じて、最小・最大オブジェクトサイズを変更できます。
- ユーザーのニーズに合わせて柔軟に調整可能です。
このようにデフォルト設定が変わることで以下のようなメリットがあります。
メリット
-
小さなオブジェクトの不要な移行を防止:
- 128 KB未満のオブジェクトが自動的に移行されなくなるため、不要な移行コストを削減できます。
- 先ほど例に挙げた 1 KBのオブジェクト1,000,000個の移行で約$50といったコストを削減できます。
-
移行リクエスト数の削減によるコスト最適化:
- 小さなオブジェクトの移行リクエストが減少し、全体的な移行コストが低減します。
- 大規模なデータセットでは、この削減効果が顕著になり、予期せぬコスト発生のリスクが低減します。
-
カスタマイズ可能な移行範囲とコスト効率の最適化:
- 必要に応じて、最小・最大オブジェクトサイズを変更できるため、オブジェクトのサイズに基づいて適用する範囲を制限できます。
- 移行した場合に高いコスト効率が見込めないオブジェクトを除外することで、ユーザーは自身のデータ特性とコスト構造に最適化されたライフサイクル管理を実現できます。
-
データ管理の一貫性向上:
- すべてのストレージクラスで同じルールが適用されるため、データ管理方針の一貫性が向上します。
既存環境への影響は?
既存のライフサイクルルールには影響ありません。現在の設定がそのまま維持されます。
新しいライフサイクルルールの作成時、または既存ルールの変更時に新しいデフォルト設定が適用されます。
そのため、既存の環境から新しいデフォルト設定への移行は、ユーザー自身で実施する必要があります。
やってみた(検証)
今回は最小オブジェクトサイズのカスタマイズなし・ありの2パターンで検証してみたいと思います。
パターン①(最小オブジェクトサイズのカスタマイズなし)
パターン①の条件は以下の通りです。
- S3 Standard → S3 Glacier Deep Archive へのライフサイクル移行ルール(1日経過)を設定
- 最小オブジェクトサイズは設定なし(デフォルトの128KBのまま)
- 以下サイズのファイルをアップロード
- 100KBのファイル(small-file.txt)
- 200KBのファイル(large-file.txt)
- 以下の結果になることを確認する
- small-file.txt はS3 Standard のまま
- large-file.txt はS3 Glacier Deep Archive へ移行
検証環境は以下のCloudFormationテンプレートで構築しました。
CloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation template for S3 Lifecycle Rule testing with 1-day transition'
Resources:
LifecycleTestBucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: 'lifecycle-test-bucket-2024'
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: TransitionToIntelligentTiering
Status: Enabled
Transitions:
- StorageClass: DEEP_ARCHIVE
TransitionInDays: 1
Prefix: ''
TagFilters:
- Key: 'TestObject'
Value: 'true'
UploadTestFiles:
Type: 'AWS::Lambda::Function'
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
s3 = boto3.client('s3')
bucket_name = event['ResourceProperties']['BucketName']
try:
# 100KBのファイルをアップロード
s3.put_object(Bucket=bucket_name, Key='small-file.txt', Body='a'*102400,
Tagging='TestObject=true')
# 200KBのファイルをアップロード
s3.put_object(Bucket=bucket_name, Key='large-file.txt', Body='a'*204800,
Tagging='TestObject=true')
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
print(e)
cfnresponse.send(event, context, cfnresponse.FAILED, {})
Runtime: python3.8
Timeout: 30
LambdaExecutionRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
Policies:
- PolicyName: S3Access
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 's3:PutObject'
- 's3:PutObjectTagging'
Resource: !Sub '${LifecycleTestBucket.Arn}/*'
- PolicyName: CloudWatchLogs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
TriggerLambda:
Type: 'Custom::TriggerLambda'
Properties:
ServiceToken: !GetAtt UploadTestFiles.Arn
BucketName: !Ref LifecycleTestBucket
Outputs:
BucketName:
Description: 'Name of the created S3 bucket'
Value: !Ref LifecycleTestBucket
BucketARN:
Description: 'ARN of the created S3 bucket'
Value: !GetAtt LifecycleTestBucket.Arn
このように条件通りオブジェクトがアップロードされており、ライフサイクルルールも設定されています。
- ライフサイクルルール
それでは、1日ほど待ちたいと思います。
よって、新しいデフォルト設定が期待通りに機能していることが確認できました。
パターン②(最小オブジェクトサイズのカスタマイズあり)
つづいてパターン②の条件は以下の通りです。
- S3 Standard → S3 Glacier Deep Archive へのライフサイクル移行ルール(1日経過)を設定
- 最小オブジェクトサイズを300 KB に変更
- 以下サイズのファイルをアップロード
- 100KBのファイル(small-file.txt)
- 200KBのファイル(medium-file.txt)
- 350KBのファイル(large-file.txt)
- 以下の結果になることを確認する
- small-file.txt はS3 Standard のまま
- medium-file.txt もS3 Standard のまま
- large-file.txt はS3 Glacier Deep Archive へ移行
検証環境は以下のCloudFormationテンプレートで構築しました。
CloudFormationテンプレート
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudFormation template for S3 Lifecycle Rule testing with 1-day transition to Deep Archive and minimum object size'
Resources:
LifecycleTestBucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: 'ifecycle-test-bucket-2024-2'
VersioningConfiguration:
Status: Enabled
LifecycleConfiguration:
Rules:
- Id: TransitionToDeepArchive
Status: Enabled
Transitions:
- StorageClass: DEEP_ARCHIVE
TransitionInDays: 1
Prefix: ''
TagFilters:
- Key: 'TestObject'
Value: 'true'
ObjectSizeGreaterThan: 307200 # 300KB = 300 * 1024 bytes
UploadTestFiles:
Type: 'AWS::Lambda::Function'
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: |
import boto3
import cfnresponse
def handler(event, context):
s3 = boto3.client('s3')
bucket_name = event['ResourceProperties']['BucketName']
try:
# 100KBのファイルをアップロード (移行対象外)
s3.put_object(Bucket=bucket_name, Key='small-file.txt', Body='a'*102400,
Tagging='TestObject=true')
# 200KBのファイルをアップロード (移行対象外)
s3.put_object(Bucket=bucket_name, Key='medium-file.txt', Body='a'*204800,
Tagging='TestObject=true')
# 350KBのファイルをアップロード (移行対象)
s3.put_object(Bucket=bucket_name, Key='large-file.txt', Body='a'*358400,
Tagging='TestObject=true')
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
print(e)
cfnresponse.send(event, context, cfnresponse.FAILED, {})
Runtime: python3.8
Timeout: 30
LambdaExecutionRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: 'sts:AssumeRole'
Policies:
- PolicyName: S3Access
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 's3:PutObject'
- 's3:PutObjectTagging'
Resource: !Sub '${LifecycleTestBucket.Arn}/*'
- PolicyName: CloudWatchLogs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogGroup'
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
Resource: 'arn:aws:logs:*:*:*'
TriggerLambda:
Type: 'Custom::TriggerLambda'
Properties:
ServiceToken: !GetAtt UploadTestFiles.Arn
BucketName: !Ref LifecycleTestBucket
Outputs:
BucketName:
Description: 'Name of the created S3 bucket'
Value: !Ref LifecycleTestBucket
BucketARN:
Description: 'ARN of the created S3 bucket'
Value: !GetAtt LifecycleTestBucket.Arn
このように条件通りオブジェクトがアップロードされており、ライフサイクルルールも設定されています。
- ライフサイクルルール
同じように、1日ほど待ちたいと思います。
こちらも、デフォルト設定が上書きされ、期待通りに機能していることが確認できました。
最後に
今回は、S3ライフサイクル移行ルールのデフォルト設定が新しくなったことを紹介しました。
このアップデートにより、S3のコスト最適化と運用効率向上が期待できます!
特に大量の小さなオブジェクトを扱うユーザーにメリットがありそうですね。必要に応じて移行できるオブジェクトのサイズもカスタマイズも可能なので、自身のユースケースに合わせて最適な設定を行ってください。
最後までお読みいただきありがとうございました!
以上、おつまみ(@AWS11077)でした!