通过阿里云OOS实现定时备份redis实例转储到OSS

功能背景

随着企业业务数据的快速增长,Redis 作为高性能的内存数据存储方案,在多种应用场景下承担着重要的角色。为确保数据安全,定时备份成为了不可或缺的一环。Redis 实例定时备份是关键数据库管理任务的一个重要组成部分,它主要服务于数据的灾难恢复、历史数据

查询、环境克隆等应用场景。

然而,在目前的 Redis 的备份方案中,虽然支持定时备份功能,可以根据用户的业务需求,设置备份周期进行自动备份。但此方式存在以下不足:

  • 数据安全风险:在实例删除后,传统的定时备份无法保留备份数据,导致数据不能永久保存,存在数据丢失的风险。
  • 运维工作繁琐:缺少自动化的备份转储机制,需要手动操作备份过程,包括下载和上传至云存储服务,这一流程不仅耗时,同时也容易出错。
  • 运维成本增加:由于备份流程需要人工介入,过程中容易出错,需要额外的时间和资源投入,从而增加了整体的运维成本。
  • 效率较低:在没有集中管理的备份方案前,为多个实例或跨地域实例执行备份时,效率相对偏低,管理复杂度高。
  • 监控及告警能力不足:缺乏有效的监控和告警机制,使得备份任务的执行状态难以实时掌握,一旦出现失败或异常问题,及时响应和处理的能力受限。

针对上述不足,结合 OOS 的编排能力,OOS 推出了定时备份 Redis 实例并自动转储至 OSS 的功能,为用户提供了一个高效、安全且自动化的备份解决方案。

此方案有以下优势

  1. 数据安全性提高:通过自动上传备份文件至 OSS , 利用 OSS 的数据冗余存储机制, 确保硬件失效时的数据持久性和可用性;此外,及时 Redis 实例删除也能永久保存。
  2. 完全自动化:一旦配置完成,备份文件将自动、定时上传到 OSS,无需人工干预,大大减轻了运维负担,降低了操作错误。
  3. 多实例多地域集中管理:OOS 定时备份 Redis 任务支持一次选择多个实例。此外,OOS 支持跨区域转储 OSS,您可以将多个地域的 Redis 实例统一备份到同一 OSS 存储桶中。
  4. 灵活的备份策略和成本控制:用户可以根据自己的需要设置备份频率,通过 OSS 的生命周期管理策略,自动清理过期的备份文件,从而更有效地控制成本。
  5. 监控和告警:结合 OSS 和云监控,用户可以实时监控备份状态,一旦备份失败或有其他问题,可以及时收到告警,确保数据的安全性。

操作步骤

注意事项:

此功能使用过程中可能会产生部分费用,计费详情参考 Redis 备份费用说明函数计算计费说明

  1. 登录 OOS 控制台

  2. 在左侧导航栏找到 "自动化任务-定时运维 ",单击创建

  3. 设置定时规则 。这里定时类型有 "立即执行、仅在指定时间执行一次、周期性重复执行" 三种方式。其中 "立即执行" 会在创建任务后立即进行重启操作, "仅在指定时间执行一次" 只会在您设定的某个时间点执行一次, "周期性重复执行" 则会按照一定的规则重复执行,如每一小时执行一次。

    这里我们选择 "周期性重复执行 ",可以通过 "快速选择 " 设置重复的频率,熟悉 cron 表达式的同学也可以通过 cron 表达式进行设置。本教程通过 "快速选择" 设置重复的频率,设置每小时执行一次,之后单击确定

    设置定时任务的结束时间。

  4. 搜索模板 "ACS-Redis-BulkyCreateBackupAndUploadToOSS",然后进行勾选。

  5. 接下来选择要进行备份的实例,首先选择实例所在地域,然后选择目标实例,点击确定。

  6. 选择要转储的 OSS 存储桶。

  7. 配置执行任务所需的 RAM 角色:

    • 创建 OOS 编排 OpenAPI 角色,可参考《为 OOS 服务设置 RAM 权限》配置 OOS 所需的 RAM 角色并授权,权限策略如下:

      json 复制代码
      {
          "Version": "1",
          "Statement": [
              {
                  "Action": [
                      "kvstore:CreateBackup",
                      "kvstore:DescribeBackupTasks",
                      "kvstore:DescribeBackups",
                      "kvstore:DescribeInstances"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
              },
              {
                  "Action": [
                      "ros:CreateStack",
                      "ros:DeleteStack",
                      "ros:GetStack"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
              },
              {
                  "Action": "oos:StartExecution",
                  "Resource": "*",
                  "Effect": "Allow"
              },
              {
                  "Action": [
                      "fc:CreateFunction",
                      "fc:CreateService",
                      "fc:DeleteFunction",
                      "fc:DeleteService",
                      "fc:GetFunction",
                      "fc:GetService",
                      "fc:InvokeFunction"
                  ],
                  "Resource": "*",
                  "Effect": "Allow"
              },
              {
                  "Condition": {
                      "StringEquals": {
                          "acs:Service": "fc.aliyuncs.com"
                      }
                  },
                  "Action": "ram:PassRole",
                  "Resource": "*",
                  "Effect": "Allow"
              }
          ]
      }
    • 创建个通过函数计算下载备份文件所需要的角色,可点击角色快捷创建配置 FC 所需的 RAM 角色(AliyunFCDefaultRole)进行快速创建。

  8. 点击 "创建" -> "确定",定时备份转储到 OSS 的任务就创建完成了。

  9. 查看任务执行结果:

    a. 您可以等到到达您设定的触发时间来查看备份结果。

    b. 点击 "立即触发" 来执行备份转储任务查看结果。

    此时任务会进入运行中,可通过执行日志查看任务执行进度。

  10. 查看转储至 OSS 中的备份文件:

    等待执行状态变成 "已结束",可以点击执行 ID。

    点击子执行 ID。

    查看输出。

    此时登录此输出的地址就可以查看转存到 OSS 的备份文件了。

    备份文件存储目录格式为:

    Backup_[实例 ID]/[日期(格式为 YYYY-MM-DD)]/[OOS 备份任务 ID]/[备份文件名称].rdb`
    
    • 如果实例为非集群架构,则每次备份将产生 1 个 rdb 文件。
    • 如果实例为集群架构,由于每个分片将会独立备份,因此每次备份将产生与分片数量一致的 rdb 文件(例如 8 分片集群则每次产生 8 个 rdb 文件)。
    • 转储至 OSS 中的备份不再有自动清理时间,可根据需要保留或删除。

附录

执行流程图

整体执行流程图:

其中创建redis备份并上传到OSS流程:

模板

上述步骤中使用的模板"ACS-Redis-BulkyCreateBackupAndUploadToOSS"内容如下(模板链接):

yaml 复制代码
FormatVersion: OOS-2019-06-01
Description:
  en: Create Redis backups in batches and upload them to OSS. Backing up redis and using fc to upload the backup to OSS may incur charges. For billing details, please refer to <a href='https://help .aliyun.com/zh/redis/user-guide/automatic-or-manual-backup#e606eb29c7mew'>Redis Backup Fee Instructions</a> and <a href='https://help.aliyun.com/zh/ fc/product-overview/billing-overview'>Function calculation billing instructions</a>
  zh-cn: 批量创建Redis备份并上传到OSS。备份redis和使用fc将备份上传到oss都可能会产生费用,计费详情参考<a href='https://help.aliyun.com/zh/redis/user-guide/automatic-or-manual-backup#e606eb29c7mew'>Redis备份费用说明</a>和<a href='https://help.aliyun.com/zh/fc/product-overview/billing-overview'>函数计算计费说明</a>
  name-en: ACS-Redis-BulkyCreateBackupAndUploadToOSS
  name-zh-cn: 批量创建Redis备份并上传到OSS
Parameters:
  regionId:
    Label:
      en: RegionId
      zh-cn: 地域ID
    Type: String
    AssociationProperty: RegionId
    Default: '{{ACS::RegionId}}'
  targets:
    Type: Json
    Label:
      en: TargetInstance
      zh-cn: 目标实例
    AssociationProperty: Targets
    AssociationPropertyMetadata:
      ResourceType: ALIYUN::Redis::Instance
      RegionId: regionId
  OSSRegionId:
    Label:
      en: OSSRegionId
      zh-cn: OSS Bucket所在地域ID
    Type: String
    AssociationProperty: RegionId
  OSSBucketName:
    Label:
      en: OSSBucketName
      zh-cn: OSS Bucket名称
    Type: String
    AssociationProperty: ALIYUN::OSS::Bucket::BucketName
    AssociationPropertyMetadata:
      RegionId: ${OSSRegionId}
  rateControl:
    Label:
      en: RateControl
      zh-cn: 任务执行的并发比率
    Type: Json
    AssociationProperty: RateControl
    Default:
      Mode: Concurrency
      MaxErrors: 0
      Concurrency: 10
  OOSAssumeRole:
    Label:
      en: OOSAssumeRole
      zh-cn: OOS扮演的RAM角色
    Type: String
    Default: ''
RamRole: '{{ OOSAssumeRole }}'
Tasks:
  - Name: GetInstance
    Description:
      en: Get the redis instances
      zh-cn: 获取Redis实例
    Action: ACS::SelectTargets
    Properties:
      ResourceType: ALIYUN::Redis::Instance
      RegionId: '{{ regionId }}'
      Filters:
        - '{{ targets }}'
    Outputs:
      InstanceIds:
        Type: List
        ValueSelector: Instances.Instance[].InstanceId
  - Name: CreateBackupAndUploadToOSS
    Action: ACS::Redis::CreateBackupAndUploadToOSS
    Description:
      en: Create backup and upload to OSS
      zh-cn: 创建Redis备份并上传到OSS
    Properties:
      regionId: '{{ regionId }}'
      instanceId: '{{ ACS::TaskLoopItem }}'
      OSSRegionId: '{{ OSSRegionId }}'
      OSSBucketName: '{{ OSSBucketName }}'
    Loop:
      RateControl: '{{ rateControl }}'
      Items: '{{ GetInstance.InstanceIds }}'
      Outputs:
        OSSObjectURLs:
          AggregateType: Fn::ListJoin
          AggregateField: OSSObjectURL
    Outputs:
      OSSObjectURL:
        Type: String
        ValueSelector: .OSSObjectURL + "{{ACS::ExecutionId}}/"  | split(".t0") | .[0]
Outputs:
  OSSObjectURLs:
    Type: List
    Value: '{{ CreateBackupAndUploadToOSS.OSSObjectURLs }}'

其中Action: ACS::Redis::CreateBackupAndUploadToOSS内容如下:

yaml 复制代码
FormatVersion: OOS-2019-06-01
Description:
 en: Create redis backup and upload to OSS
 zh-cn: 创建Redis备份并上传到OSS
 name-en: ACS::Redis::CreateBackupAndUploadToOSS
 name-zh-cn: 创建Redis备份并上传到OSS
Parameters:
 regionId:
   Label:
     en: RegionId
     zh-cn: 地域ID
   Type: String
   AssociationProperty: RegionId
 instanceId:
   Label:
     en: InstanceId
     zh-cn: 实例ID
   Type: String
   AssociationProperty: ALIYUN::Redis::Instance::InstanceId
   AssociationPropertyMetadata:
     RegionId: ${regionId}
 OSSRegionId:
   Label:
     en: OSSRegionId
     zh-cn: OSS bucket所在地域ID
   Type: String
   AssociationProperty: RegionId
 OSSBucketName:
   Label:
     en: OSSBucketName
     zh-cn: OSS Bucket 名称
   Type: String
   AssociationProperty: ALIYUN::OSS::Bucket::BucketName
   AssociationPropertyMetadata:
     RegionId: ${OSSRegionId}
   Default: ''
Tasks:
 - Name: CreateBackup
   Action: ACS::ExecuteApi
   Description:
     en: Create backup
     zh-cn: 创建Redis备份
   Properties:
     Service: r-kvstore
     API: CreateBackup
     Parameters:
       RegionId: '{{ regionId }}'
       InstanceId: '{{ instanceId }}'
   Outputs:
     BackupJobID:
       Type: String
       ValueSelector: .BackupJobID
 - Name: WaitForBackupCreated
   Action: ACS::WaitFor
   Description:
     en: Wait for backup created
     zh-cn: 等待备份创建完成
   Retries: 30
   DelayType: Exponential
   Delay: 2
   BackOff: 2
   Properties:
     Service: r-kvstore
     API: DescribeBackupTasks
     Parameters:
       RegionId: '{{ regionId }}'
       InstanceId: '{{ instanceId }}'
       BackupJobId: '{{ CreateBackup.BackupJobID }}'
     DesiredValues:
       - Finished
     NotDesiredValues: []
     StopRetryValues: []
     PropertySelector: .BackupJobs[].BackupProgressStatus
 - Name: GetBackupDownloadUrl
   Action: ACS::ExecuteApi
   Description:
     en: Get backup download url
     zh-cn: 获取备份下载地址
   Properties:
     Service: r-kvstore
     API: DescribeBackups
     Parameters:
       RegionId: '{{ regionId }}'
       InstanceId: '{{ instanceId }}'
       BackupJobId: '{{ CreateBackup.BackupJobID }}'
       StartTime:
         Fn::FormatUTCTime:
           - Fn::AddHour:
               - '{{ ACS::CurrentUTCTime }}'
               - -1
           - '%Y-%m-%dT%H:%MZ'
       EndTime:
         Fn::FormatUTCTime:
           - '{{ ACS::CurrentUTCTime }}'
           - '%Y-%m-%dT%H:%MZ'
   Outputs:
     BackupDownloadURL:
       Type: List
       ValueSelector: .Backups.Backup[].BackupDownloadURL
 - Name: UploadBackupToOSS
   Action: ACS::FC::ExecuteScript
   Description:
     en: Upload backup to OSS
     zh-cn: 上传备份到OSS
   Properties:
     runtime: python3.10
     handler: index.handler
     role: acs:ram::{{ACS::AccountId}}:role/AliyunFcDefaultRole
     script: |-
       import oss2
       import requests

       def handler(event, context):
         auth = oss2.StsAuth(context.credentials.access_key_id, context.credentials.access_key_secret, context.credentials.security_token)
         endpoint = 'https://oss-{{OSSRegionId}}.aliyuncs.com'
         bucket = oss2.Bucket(auth, endpoint, '{{OSSBucketName}}')
         unique_identifier = '{{ACS::TaskLoopItem}}'.split('?')[0].split('/')[-1]
         execution_id = '{{ACS::ExecutionId}}'.split('.')[0]
         input = requests.get('{{ACS::TaskLoopItem}}')
         bucket.put_object(f'Backup_{{InstanceId}}/{{ACS::CurrentDate}}/{execution_id}/{unique_identifier}', input)
   Loop:
     Items: '{{ GetBackupDownloadUrl.BackupDownloadURL }}'
     RateControl:
       Mode: Concurrency
       MaxErrors: 0
       Concurrency: 20
Outputs:
 OSSObjectURL:
   Type: String
   Value: https://oss.console.aliyun.com/bucket/oss-{{OSSRegionId}}/{{OSSBucketName}}/object?path=Backup_{{InstanceId}}/{{ACS::CurrentDate}}/

👍 点赞 - 您的支持是我持续创作的最大动力!

⭐️ 收藏 - 您的关注是我前进的明灯!

✏️ 评论 - 您的反馈是我成长的宝贵资源!

相关推荐
CCSBRIDGE8 分钟前
给阿里云OSS绑定域名并启用SSL
阿里云·云计算·ssl
杨充16 分钟前
13.观察者模式设计思想
java·redis·观察者模式
喵叔哟27 分钟前
重构代码之移动字段
java·数据库·重构
念白44331 分钟前
智能病历xml提取
数据库·sql·oracle
qingy_204635 分钟前
【JavaWeb】JavaWeb入门之XML详解
数据库·oracle
大数据面试宝典39 分钟前
用AI来写SQL:让ChatGPT成为你的数据库助手
数据库·人工智能·chatgpt
努力的小雨44 分钟前
快速上手 KSQL:轻松与数据库交互的利器
数据库·经验分享
何曾参静谧44 分钟前
「Py」Python基础篇 之 Python都可以做哪些自动化?
开发语言·python·自动化
Gentle5861 小时前
labview中连接sql server数据库查询语句
数据库·labview
Gentle5861 小时前
labview用sql server数据库存取数据到一个单元格
数据库·labview