Cloud Scheduler を使用した Memorystore for Redis データベース エクスポートのスケジューリング

このチュートリアルでは、Cloud SchedulerCloud Functions を使用して、Memorystore for Redis データベースを Cloud Storage に自動的にエクスポートする方法を説明します。データベースを Cloud Storage にエクスポートすると、堅牢で多様な障害復旧計画を作成できます。たとえば、別のリージョンへのエクスポートや、他の Memorystore for Redis インスタンスへのインポートが行えます。

アーキテクチャ

このチュートリアルでは、次の Google Cloud コンポーネントを使用します。

Cloud Scheduler ジョブは、Memorystore インスタンス ID、プロジェクト ID、配置されているリージョン、バックアップを保存する Cloud Storage のロケーションに関する情報を含むメッセージを Pub/Sub トピックに送信します。このイベントにより Cloud Functions の関数がトリガーされてペイロードが取得され、API を介して Memorystore for Redis でデータベースのエクスポートが開始されます。データベースでエクスポートが生成され、Cloud Storage に保存されます。次の図は、このワークフローを示しています。

Cloud Scheduler から Pub/Sub へのワークフロー。これにより、エクスポートを開始する Cloud Functions の関数がトリガーされます。

目標

費用

このチュートリアルでは、課金対象である次の Google Cloud コンポーネントを使用します。

料金計算ツールを使用すると、予想使用量に基づいて費用の見積もりを算出できます。新しい Google Cloud ユーザーは無料トライアルをご利用いただけます。

このチュートリアルを終了した後、作成したリソースを削除すると、それ以上の請求は発生しません。詳しくは、クリーンアップをご覧ください。

始める前に

  1. Google Cloud Console の [プロジェクト セレクタ] ページで、Google Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタに移動

  2. Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  3. Cloud Console で、Cloud Shell をアクティブにします。

    Cloud Shell をアクティブにする

  4. Memorystore for Redis、Cloud Functions、Cloud Scheduler、App Engine API を有効にします。

    API を有効にする

このチュートリアルでは、Cloud Shell からすべてのコマンドを実行します。

環境設定

まず、環境を構成してから、このチュートリアルに必要な権限を持つカスタムロールを作成します。

  1. Cloud Shell で、次の環境変数を構成します。

    export PROJECT_ID=`gcloud config get-value project`
    export DEMO="mem-exporter"
    export BUCKET_NAME=${USER}-mem-$(date +%s)
    export MEM_INSTANCE="${DEMO}-instance"
    export GCF_NAME="${DEMO}-gcf"
    export PUBSUB_TOPIC="${DEMO}-topic"
    export SCHEDULER_JOB="${DEMO}-job"
    export MEM_ROLE="memExporter"
    export STORAGE_ROLE="simpleStorageRole"
    export REGION="us-central1"
    
  2. このチュートリアルで必要な権限のみを持つ 2 つのカスタムロールを作成します。

    gcloud iam roles create ${STORAGE_ROLE} --project=${PROJECT_ID} \
        --title="Simple Storage Role" \
        --description="Grant permissions to view and create objects in Cloud Storage" \
        --permissions="storage.objects.create,storage.buckets.get"
    
    gcloud iam roles create ${MEM_ROLE} --project=${PROJECT_ID} \
        --title="Memorystore Exporter Role" \
        --description="Grant permissions to export data from a Memorystore instance to a Cloud Storage bucket" \
        --permissions="redis.instances.export"
    

    これらのロールは、最小権限の原則に従い、Cloud Functions と Memorystore サービス アカウントのアクセス範囲を制限します。

Cloud Storage バケットと Memorystore インスタンスの作成

このセクションでは、まず Cloud Storage バケットと Memorystore for Redis インスタンスを作成します。次に、Memorystore にサンプルデータを追加します。

Cloud Storage バケットの作成

gsutil コマンドライン ツールを使用して Cloud Storage バケットを作成します。

  • エクスポートしたデータを保存する Cloud Storage バケットを作成します。

    gsutil mb -l ${REGION} gs://${BUCKET_NAME}
    

Memorystore インスタンスを作成し、そのサービス アカウントに権限を付与する

次に、Memorystore インスタンスを作成し、そのサービス アカウントに Cloud Storage にデータをエクスポートする権限を付与します。

  1. Memorystore for Redis 4 インスタンスを作成します。

    gcloud redis instances create ${MEM_INSTANCE} --size=1 --region=${REGION}
    

    この処理が完了するまでに数分かかります。

  2. Memorystore インスタンスが READY であることを確認します。

    gcloud redis instances list --region=${REGION}
    

    出力は次のようになります。

    INSTANCE_NAME   VERSION    REGION       TIER   SIZE_GB  HOST          PORT  NETWORK  RESERVED_IP      STATUS  CREATE_TIME
    redis-instance  REDIS_4_0  us-central1  BASIC  1        10.61.20.131  6379  default  10.61.20.128/29  READY   2020-04-23T18:38:54
    
  3. Simple Storage ロールで Cloud Storage にデータをエクスポートするように、Memorystore サービス アカウントに権限を付与します。

    export MEM_SA=$(gcloud redis instances describe ${MEM_INSTANCE} --region ${REGION} \
        --project ${PROJECT_ID} \
        --format "value(persistenceIamIdentity)")
    
    gsutil iam ch ${MEM_SA}:projects/${PROJECT_ID}/roles/${STORAGE_ROLE} gs://${BUCKET_NAME}
    

Pub/Sub トピック、Cloud Functions の関数、Cloud Scheduler ジョブの作成

このセクションでは、カスタム サービス アカウントを作成して、作成したカスタム Redis ロールにバインドします。次に、Cloud Functions の関数の実行をトリガーする Pub/Sub トピックを作成します。また、データのエクスポートを定期的に行う Cloud Scheduler ジョブも作成します。

Cloud Functions の関数のサービス アカウントを作成する

最初の手順では、カスタム サービス アカウントを作成し、作成したカスタム Redis ロールにバインドします。

  1. Cloud Functions の関数が使用する IAM サービス アカウントを作成し、変数に保存します。

    gcloud iam service-accounts create ${GCF_NAME} \
        --display-name="Service Account for GCF and Memorystore"
    
    export GCF_SA=$(gcloud iam service-accounts list --filter="${GCF_NAME}" --format="value(email)")
    
  2. Cloud Functions の関数サービス アカウントにカスタム Redis ロールへのアクセス権を付与します。

    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member="serviceAccount:${GCF_SA}" \
        --role="projects/${PROJECT_ID}/roles/${MEM_ROLE}"
    
  3. Cloud Functions の関数サービス アカウントにカスタム Storage ロールへのアクセス権を付与します。

    gsutil iam ch \
        serviceAccount:${GCF_SA}:projects/${PROJECT_ID}/roles/${STORAGE_ROLE} \
        gs://${BUCKET_NAME}
    

Pub/Sub トピックを作成する

次の手順では、Memorystore データベースとやり取りする Cloud Functions の関数のトリガーに使用される Pub/Sub トピックを作成します。

  • Pub/Sub トピックを作成します。

    gcloud pubsub topics create ${PUBSUB_TOPIC}
    

Cloud Function を作成する

次に、Cloud Functions の関数を作成します。

  1. Cloud Functions の関数のコード用のフォルダを作成します。

    mkdir scheduler_gcf_code && cd scheduler_gcf_code
    
  2. Cloud Shell に次のコードを貼り付けて main.py ファイルを作成します。

    cat <<EOF  > main.py
    
    import base64
    import logging
    import json
    
    from datetime import datetime
    from httplib2 import Http
    
    from googleapiclient import discovery
    from googleapiclient.errors import HttpError
    from oauth2client.client import GoogleCredentials
    
    def main(event, context):
        pubsub_message = json.loads(base64.b64decode(event['data']).decode('utf-8'))
        credentials = GoogleCredentials.get_application_default()
    
        service = discovery.build('redis', 'v1beta1', http=credentials.authorize(Http()), cache_discovery=False)
    
        datestamp = datetime.now().strftime("%Y%m%d%H%M") # format timestamp: YearMonthDayHourMinute
        uri = f"{pubsub_message['gs']}/backup-{datestamp}.rdb"
    
        request_body = {
            "outputConfig": {
                "gcsDestination" : {
                    "uri": uri
                }
            }
        }
    
        try:
            request = service.projects().locations().instances().export(
                name=pubsub_message['name'],
                body=request_body
            )
    
            response = request.execute()
        except HttpError as err:
            logging.error(f"Could NOT run backup. Reason: {err}")
        else:
            logging.info(f"Backup task status: {response}")
    EOF
    
  3. Cloud Shell に次のコードを貼り付けて requirements.txt ファイルを作成します。

    cat <<EOF > requirements.txt
    
    google-api-python-client
    Oauth2client
    EOF
    
  4. コードをデプロイします。新しい関数の未認証呼び出しを許可するかどうかを確認するメッセージが表示されたら、no を選択します。

    gcloud functions deploy ${GCF_NAME} \
        --trigger-topic=${PUBSUB_TOPIC} \
        --runtime=python37 \
        --entry-point=main \
        --service-account=${GCF_NAME}@${PROJECT_ID}.iam.gserviceaccount.com
    

Cloud Scheduler ジョブを作成する

最後に、データのエクスポートを定期的に行う Cloud Scheduler ジョブを作成します。

  1. Cloud Scheduler ジョブの App Engine インスタンスを作成します。

    gcloud app create --region=${REGION::-1}
    
  2. Memorystore の完全名を変数に保存します。

    export MEM_NAME=$(gcloud redis instances describe ${MEM_INSTANCE} --region ${REGION} --format "value(name)")
    
  3. データのエクスポートを定期的に行う Cloud Scheduler ジョブを作成します。

    gcloud scheduler jobs create pubsub ${SCHEDULER_JOB} \
        --schedule='0 23 * * *' --topic=${PUBSUB_TOPIC} \
        --message-body='{"name":'\"${MEM_NAME}\"',"gs":'\"gs://${BUCKET_NAME}\"'}' \
        --time-zone='America/Los_Angeles'
    

    このジョブは毎日午後 11 時に実行されるようにスケジューリングされています。

ソリューションのテスト

最後に、ソリューションをテストします。まず、Cloud Scheduler ジョブを実行します。

  1. Cloud Scheduler ジョブを手動で実行して、データベースの Memorystore エクスポートをトリガーします。

    gcloud scheduler jobs run ${SCHEDULER_JOB}
    
  2. Memorystore インスタンスで実行されたオペレーションを一覧表示し、EXPORT 型のオペレーションがあることを確認します。

    gcloud redis operations list --region=${REGION} --filter="${MEM_INSTANCE}"
    

    出力には、完了したエクスポート ジョブが表示されます。次に例を示します。

    OPERATION_NAME                                           REGION       TYPE    TARGET                 DONE  CREATE_TIME          DURATION
    operation-1592329364987-5a837122a600c-b22c2703-5077c6b7  us-central1  export  mem-exporter-instance  True  2020-06-16T17:42:45  16S
    
  3. Cloud Storage バケットをチェックして、エクスポート ファイルが作成されているかどうかを確認します。

    gsutil ls gs://${BUCKET_NAME} | grep rdb
    

    前の手順の STATUS オペレーションで DONE が返された後、backup-mem-timestamp.rdb という名前のファイルが表示されます。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、次の手順に従います。課金を停止する最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

次のステップ