本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
跨账号跨区域复制是指将某个账号某个地域下源存储空间(Bucket)的文件(Object)的创建、更新和删除等操作自动、异步(近实时)地复制到另一个账号另一个地域下的目标Bucket。本文介绍如何进行跨账号跨区域复制。
前提条件
已在账号A下的某个地域创建Bucket A作为跨区域复制的源Bucket,并记录账号A的UID、Bucket A的名称及所在地域。
已在账号B下的另一个地域创建Bucket B作为跨区域复制的目标Bucket,并记录账号B的UID、Bucket B的名称及所在地域。
操作步骤
使用OSS控制台
通过账号A完成以下操作。
创建普通服务角色。
重要您可以选择通过RAM用户创建角色,RAM用户必须拥有以下权限:
ram:CreateRole
、ram:GetRole
、ram:ListPoliciesForRole
、ram:AttachPolicyToRole
。但是考虑到授予RAM用户ram:CreateRole
、ram:GetRole
等角色相关的权限风险较大,您可以通过RAM用户关联的阿里云账号创建RAM角色并为相应的RAM角色完成授权。授权完成后,RAM用户可以直接复用阿里云账号创建的RAM角色。创建角色过程中,需选择可信实体类型为阿里云服务,角色类型选择普通服务角色,受信服务选择对象存储。具体步骤,请参见创建普通服务角色。
说明角色创建成功后,请记录基本信息区域的RAM角色ARN,以便后续添加权限时使用。
为角色授予源Bucket执行跨区域复制的权限。
您可以选择以下任意方式为角色授权。
为RAM角色授予系统策略
警告您可以选择为RAM角色授予系统策略
AliyunOSSFullAccess
。AliyunOSSFullAccess
默认拥有当前账号下所有Bucket的所有操作权限,请谨慎使用。具体步骤,请参见为RAM角色授权。
为RAM角色授予自定义策略
通过RAM Policy的方式对RAM角色授予源Bucket(src-bucket)复制所需的最小权限。
说明实际使用时,请相应替换源Bucket名称。
{ "Version":"1", "Statement":[ { "Effect":"Allow", "Action":[ "oss:ReplicateList", "oss:ReplicateGet" ], "Resource":[ "acs:oss:*:*:src-bucket", "acs:oss:*:*:src-bucket/*" ] } ] }
具体步骤,请参见为RAM角色授权。
通过账号B授予角色在目标Bucket接收复制对象的权限。
(推荐)方式一:按图形策略添加
方式二:按语法策略添加
在左侧导航栏,选择权限控制>Bucket 授权策略。
在Bucket 授权策略页面的按语法策略添加页签,单击编辑。
在语法策略输入框中,输入以下Bucket Policy。
重要通过Bucket Policy按语法策略的方式进行授权时,新添加的策略会覆盖已有的策略,请确保新添加策略包含已有策略的内容,否则可能导致关联已有策略的操作失败。
实际使用时,请相应替换自定义角色名称(如果自定义角色名称包含大写字母,需转换为对应的小写字母。例如已创建的角色名称为AliyunOssDrsRole,您需要转换为aliyunossdrsrole)、目标Bucket名称(dest-bucket)、源Bucket所属账号UID(137918634953xxxx)以及目标Bucket所属账号UID(111933544165xxxx)。
{ "Version":"1", "Statement":[ { "Effect":"Allow", "Action":[ "oss:ReplicateList", "oss:ReplicateGet", "oss:ReplicatePut", "oss:ReplicateDelete" ], "Principal": [ "arn:sts::137918634953xxxx:assumed-role/aliyunossdrsrole/*" ], "Resource":[ "acs:oss:*:111933544165xxxx::dest-bucket", "acs:oss:*:111933544165xxxx::dest-bucket/*" ] } ] }
单击保存。
通过账号A为源Bucket创建跨区域复制规则。
登录OSS管理控制台。
单击Bucket 列表,然后单击源Bucket名称。
在左侧导航栏,选择数据管理 > 跨区域复制。
在跨区域复制页签,单击跨区域复制。
在跨区域复制对话框,按以下说明配置各项参数。
区域
参数
说明
设置目标Bucket
源Bucket
显示源Bucket所在地域及名称。
目标Bucket
选中在另一个账号中指定一个Bucket,然后下拉选择目标Bucket所在地域,并手动输入目标Bucket名称。
设置复制策略
数据复制对象
选择需要复制的源数据。
全部文件进行同步:将该Bucket内所有的Object复制到目标存储空间。
指定文件名前缀进行同步:将该Bucket内指定前缀的Object复制到目标Bucket。最多可以添加10个前缀。
数据复制策略
选择数据复制的方式。
增/改 同步:将该Bucket内Object新增和更新操作复制到目标Bucket。
增/删/改 同步:将该Bucket内Object的新增、更新、删除操作复制到目标Bucket。
如果某个Object是通过分片上传的方式上传至源Bucket,则每个分片的上传操作都会复制至目标Bucket。最终,对所有分片执行CompleteMultipartUpload后生成的Object,也会被复制到目标Bucket。
有关跨区域复制结合版本控制的复制行为说明,请参见数据复制结合版本控制。
复制历史数据
选择是否复制跨区域复制规则生效前源Bucket中已有的历史数据。
复制:将历史数据复制至目标Bucket。
重要复制历史数据时,从源Bucket复制的Object可能会覆盖目标Bucket中同名的Object。为避免这部分文件丢失,建议您对源Bucket和目标Bucket开启版本控制。
不复制:仅复制跨区域复制规则生效后上传或更新的Object。
授权角色
下拉选择步骤1创建的角色。
加速类型
仅当跨区域复制涉及的两个Bucket分别属于中国内地与非中国内地地域时,加速类型支持传输加速。
开启传输加速功能,OSS还会额外收取传输加速费用。计费方式,请参见传输加速费用。
数据复制时间控制(RTC)
说明仅支持华东1(杭州)、华东2(上海)、华北1(青岛)、华北2(北京)、华北 3(张家口)、华南1(深圳)各地域之间的跨区域复制任务开启RTC。
仅支持美国(硅谷)、美国(弗吉尼亚)地域之间的跨区域复制任务开启RTC。
开启RTC后,OSS会在几秒内复制您上传到OSS的大多数Object,并在10分钟内复制99.99%的Object。关于RTC的更多信息,请参见使用数据复制时间控制(RTC)。开启RTC,将收取额外费用。更多信息,请参见跨区域复制RTC费用。
单击确定,然后在弹出的对话框,单击确认开启。
当跨区域复制规则创建完成后,不允许对此规则进行编辑或删除。
复制任务会在跨区域复制规则配置完成的3~5分钟后启动。您可以在源Bucket的跨区域复制页签,查看复制进度。
由于Bucket间的跨区域复制采用异步(近实时)复制,数据复制到目标Bucket需要的时间取决于数据的大小,通常几分钟到几小时不等。
使用阿里云SDK
仅支持通过Java、Python以及Go SDK进行跨账号跨区域复制。
Java
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.AddBucketReplicationRequest;
public class Demo {
public static void main(String[] args) throws Exception {
// Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 强烈建议不要把访问凭证保存到工程代码里,否则可能导致访问凭证泄露,威胁您账号下所有资源的安全。本代码示例以从环境变量中获取访问凭证为例。运行本代码示例之前,请先配置环境变量。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填写源Bucket名称,例如src-bucket。
String bucketName = "src-bucket";
// 指定数据要复制到的目标Bucket。目标Bucket与源Bucket必须属于不同账号。
String targetBucketName = "dest-bucket";
// 指定目标Bucket所在地域。目标Bucket与源Bucket必须处于不同地域。
String targetBucketLocation = "oss-cn-shanghai";
// 创建OSSClient实例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
AddBucketReplicationRequest request = new AddBucketReplicationRequest(bucketName);
request.setTargetBucketName(targetBucketName);
request.setTargetBucketLocation(targetBucketLocation);
// 默认复制历史数据。此处设置为false,表示禁止复制历史数据。
request.setEnableHistoricalObjectReplication(false);
// 指定授权OSS进行数据复制的角色名称,且该角色必须已被授予源Bucket执行跨区域复制以及目标Bucket接收复制对象的权限。
request.setSyncRole("yourRole");
//List prefixes = new ArrayList();
//prefixes.add("image/");
//prefixes.add("video");
//prefixes.add("a");
//prefixes.add("A");
// 指定待复制Object的前缀Prefix。指定Prefix后,只有匹配该Prefix的Object才会复制到目标Bucket。
//request.setObjectPrefixList(prefixes);
//List actions = new ArrayList();
//actions.add(AddBucketReplicationRequest.ReplicationAction.ALL);
// 指定可以被复制到目标Bucket的操作。默认值为ALL,表示源Bucket的所有操作都会复制到目标Bucket。
//request.setReplicationActionList(actions);
ossClient.addBucketReplication(request);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
Python
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from oss2.models import ReplicationRule
# 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# 填写源Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
# 填写源Bucket名称,例如src-bucket。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'src-bucket')
replica_config = ReplicationRule(
# 指定数据要复制到的目标Bucket。目标Bucket与源Bucket必须属于不同账号。
target_bucket_name='dest-bucket',
# 指定目标Bucket所在地域。目标Bucket与源Bucket必须处于不同地域。
target_bucket_location='oss-cn-shanghai',
# 指定授权OSS进行数据复制的角色名称,且该角色必须已被授予源Bucket执行跨区域复制以及目标Bucket接收复制对象的权限。
sync_role_name='roleNameTest',
)
# 指定待复制Object的前缀Prefix。指定Prefix后,只有匹配该Prefix的Object才会复制到目标Bucket。
# prefix_list = ['prefix1', 'prefix2']
# 设置数据复制规则。
# replica_config = ReplicationRule(
# prefix_list=prefix_list,
# 指定可以被复制到目标Bucket的操作。默认值为ALL,表示源Bucket的所有操作都会复制到目标Bucket。
# action_list=[ReplicationRule.ALL],
# 指定数据要复制到的目标Bucket。目标Bucket与源Bucket必须属于不同账号。
# target_bucket_name='dest-bucket',
# 指定目标Bucket所在地域。目标Bucket与源Bucket必须处于不同地域。
# target_bucket_location='yourTargetBucketLocation',
# 默认复制历史数据。此处设置为False,表示禁止复制历史数据。
# is_enable_historical_object_replication=False,
# 指定数据复制时使用的数据传输链路。
# target_transfer_type='oss_acc',
#)
# 开启数据复制。
bucket.put_bucket_replication(replica_config)
Go
package main
import (
"encoding/xml"
"fmt"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
"os"
)
func HandleError(err error) {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 开启数据复制。
func main() {
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 创建OSSClient实例。
// yourEndpoint填写Bucket对应的Endpoint,以华东1(杭州)为例,填写为https://oss-cn-hangzhou.aliyuncs.com。其它Region请按实际情况填写。
client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 指定源Bucket名称。
srcbucketName := "yourSrcBucket"
// 指定数据要复制到的目标Bucket。目标Bucket与源Bucket必须属于不同账号。
destBucketName := "yourDestBucket"
// 指定待复制Object的前缀prefix_1和prefix_2。指定Prefix后,只有匹配该Prefix的Object才会复制到目标Bucket。
// 如果您需要将源Bucket中的所有Object复制到目标Bucket,则无需设置Prefix。
prefix1 := "prefix_1"
prefix2 := "prefix_2"
prefixSet := oss.ReplicationRulePrefix{Prefix: []*string{&prefix1, &prefix2}}
// 在配置跨区域复制规则时,开启数据复制时间控制(RTC)功能。
enabled := "enabled"
reqReplication := oss.PutBucketReplication{
Rule: []oss.ReplicationRule{
{
PrefixSet: &prefixSet,
//指定可以被复制到目标Bucket的操作。默认值为ALL,表示源Bucket的所有操作都会复制到目标Bucket。
Action: "ALL",
RTC: &enabled,
Destination: &oss.ReplicationRuleDestination{
Bucket: destBucketName,
// 指定目标Bucket所在地域。源Bucket与目标Bucket必须处于不同的地域。
Location: "oss-cn-hangzhou",
// 指定数据复制时使用的数据传输链路。此处设置为oss_acc,表示使用了传输加速链路。
TransferType: "oss_acc",
},
// 默认复制历史数据。此处设置为disabled,表示禁止复制历史数据。
HistoricalObjectReplication: "disabled",
// 指定授权OSS进行数据复制的角色名称,且该角色必须已被授予源Bucket执行跨区域复制以及目标Bucket接收复制对象的权限。
SyncRole: "yourRole",
},
},
}
xmlBody, err := xml.Marshal(reqReplication)
if err != nil {
HandleError(err)
}
err = client.PutBucketReplication(srcbucketName, string(xmlBody))
if err != nil {
HandleError(err)
}
fmt.Println("Put Bucket Replication Success!")
}
使用命令行工具ossutil
关于使用ossutil开启跨账号跨区域复制的具体步骤,请参见replication(数据复制)。
使用REST API
如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PutBucketReplication。
相关文档
- 本页导读 (1)