全部產品
Search
文件中心

Object Storage Service:將一個帳號下某個地區Bucket的資料複製到另一個帳號下的另一個地區

更新時間:Jun 05, 2025

如果您希望將一個帳號下某個地區Bucket的資料複製到另一個帳號下的另一個地區,以達到資料跨帳號跨地區容災的目的,您需要使用跨帳號跨地區複製。

前提條件

  • 已在帳號A下的某個地區建立Bucket A作為跨地區複製的源Bucket,並記錄帳號A的UID、Bucket A的名稱及所在地區。

  • 帳號A必須有以下許可權:oss:PutBucketReplicationoss:GetBucketReplicationoss:DeleteBucketReplication、oss:GetBucketReplicationLocation、oss:GetBucketReplicationProgress。具體操作,請參見為RAM使用者授權自訂的權限原則

  • 已在帳號B下的另一個地區建立Bucket B作為跨地區複製的目標Bucket,並記錄帳號B的UID、Bucket B的名稱及所在地區。

角色授權

跨帳號複製任務涉及兩個不同帳號的Bucket,您需要按照以下說明完成RAM角色所需的信任策略和最小權限原則。

  1. 通過帳號A完成以下操作。

    1. 建立普通服務角色。

      重要

      您可以選擇通過RAM使用者建立角色,RAM使用者必須擁有以下許可權:ram:CreateRoleram:GetRoleram:ListRolesram:ListPoliciesForRoleram:AttachPolicyToRole。但是考慮到授予RAM使用者ram:CreateRoleram:GetRole等角色相關的許可權風險較大,您可以通過RAM使用者關聯的阿里雲帳號建立RAM角色並為相應的RAM角色完成授權。授權完成後,RAM使用者可以直接複用阿里雲帳號建立的RAM角色。

      建立角色過程中,信任主體類型選擇雲端服務,信任主體名稱選擇Object Storage Service。具體步驟,請參見建立普通服務角色

      說明

      角色建立成功後,請記錄基本資料地區的RAM角色ARN,以便後續添加許可權時使用。

    2. 為角色授予源Bucket執行跨地區複製的許可權。

      您可以選擇以下任意方式為角色授權。

      為RAM角色授予系統策略

      警告

      您可以選擇為RAM角色授予系統策略AliyunOSSFullAccessAliyunOSSFullAccess預設擁有當前帳號下所有Bucket的所有操作許可權,請謹慎使用。

      為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/*"
               ]
            }
         ]
      }

      如果您希望將KMS加密的Object複製到目標Bucket,您還需要為角色授予AliyunKMSFullAccess系統策略。具體步驟,請參見為RAM角色授權

  2. 通過帳號B授予角色在目標Bucket接收複製對象的許可權。

    (推薦)方式一:按圖形策略添加

    1. 登入OSS管理主控台

    2. 在左側導覽列,單擊Bucket 列表,然後單擊目標bucket名稱dest-bucket

    3. 在左側導覽列,選擇許可權控制 > Bucket 授權策略

    4. Bucket 授權策略頁面的按圖形策略添加頁簽,單擊接收複製對象

    5. 接收複製對象面板,UID及RAM角色擷取方式選中從源端複製RAM角色ARN擷取源端複製RAM角色ARN選擇步驟1建立的角色ARN,授權用途選中跨帳號跨地區複製

    6. 單擊產生 Policy

    方式二:按文法策略添加

    1. 在左側導覽列,選擇許可權控制>Bucket 授權策略

    2. Bucket 授權策略頁面的按文法策略添加頁簽,單擊編輯

    3. 在文法策略輸入框中,輸入以下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/*"
               ]
            }
         ]
      }
    4. 單擊儲存

複製KMS加密的Object

說明

支援複製KMS加密的Object到以下目標地區:華東1(杭州)、華東2(上海)、華南1(深圳)、華南2(河源)、華南3(廣州)、華北1(青島)、華北2(北京)、華北3(張家口)、華北5(呼和浩特)、華北6(烏蘭察布)、西南1(成都)、華東2(上海金融雲)、中國香港、新加坡、馬來西亞(吉隆坡)、印尼(雅加達)、菲律賓(馬尼拉)、泰國(曼穀)、日本(東京)、美國(矽谷)、美國(維吉尼亞)、德國(法蘭克福)、英國(倫敦)。

如果您希望將帳號A下源Bucket中KMS加密的Object複製到帳號B下的目標Bucket,您需要使用目標Bucket所屬帳號B執行以下步驟。

  1. 登入Key Management Service控制台的執行個體管理頁面,在與目標Bucket相同的地區購買並啟用KMS執行個體。購買KMS執行個體時,確保訪問管理數量大於等於2,其他參數保留預設配置。具體步驟,請參見購買和啟用KMS執行個體

  2. 在KMS執行個體下建立密鑰。密鑰類型限制為非預設密鑰(建議軟體密鑰)。具體步驟,請參見建立軟體密鑰

    說明

    密鑰建立成功後,請記錄基本資料地區的密鑰ARN,以便後續建立複製規則時使用。

  3. 為建立的密鑰設定密鑰策略。設定密鑰策略時,選擇其他帳號使用者,並將其他帳號使用者指定為上述步驟建立的角色ARN。具體步驟,請參見設定密鑰策略

    重要

    跨帳號複製KMS加密資料要求密鑰策略至少包含解密(kms:Decrypt)和產生資料密鑰(kms:GenerateDataKey)的許可權。通過控制台設定密鑰策略時,預設包含這些許可權。如果通過OpenAPI設定自訂密鑰策略,需要確保至少包含kms:Decryptkms:GenerateDataKey許可權。

操作步驟

使用OSS控制台

通過帳號A為源Bucket建立跨地區複製規則。

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊源Bucket名稱。

  3. 在左側導覽列,選擇資料管理 > 跨區域復制

  4. 跨區域復制頁簽,單擊跨區域復制

  5. 跨區域復制對話方塊,按以下說明配置各項參數。

    地區

    參數

    說明

    設定目標Bucket

    源Bucket

    顯示源Bucket所在地區及名稱。

    目標Bucket

    選中在另一個帳號中指定一個Bucket,然後下拉選擇目標Bucket所在地區,並手動輸入目標Bucket名稱。

    設定複製策略

    數據複製對象

    選擇需要複製的來源資料。

    • 全部檔案進行同步:將該Bucket內所有的Object複製到目標儲存空間。

    • 指定檔案名稱首碼進行同步:將該Bucket內指定首碼的Object複製到目標Bucket,預設最多可以添加10個首碼。如需增加首碼數量,請聯絡支援人員申請調整,最多可提升至30個。

    數據複製策略

    選擇資料複製的方式。

    說明

    建立資料複製規則後,源Bucket內通過生命週期規則或者CopyObject修改儲存類型後引起的儲存類型變更、以及該Bucket內Object的最後訪問時間(x-oss-last-access-time)屬性,均不會同步到目標Bucket。

    • 增/改 同步(適用於資料容災的情境):將源Bucket內Object新增和更新操作複製到目標Bucket。

      重要

      該策略下僅新增和更新的Object會被複製,而刪除操作不會影響目標Bucket。通過這種方式,可以有效防止因源Bucket手動刪除、通過生命週期自動刪除的行為導致目標Bucket資料丟失的問題。

    • 增/刪/改 同步(適用於共用和訪問同一資料集的情境:將源Bucket內Object的新增、更新、刪除操作複製到目標Bucket。

      重要

      該策略下新增、更新和刪除Object都會被複製到目標Bucket。通過這種方式,確保了資料的一致性,適用於需要共用和訪問同一資料集的多使用者或應用程式環境。但是配置該策略後,當手動刪除或者通過生命週期自動刪除源Bucket內的Object時,目標Bucket也會刪除對應的Object,且Object刪除後無法恢複。

    如果某個Object是通過分區上傳的方式上傳至源Bucket,則每個分區的上傳操作都會複製至目標Bucket。最終,對所有分區執行CompleteMultipartUpload後產生的Object,也會被複製到目標Bucket。

    有關跨地區複製結合版本控制的複製行為說明,請參見資料複製結合版本控制

    複製歷史數據

    選擇是否複製跨地區複製規則生效前源Bucket中已有的歷史資料。

    • 複製:將歷史資料複製至目標Bucket。

      重要

      複製歷史資料時,從源Bucket複製的Object可能會覆蓋目標Bucket中同名的Object。為避免這部分檔案丟失,建議您對源Bucket和目標Bucket開啟版本控制。

    • 不複製:僅複製跨地區複製規則生效後上傳或更新的Object。

    KMS加密目標對象

    選擇是否將源Bucket內KMS加密的Object複製到目標Bucket。

    • 複製:在源Object或者目標Bucket使用了KMS託管祕密金鑰加密方式(即SSE-KMS,指定CMK ID)的情況下,要將Object複製到目標Bucket。選擇複製選項後,您還需要指定KMS密鑰。

      說明

      您可以通過HeadObjectGetBucketEncryption分別查詢源Object和目標Bucket的加密狀態。

    • 不複製:不複製KMS加密的Object到目標Bucket。

    使用的KMS密鑰

    填寫KMS密鑰ARN。如何擷取KMS密鑰ARN,請參見在KMS執行個體下建立軟體密鑰

    授權角色

    下拉選擇步驟1建立的角色。

    加速類型

    僅當跨地區複製涉及的兩個Bucket分別屬於中國內地與非中國內地地區時,加速類型支援傳輸加速

    開啟傳輸加速功能,OSS還會額外收取傳輸加速費用。計費方式,請參見傳輸加速費用

    資料複製時間控制(RTC)

    說明
    • 僅支援華東1(杭州)、華東2(上海)、華北1(青島)、華北2(北京)、華北 3(張家口)、華南1(深圳)各地區之間的跨地區複製任務開啟RTC。

    • 僅支援美國(矽谷)、美國(維吉尼亞)地區之間的跨地區複製任務開啟RTC。

    開啟RTC後,OSS會在幾秒內複製您上傳到OSS的大多數Object,並在10分鐘內複製99.99%的Object。關於RTC的更多資訊,請參見使用資料複製時間控制(RTC)。開啟RTC,將收取額外費用。更多資訊,請參見跨地區複製RTC費用

  6. 單擊確定,然後在彈出的對話方塊,單擊確認開啟

    • 當跨地區複製規則建立完成後,不允許對此規則進行編輯或刪除。

    • 複製任務會在跨地區複製規則配置完成的3~5分鐘後啟動。您可以在源Bucket的跨區域復制頁簽,查看複製進度。

    • 由於Bucket間的跨地區複製採用非同步(近即時)複製,資料複製到目標Bucket需要的時間取決於資料的大小,通常幾分鐘到幾小時不等。

使用阿里雲SDK

僅支援通過Java、Python以及Go SDK進行跨帳號跨地區複製。

Java

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
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";
        // 填寫Endpoint對應的Region資訊,例如cn-hangzhou。
        String region = "cn-hangzhou";
        // 強烈建議不要把訪問憑證儲存到工程代碼裡,否則可能導致訪問憑證泄露,威脅您帳號下所有資源的安全。本程式碼範例以從環境變數中擷取訪問憑證為例。運行本程式碼範例之前,請先配置環境變數。
        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執行個體。
        // 當OSSClient執行個體不再使用時,調用shutdown方法以釋放資源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 顯式聲明使用 V4 簽名演算法
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        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.PUT);
            // 將源Bucket內Object的新增、更新操作複製到目標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內Object的新增、更新操作複製到目標Bucket。
     # action_list=[ReplicationRule.P],
     # 指定資料要複製到的目標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 (
	"context"
	"flag"
	"log"

	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)

// 定義全域變數
var (
	region     string // 儲存地區
	bucketName string // 儲存空間名稱
)

// init函數用於初始化命令列參數
func init() {
	flag.StringVar(&region, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}

func main() {
	// 解析命令列參數
	flag.Parse()

	var (
		targetBucket   = "target bucket name" // 目標儲存空間名稱
		targetLocation = "oss-cn-beijing"     // 目標儲存地區
	)

	// 檢查bucket名稱是否為空白
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}

	// 檢查region是否為空白
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}

	// 載入預設配置並設定憑證提供者和地區
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)

	// 建立OSS用戶端
	client := oss.NewClient(cfg)

	// 建立開啟儲存空間資料複製的請求
	request := &oss.PutBucketReplicationRequest{
		Bucket: oss.Ptr(bucketName), // 儲存空間名稱
		ReplicationConfiguration: &oss.ReplicationConfiguration{
			Rules: []oss.ReplicationRule{
				{
					RTC: &oss.ReplicationTimeControl{
						Status: oss.Ptr("enabled"), // 在配置跨地區複製規則時,開啟資料複製時間控制(RTC)功能
					},
					Destination: &oss.ReplicationDestination{
						Bucket:       oss.Ptr(targetBucket),   // 目標儲存空間名稱
						Location:     oss.Ptr(targetLocation), // 目標儲存地區
						TransferType: oss.TransferTypeOssAcc,  // 傳輸類型
					},
					HistoricalObjectReplication: oss.HistoricalObjectReplicationEnabled, // 開啟歷史資料複製功能
				},
			},
		},
	}

	// 執行開啟儲存空間資料複製的請求
	result, err := client.PutBucketReplication(context.TODO(), request)
	if err != nil {
		log.Fatalf("failed to put bucket replication %v", err)
	}

	// 列印開啟儲存空間資料複製的結果
	log.Printf("put bucket replication result:%#v\n", result)
}

使用命令列工具ossutil

關於使用ossutil開啟跨帳號跨地區複製的具體步驟,請參見put-bucket-replication

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。更多資訊,請參見PutBucketReplication

相關文檔