🔄 Storage Gateway RefreshCache

自動化で実現する完璧な同期 - 初心者でも分かる完全ガイド

📚 図書館システムで例えると超わかりやすい!

Storage Gateway = 図書館の貸出カウンター

本棚(S3バケット)には膨大な本があるけど、
貸出カウンター(Storage Gateway)には人気の本だけを置いておきます。

でも、誰かが本棚に直接本を追加したら?
カウンターの在庫リストは 古いまま になってしまいます!

RefreshCache = 在庫リストの更新作業
これを自動化する方法を完全マスターしましょう✨

📚 図書館システムの3つの要素

🏛️

S3バケット
(本棚)

全ての本が保管されている場所

• 膨大な本のコレクション
• 誰でも直接アクセス可能
• でもアクセスが遅い
• 永続的なストレージ

🏪

Storage Gateway
(貸出カウンター)

利用者に本を渡す窓口

• 人気の本をキャッシュ
• 高速アクセス可能
• オンプレミスから利用
• S3への橋渡し役

📋

キャッシュ
(在庫リスト)

カウンターの在庫情報

• どの本があるか記録
• 定期的な更新が必要
• 古いと問題発生
• RefreshCacheで更新

⚠️ なぜRefreshCacheが必要なのか?

1️⃣
初期状態:完璧な同期
Storage Gatewayを通してS3にファイルを書き込んだ場合、Gatewayは自動的に自分のキャッシュを更新します。
→ 問題なし! 👍
2️⃣
問題発生:S3への直接アップロード
AWS CLIや他のツールでS3に 直接 ファイルをアップロード。
Storage Gatewayはこの変更を 知らない
→ キャッシュが古くなる 😱
3️⃣
ユーザーの混乱
オンプレミスからStorage Gateway経由でアクセスすると...
「新しいファイルが見えない!」
「古いファイルがまだある!」
→ データの不整合 💥
4️⃣
解決:RefreshCacheの実行
RefreshCache APIを呼び出すと、Storage Gatewayが
S3の最新状態をチェックしてキャッシュを更新!
→ 同期完了! ✨

RefreshCacheを自動化する3つの方法

方法1: Lambda + S3イベント
S3にファイルがアップロードされた 瞬間 にLambdaが起動してRefreshCacheを実行
✅ メリット: • リアルタイム反映
• 設定が簡単
• コスト効率が高い
• イベント駆動型
⚠️ 注意点: • S3イベントの設定必要
• 大量ファイルで課金増
方法2: Lambda + EventBridge
🔄 柔軟
EventBridgeで 定期的 (例:5分ごと)にLambdaを起動してRefreshCacheを実行
✅ メリット: • スケジュール制御可能
• シンプルな構成
• 予測可能なコスト
• バッチ処理向き
⚠️ 注意点: • リアルタイム性は低い
• 不要な実行も発生
🔀
方法3: Step Functions
⚙️ 高度
Step Functionsで複雑なワークフローを構築。リトライやエラーハンドリングを含む処理
✅ メリット: • 複雑なロジック対応
• エラーハンドリング充実
• 可視化が容易
• 条件分岐が可能
⚠️ 注意点: • 設定が複雑
• コストがやや高い
• オーバーエンジニア注意

🛠️ 実装手順:Lambda + S3イベント(推奨)

1
IAMロールの作成
Lambda用のIAMロールを作成して、必要な権限を付与します。

必要な権限:
• Storage Gatewayへのアクセス権限
• CloudWatch Logsへの書き込み権限
📄 IAMポリシー(JSON)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "storagegateway:RefreshCache",
        "storagegateway:DescribeNFSFileShares",
        "storagegateway:DescribeSMBFileShares"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}
2
Lambda関数の作成
RefreshCacheを実行するLambda関数を作成します。
Python 3.12でシンプルに実装できます。
🐍 Lambda関数(Python)
import boto3
import json
import os

# Storage Gatewayクライアントの初期化
sgw_client = boto3.client('storagegateway')

def lambda_handler(event, context):
    # 環境変数からFile Share ARNを取得
    file_share_arn = os.environ['FILE_SHARE_ARN']
    
    try:
        # S3イベントから情報を取得
        s3_bucket = event['Records'][0]['s3']['bucket']['name']
        s3_key = event['Records'][0]['s3']['object']['key']
        
        print(f"S3イベント検知: バケット={s3_bucket}, キー={s3_key}")
        
        # RefreshCacheを実行
        response = sgw_client.refresh_cache(
            FileShareARN=file_share_arn,
            FolderList=['/']  # ルートから全て更新
        )
        
        print(f"RefreshCache実行成功: {response}")
        
        return {
            'statusCode': 200,
            'body': json.dumps({
                'message': 'RefreshCache completed successfully',
                'file_share_arn': file_share_arn,
                's3_object': f"s3://{s3_bucket}/{s3_key}"
            })
        }
        
    except Exception as e:
        print(f"エラー発生: {str(e)}")
        raise e
💡 環境変数の設定を忘れずに!
Lambda関数の環境変数に FILE_SHARE_ARN を設定してください。
例: arn:aws:storagegateway:ap-northeast-1:123456789012:share/share-XXXXXXXX
3
S3イベント通知の設定
S3バケットのプロパティから、イベント通知を設定します。

設定項目:
• イベントタイプ:「すべてのオブジェクト作成イベント」を選択
• 送信先:Lambda関数を選択
• プレフィックス/サフィックス:必要に応じて設定
📄 S3イベント通知設定(AWS CLI)
# Lambda関数にS3からの呼び出し権限を付与
aws lambda add-permission \
  --function-name RefreshCacheFunction \
  --statement-id s3-trigger-permission \
  --action lambda:InvokeFunction \
  --principal s3.amazonaws.com \
  --source-arn arn:aws:s3:::your-bucket-name

# S3バケットにイベント通知を設定
aws s3api put-bucket-notification-configuration \
  --bucket your-bucket-name \
  --notification-configuration file://notification.json
📄 notification.json
{
  "LambdaFunctionConfigurations": [
    {
      "LambdaFunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:RefreshCacheFunction",
      "Events": [
        "s3:ObjectCreated:*",
        "s3:ObjectRemoved:*"
      ]
    }
  ]
}
4
動作テストと監視
テスト手順:
1️⃣ S3バケットに直接ファイルをアップロード
2️⃣ CloudWatch LogsでLambda実行を確認
3️⃣ Storage Gateway経由でファイルが見えるか確認

監視ポイント:
• Lambda実行回数
• エラー率
• 実行時間
• RefreshCacheの成功/失敗

🏗️ 全体アーキテクチャ

👤
ユーザー/アプリ
S3に直接
アップロード
🪣
S3バケット
ファイル保存
イベント発行
Lambda関数
イベント受信
RefreshCache実行
🚪
Storage Gateway
キャッシュ更新
最新状態に同期
💻
オンプレミス
最新ファイルに
アクセス可能

⏰ 実装パターン2:EventBridge定期実行

「毎朝9時に実行」「5分おきに実行」など、スケジュールベースで実行したい場合はこちら

🐍 Lambda関数(スケジュール実行用)
import boto3
import json
import os
from datetime import datetime

sgw_client = boto3.client('storagegateway')

def lambda_handler(event, context):
    # 環境変数から複数のFile Share ARNを取得(カンマ区切り)
    file_share_arns = os.environ['FILE_SHARE_ARNS'].split(',')
    
    results = []
    
    for file_share_arn in file_share_arns:
        file_share_arn = file_share_arn.strip()
        
        try:
            print(f"RefreshCache開始: {file_share_arn}")
            
            # RefreshCacheを実行
            response = sgw_client.refresh_cache(
                FileShareARN=file_share_arn,
                FolderList=['/'],
                Recursive=True
            )
            
            results.append({
                'file_share_arn': file_share_arn,
                'status': 'success',
                'notification_id': response.get('NotificationId')
            })
            
            print(f"RefreshCache成功: {file_share_arn}")
            
        except Exception as e:
            results.append({
                'file_share_arn': file_share_arn,
                'status': 'failed',
                'error': str(e)
            })
            print(f"RefreshCache失敗: {file_share_arn} - {str(e)}")
    
    return {
        'statusCode': 200,
        'body': json.dumps({
            'timestamp': datetime.now().isoformat(),
            'results': results
        })
    }
📄 EventBridgeルール(AWS CLI)
# 5分おきに実行する場合
aws events put-rule \
  --name RefreshCacheSchedule \
  --schedule-expression "rate(5 minutes)" \
  --state ENABLED

# 毎日午前9時(JST)に実行する場合
aws events put-rule \
  --name RefreshCacheDailyAt9AM \
  --schedule-expression "cron(0 0 * * ? *)" \
  --state ENABLED

# Lambdaをターゲットに追加
aws events put-targets \
  --rule RefreshCacheSchedule \
  --targets "Id"="1","Arn"="arn:aws:lambda:ap-northeast-1:123456789012:function:RefreshCacheFunction"

💼 シナリオ別:どの方法を選ぶ?

📸

監視カメラ映像の保存

シナリオ:
監視カメラの映像が24時間365日S3にアップロードされ、オンプレミスから即座に確認したい。

推奨方法:
Lambda + S3イベント

理由:
• ファイルアップロード直後に自動実行
• リアルタイム性が重要
• イベント駆動で効率的
📊

日次レポートの配信

シナリオ:
毎日深夜にバッチ処理でレポートをS3にアップロード。翌朝9時に社員が確認する。

推奨方法:
Lambda + EventBridge

理由:
• 毎朝8:30に実行すれば十分
• スケジュール管理が簡単
• コストが予測可能
🏥

医療画像の共有

シナリオ:
複数の病院からMRI画像がS3にアップロード。データの整合性とトレーサビリティが最重要。

推奨方法:
Step Functions

理由:
• エラー時の詳細なログ記録
• リトライ機構が必須
• コンプライアンス対応
🎬

動画編集素材の同期

シナリオ:
クラウドとオンプレミスの編集環境で大容量の動画素材を共有。ファイルサイズが大きい。

推奨方法:
Lambda + S3イベント
+ FolderList指定で特定フォルダのみ

理由:
• 大容量ファイルは即座に反映
• FolderListで更新範囲を限定
• ネットワーク負荷を最小化

🔧 よくある問題と解決策

❌ 問題1: Lambda実行後もファイルが見えない

症状:
RefreshCacheは成功しているのに、オンプレミスから新しいファイルが見えない
✅ 解決策:
待機時間: RefreshCacheは非同期処理。完了まで数分かかる場合あり
FolderList確認: FolderListで正しいパスを指定しているか確認
再マウント: クライアント側でNFS/SMB共有を再マウント
キャッシュクリア: OSレベルのキャッシュもクリア

❌ 問題2: Lambdaが権限エラーで失敗

症状:
AccessDenied または UnauthorizedException エラーが発生
✅ 解決策:
IAMロール確認: storagegateway:RefreshCache 権限があるか
リソースポリシー: 特定のFile Shareに限定している場合はARNを確認
信頼関係: Lambda実行ロールの信頼関係を確認

❌ 問題3: S3イベントが発火しない

症状:
S3にファイルをアップロードしてもLambdaが起動しない
✅ 解決策:
イベント設定確認: S3バケットのイベント通知設定を確認
Lambda権限: S3からLambdaを呼び出す権限があるか確認
プレフィックス/サフィックス: フィルター条件に合致しているか
既存の設定: 同じイベントに複数の通知設定がないか確認

❌ 問題4: コストが想定より高い

症状:
Lambda実行回数が多すぎてコストが膨らんでいる
✅ 解決策:
イベントフィルタリング: S3イベントにプレフィックスを設定して不要なイベントを除外
バッチ処理化: EventBridgeで定期実行に変更を検討
FolderList最適化: 全体ではなく必要なフォルダのみRefresh
Recursive設定: Recursive=Falseで浅い階層のみ更新

❌ 問題5: 大量ファイルで処理が重い

症状:
数万ファイルがあり、RefreshCacheに時間がかかりすぎる
✅ 解決策:
FolderList分割: 複数のLambda実行で異なるフォルダを並列処理
段階的更新: 重要なフォルダを優先的に更新
スケジュール調整: アクセスの少ない時間帯に実行
TTL調整: Gateway側のキャッシュTTLを調整して更新頻度を減らす
💡 RefreshCache自動化のベストプラクティス
1. 適切な更新範囲の設定:
全体を更新するのではなく、 FolderList で変更があった部分だけを指定しましょう。処理時間とコストを大幅削減できます。

2. エラーハンドリングとリトライ:
一時的なネットワークエラーなどに備えて、Lambda関数にリトライロジックを実装しましょう。Step Functionsを使えば自動リトライが可能です。

3. CloudWatch監視の設定:
RefreshCacheの成功/失敗をCloudWatchアラームで監視し、問題発生時にすぐに気づけるようにしましょう。

4. コスト最適化:
• 本当にリアルタイム更新が必要か再検討
• 定期実行で十分なら EventBridge を活用
• S3イベントフィルターで不要なイベントを除外

5. セキュリティ考慮:
• IAMロールは最小権限の原則で設定
• CloudTrailでRefreshCache実行履歴を記録
• 本番環境では環境変数を暗号化

6. テストとドキュメント:
• 本番適用前に必ず検証環境でテスト
• 設定内容とトラブルシューティング手順をドキュメント化
• 定期的な動作確認を実施

🎓 まとめ

📚 図書館の在庫リスト = RefreshCache

S3(本棚)に直接追加された本を
Storage Gateway(カウンター)の在庫リスト(キャッシュ)に
自動的に反映させる仕組み = RefreshCache自動化✨

リアルタイム

Lambda + S3イベント
アップロード直後に
即座に反映
スケジュール

Lambda + EventBridge
決まった時間に
定期実行
🔀
高度な制御

Step Functions
複雑なワークフロー
エラー処理充実

🎯 選択の基準:

迷ったら → Lambda + S3イベント

定期実行で十分 → Lambda + EventBridge

複雑な要件 → Step Functions

RefreshCacheの自動化で、
オンプレミスとクラウドの 完璧な同期 を実現!
もう手動更新に悩まされることはありません!🎉

Created by SSuzuki1063

AWS SAP Learning Resources