本教程介绍如何使用 Cloud Scheduler 和 Cloud Functions,自动将 Memorystore for Redis 数据库导出到 Cloud Storage。通过将数据库导出到 Cloud Storage,您可以创建可靠且多样的灾难恢复计划。例如,您可以导出到其他地区,并导入到其他 Memorystore for Redis 实例。
架构
本教程涉及以下 Google Cloud 组件:
- Cloud Scheduler 作业:根据设置的时间表进行调用以启动数据库导出的作业。
- Cloud Functions 函数:用于将数据从 Memorystore 导出到 Cloud Storage 的函数。
- Pub/Sub 消息:针对每个数据导出事件发送和接收的消息。
- Cloud Storage 存储分区:用于存储导出数据的存储分区。
- Memorystore for Redis:要从中导出数据的源数据库。
Cloud Scheduler 作业在 Pub/Sub 主题上发布一条消息,其中包含有关 Memorystore 实例 ID、项目 ID、它所在的地区以及用于存储备份的 Cloud Storage 位置的信息。此事件会触发 Cloud Functions 函数,该函数获取此载荷并通过其 API 在 Memorystore for Redis 上启动数据库导出。数据库会生成导出并将其保存到 Cloud Storage。下图展示了此工作流。
目标
- 创建 Cloud Storage 存储分区和 Memorystore 实例。
- 创建 Pub/Sub 主题、Cloud Functions 函数和 Cloud Scheduler 作业。
- 通过手动运行 Cloud Scheduler 作业来触发数据库数据导出。
费用
本教程使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用量来估算费用。 Google Cloud 新用户可能有资格申请免费试用。
完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理。
准备工作
-
在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能。
-
在 Cloud Console 中,激活 Cloud Shell。
- 启用 Memorystore for Redis、Cloud Functions、Cloud Scheduler、App Engine API。
在本教程中,您将通过 Cloud Shell 运行所有命令。
设置您的环境
首先,先配置环境,然后创建具有本教程所需权限的自定义角色。
在 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"
创建两个仅具有本教程所需权限的自定义角色:
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 的权限。
创建一个 Memorystore for Redis 4 实例:
gcloud redis instances create ${MEM_INSTANCE} --size=1 --region=${REGION}
此操作需要几分钟时间才能完成。
验证 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
使用 Simple Storage 角色向您的 Memorystore 服务帐号授予将数据导出到 Cloud Storage 的权限:
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 角色。
创建 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)")
向 Cloud Functions 函数服务帐号授予对自定义 Redis 角色的访问权限:
gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${GCF_SA}" \ --role="projects/${PROJECT_ID}/roles/${MEM_ROLE}"
向 Cloud Functions 函数服务帐号授予对自定义 Storage 角色的访问权限:
gsutil iam ch \ serviceAccount:${GCF_SA}:projects/${PROJECT_ID}/roles/${STORAGE_ROLE} \ gs://${BUCKET_NAME}
创建 Pub/Sub 主题
下一步是创建一个 Pub/Sub 主题,用于触发与 Memorystore 数据库交互的 Cloud Functions 函数。
创建 Pub/Sub 主题:
gcloud pubsub topics create ${PUBSUB_TOPIC}
创建 Cloud Functions 函数
接下来,您将创建 Cloud Functions 函数。
为 Cloud Functions 函数代码创建文件夹:
mkdir scheduler_gcf_code && cd scheduler_gcf_code
通过将以下内容粘贴到 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
通过将以下内容粘贴到 Cloud Shell 中来创建
requirements.txt
文件:cat <<EOF > requirements.txt google-api-python-client Oauth2client EOF
部署代码。如果系统询问您是否要允许对新函数进行未经身份验证的调用,请回答
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 作业以定期执行数据导出函数。
为 Cloud Scheduler 作业创建 App Engine 实例:
gcloud app create --region=${REGION::-1}
将 Memorystore 完整名称保存到变量中:
export MEM_NAME=$(gcloud redis instances describe ${MEM_INSTANCE} --region ${REGION} --format "value(name)")
创建一个 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 作业。
手动运行 Cloud Scheduler 作业以触发数据库的 Memorystore 导出。
gcloud scheduler jobs run ${SCHEDULER_JOB}
列出在 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
检查 Cloud Storage 存储分区,以查看导出文件是否已创建:
gsutil ls gs://${BUCKET_NAME} | grep rdb
在上一步的
STATUS
操作返回DONE
之后,您会看到一个名为backup-mem-timestamp.rdb
的文件。
清理
您可以按照以下步骤操作,以避免系统因本教程中使用的资源而向您的 Google Cloud 帐号收取费用。为避免支付费用,最简单的方法是删除您为本教程创建的项目。
- 在 Cloud Console 中,转到管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。
后续步骤
- 了解如何使用 Cloud Scheduler 安排计算实例。
- 了解如何使用 Cloud Scheduler 安排 Cloud SQL 数据库导出。
- 试用其他 Google Cloud 功能。查阅我们的教程。