S3に保存されたファイルを特定のプレフィックスで一括削除する効率的な方法
背景
ファイルを個別に削除すると大量のAPI呼び出しが発生し、パフォーマンスとコストの問題が生じる
実装方法
ListObjectsV2Command と DeleteObjectsCommand を使用してプレフィックスベースで一括削除
import {
S3Client,
DeleteObjectsCommand,
ListObjectsV2Command,
} from '@aws-sdk/client-s3';
async function deleteAllFilesByPrefix(
bucket: string,
prefix: string
): Promise<void> {
const s3Client = new S3Client({ region: 'ap-northeast-1' });
let continuationToken: string | undefined;
do {
// プレフィックスでファイル一覧取得(最大1000件)
const listCommand = new ListObjectsV2Command({
Bucket: bucket,
Prefix: prefix,
ContinuationToken: continuationToken,
});
const listResponse = await s3Client.send(listCommand);
if (listResponse.Contents && listResponse.Contents.length > 0) {
// 最大1000件を一括削除
const objectsToDelete = listResponse.Contents
.filter((obj) => obj.Key !== undefined)
.map((obj) => ({ Key: obj.Key as string }));
if (objectsToDelete.length > 0) {
const deleteCommand = new DeleteObjectsCommand({
Bucket: bucket,
Delete: {
Objects: objectsToDelete,
Quiet: true,
},
});
await s3Client.send(deleteCommand);
}
}
continuationToken = listResponse.NextContinuationToken;
} while (continuationToken);
}
重要なポイント
DeleteObjectsCommand は最大1000件まで一括削除可能(AWS仕様)
ListObjectsV2Command もデフォルトで最大1000件まで取得
- ページネーション(ContinuationToken)で1000件以上にも対応
Quiet: true で削除結果詳細を省略しパフォーマンス向上
- TypeScript ESLintルールで non-null assertion (
!) が禁止されている場合は filter と型アサーションで対応
パフォーマンス比較
- 個別削除: 1000ファイル = 1000回のAPI呼び出し
- 一括削除: 1000ファイル = 2回のAPI呼び出し(List + Delete)
- 5000ファイルでも12回程度(List×6 + Delete×6)