本教程介绍如何使用 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 Console 中的项目选择器页面上,选择或创建一个 Google Cloud 项目。
-
在 Google Cloud 控制台中,激活 Cloud Shell。
-
启用 Memorystore for Redis, Cloud Functions, Cloud Scheduler, and Cloud Build 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 FUNCTION_NAME="${DEMO}-gcf" export PUBSUB_TOPIC="${DEMO}-topic" export SCHEDULER_JOB="${DEMO}-job" export MEM_EXPORT_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_EXPORT_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}
创建计划的数据导出任务
在本部分中,您将创建一个自定义服务账号并将其绑定到您创建的自定义 Redis 角色。然后,您将创建一个用于触发 Cloud Functions 函数执行的 Pub/Sub 主题。您还将创建一个 Cloud Scheduler 作业以定期执行数据导出函数。
为 Cloud Functions 函数创建服务账号
第一步是创建服务账号并将其绑定到角色。
创建 Cloud Functions 函数要使用的 IAM 服务账号并将其保存到变量中:
gcloud iam service-accounts create ${FUNCTION_NAME} \ --display-name="Service Account for GCF and Memorystore" export GCF_SA=$(gcloud iam service-accounts list --filter="${FUNCTION_NAME}" --format="value(email)")
向服务账号授予访问自定义
Memorystore Exporter
角色的权限,使其能够请求 Memorystore 导出:gcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="serviceAccount:${GCF_SA}" \ --role="projects/${PROJECT_ID}/roles/${MEM_EXPORT_ROLE}"
向服务账号授予自定义
Simple 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 instance_name=pubsub_message['name'].split("/")[-1] uri = f"{pubsub_message['gs']}/backup-{instance_name}-{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
部署代码。
gcloud functions deploy ${FUNCTION_NAME} \ --trigger-topic=${PUBSUB_TOPIC} \ --runtime=python37 \ --entry-point=main \ --service-account=${FUNCTION_NAME}@${PROJECT_ID}.iam.gserviceaccount.com \ --ingress-settings=internal-and-gclb
创建 Cloud Scheduler 作业
最后,您将创建一个 Cloud Scheduler 作业以定期执行数据导出函数。
将 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' --location=${REGION}
此作业安排在每天晚上 11 点(太平洋时间)运行。
消息正文包含要导出的 Memorystore 实例的名称,以及目标 Cloud Storage 存储桶。
测试您的解决方案
最后一步是测试您的解决方案。首先,您需要运行 Cloud Scheduler 作业。
手动运行 Cloud Scheduler 作业以触发数据库的 Memorystore 导出。
gcloud scheduler jobs run ${SCHEDULER_JOB} --location=${REGION}
列出在 Memorystore 实例上执行的操作,并验证是否存在类型为
EXPORT
的操作:gcloud redis operations list --region=${REGION} --filter="${MEM_INSTANCE}"
以下输出示例显示
DONE
状态为True
的导出作业,以指示其已完成。如果DONE
状态显示False
,则表示作业仍在处理;请等待一分钟,然后重新运行上一个命令。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 -l gs://${BUCKET_NAME}/*.rdb
您会看到一个名为
backup-INSTANCE_NAME-TIMESTAMP.rdb
的文件。
清理
您可以按照以下步骤操作,以避免系统因本教程中使用的资源而向您的 Google Cloud 账号收取费用。为避免支付费用,最简单的方法是删除您为本教程创建的项目。
- 在 Google Cloud 控制台中,进入管理资源页面。
- 在项目列表中,选择要删除的项目,然后点击删除。
- 在对话框中输入项目 ID,然后点击关闭以删除项目。
后续步骤
- 了解如何使用 Cloud Scheduler 安排计算实例。
- 了解如何使用 Cloud Scheduler 安排 Cloud SQL 数据库导出。
- 探索有关 Google Cloud 的参考架构、图表和最佳做法。查看我们的 Cloud Architecture Center。