本文中含有需要您注意的重要提示信息,忽略該信息可能對您的業務造成影響,請務必仔細閱讀。
同賬號同區域復制是指將某個賬號某個地域下源存儲空間(Bucket)的文件(Object)的創建、更新和刪除等操作自動、異步(近實時)地復制到當前賬號相同地域下的目標Bucket。本文介紹如何進行同賬號同區域復制。
前提條件
已在某個賬號下的某個地域創建Bucket A作為同區域復制的源Bucket,并記錄賬號的UID、Bucket A的名稱及所在地域。
已在相同賬號下的相同地域創建Bucket B作為同區域復制的目標Bucket,并記錄Bucket B的名稱。
角色類型
執行同賬號同區域復制時,需要指定用于源Bucket與目標Bucket之間執行復制操作的角色。您可以選擇以下任意角色完成同賬號同區域復制任務。
您可以選擇通過RAM用戶創建角色,RAM用戶必須擁有以下權限:ram:CreateRole
、ram:GetRole
、ram:ListPoliciesForRole
、ram:AttachPolicyToRole
。但是考慮到授予RAM用戶ram:CreateRole
、ram:GetRole
等角色相關的權限風險較大,您可以通過RAM用戶關聯的阿里云賬號創建RAM角色并為相應的RAM角色完成授權。授權完成后,RAM用戶可以直接復用阿里云賬號創建的RAM角色。
(推薦)新建角色
創建同賬號同區域復制規則時,支持選擇新建角色來完成復制任務。選擇新建角色后,后臺將自動創建格式為oss-replication-{uuid}
的角色,并根據是否選擇復制KMS加密對象授予不同權限策略。
選擇復制KMS加密對象
新建角色后,您需要按照頁面指引完成角色授權操作。授權完成后,該角色擁有源Bucket同步到目標Bucket精準權限策略以及AliyunKMSFullAccess(管理密鑰管理服務KMS的權限)。
選擇不復制KMS加密對象
新建角色后,您需要按照頁面指引完成角色授權操作。授權完成后,該角色擁有源Bucket同步到目標Bucket精準權限策略。
AliyunOSSRole
創建同賬號同區域復制規則時,支持選擇AliyunOSSRole角色來完成復制任務。選擇該角色后,后臺會根據是否選擇復制KMS加密對象授予不同權限策略。
選擇復制KMS加密對象
選擇AliyunOSSRole角色后,后臺將自動為AliyunOSSRole角色授予以下權限策略:AliyunOSSFullAccess(管理對象存儲OSS的權限)以及AliyunKMSFullAccess(管理密鑰管理服務KMS的權限)。
警告該角色擁有當前賬號下所有Bucket以及KMS的所有操作權限,權限范圍較大,請謹慎使用。
選擇不復制KMS加密對象
選擇AliyunOSSRole角色后,后臺將自動為AliyunOSSRole角色授予AliyunOSSFullAccess(管理對象存儲OSS的權限)。
警告該角色擁有當前賬號下所有Bucket所有操作權限,權限范圍較大,請謹慎使用。
自定義角色
創建同賬號同區域復制規則時,支持使用自定義角色來完成復制任務。您需要通過RAM控制臺創建自定義角色,并為角色賦予相關權限。
創建普通服務角色。
創建角色過程中,需選擇可信實體類型為阿里云服務,角色類型選擇普通服務角色,受信服務選擇對象存儲。具體步驟,請參見創建普通服務角色。
為角色授權。
您可以選擇以下任意方式為角色授權。
為RAM角色授予系統策略
警告您可以選擇為RAM角色授予系統策略
AliyunOSSFullAccess
。AliyunOSSFullAccess
默認擁有當前賬號下所有Bucket的所有操作權限,請謹慎使用。如果您希望將KMS加密的Object復制到目標Bucket,您還需要為角色授予
AliyunKMSFullAccess
系統策略。具體步驟,請參見為RAM角色授權。
為RAM角色授予自定義策略
建議您選擇為RAM角色授予源Bucket(src-bucket)和目標Bucket(dest-bucket)復制所需的最小權限。
說明實際使用時,請相應替換源Bucket和目標Bucket名稱。
{ "Version":"1", "Statement":[ { "Effect":"Allow", "Action":[ "oss:ReplicateList", "oss:ReplicateGet" ], "Resource":[ "acs:oss:*:*:src-bucket", "acs:oss:*:*:src-bucket/*" ] }, { "Effect":"Allow", "Action":[ "oss:ReplicateList", "oss:ReplicateGet", "oss:ReplicatePut", "oss:ReplicateDelete" ], "Resource":[ "acs:oss:*:*:dest-bucket", "acs:oss:*:*:dest-bucket/*" ] } ] }
具體步驟,請參見為RAM角色授權。
說明如果您希望將KMS加密的Object復制到目標Bucket,您還需要為角色授予
AliyunKMSFullAccess
系統策略。
操作步驟
使用OSS控制臺
登錄OSS管理控制臺。
單擊Bucket 列表,然后單擊src-bucket。
在左側導航欄,選擇 。
在同區域復制頁簽,單擊同區域復制。
在同區域復制對話框,按以下說明配置各項參數。
區域
參數
說明
設置目標Bucket
源Bucket
顯示源Bucket所在地域及名稱。
目標Bucket
選中在此賬號下選擇一個Bucket,然后下拉相同地域下的目標Bucket名稱。
設置復制策略
數據復制對象
選擇需要復制的源數據。
全部文件進行同步:將該Bucket內所有的Object復制到目標存儲空間。
指定文件名前綴進行同步:將該Bucket內指定前綴的Object復制到目標Bucket。最多可以添加10個前綴。
Object標簽
復制擁有指定標簽的Object到目標Bucket。設置方法為選中設置規則后添加標簽(鍵-值對),最多可添加10個標簽。
要設置該參數,必須滿足以下條件:
已設置Object標簽。具體操作,請參見設置對象標簽。
源Bucket與目標Bucket需同時處于華東1(杭州)地域。
源Bucket和目標Bucket均已開啟版本控制。
數據復制策略為增/改 同步。
數據復制策略
選擇數據復制的方式。
說明創建數據復制規則后,源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 加密目標對象
選擇是否將KMS加密的Object復制到目標Bucket。
復制:在源Object或者目標Bucket使用了KMS托管密鑰加密方式(即SSE-KMS,指定CMK ID)的情況下,要將Object復制到目標Bucket。
說明您可以通過HeadObject和GetBucketEncryption分別查詢源Object和目標Bucket的加密狀態。
不復制:不復制KMS加密的Object到目標Bucket。
使用的 KMS 密鑰
選擇將KMS加密的Object復制到目標Bucket,您需要為目標Object指定加密的KMS密鑰。
指定KMS密鑰前,您需要提前在KMS平臺創建一個與目標Bucket相同地域的KMS密鑰。具體操作,請參見創建密鑰。
授權角色
推薦選擇新建角色。下拉選擇新建角色后,您需要按照頁面指引完成角色授權操作。
您還可以選擇AliyunOSSRole或者自定義角色。關于這三種類型角色的更多信息,請參見角色類型。
單擊確定,然后在彈出的對話框,單擊確認開啟。
當同區域復制規則創建完成后,不允許對此規則進行編輯或刪除。
復制任務會在同區域復制規則配置完成的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名稱。
String bucketName = "src-bucket";
// 指定數據要復制到的目標Bucket。目標Bucket與源Bucket必須屬于相同賬號。
String targetBucketName = "dest-bucket";
// 指定目標Bucket所在地域。目標Bucket與源Bucket必須處于相同地域。
String targetBucketLocation = "oss-cn-hangzhou";
// 創建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");
// 指定OSS是否復制通過SSE-KMS加密創建的對象。
//request.setSseKmsEncryptedObjectsStatus("Enabled");
// 指定SSE-KMS密鑰ID。如果指定Status為Enabled,則必須指定該元素。
//request.setReplicaKmsKeyID("3542abdd-5821-4fb5-a425-90adca***");
//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-hangzhou'
# 指定授權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.PUT],
# 指定數據要復制到的目標Bucket。
# target_bucket_name='dest-bucket',
# 指定目標Bucket所在地域。
# target_bucket_location='yourTargetBucketLocation',
# 默認復制歷史數據。此處設置為False,表示禁止復制歷史數據。
# is_enable_historical_object_replication=False,
# 復制通過SSE-KMS加密創建的對象。
# sse_kms_encrypted_objects_status=ReplicationRule.ENABLED
# 指定SSE-KMS密鑰ID。如果指定復制通過SSE-KMS加密創建的對象,則必須指定該元素。
# replica_kms_keyid='9468da86-3509-4f8d-a61e-6eab1eac****',
#)
# 開啟數據復制。
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。
destBucketName := "yourDestBucket"
// 指定待復制Object的前綴prefix_1和prefix_2。指定Prefix后,只有匹配該Prefix的Object才會復制到目標Bucket。
// 如果您需要將源Bucket中的所有Object復制到目標Bucket,則無需設置Prefix。
prefix1 := "prefix_1"
prefix2 := "prefix_2"
// 指定SSE-KMS密鑰ID。如果指定Status為Enabled,則必須指定該元素。
keyId := "c4d49f85-ee30-426b-a5ed-95e9****"
// 指定OSS是否復制通過SSE-KMS加密創建的對象。
source := "Enabled"
prefixSet := oss.ReplicationRulePrefix{Prefix: []*string{&prefix1, &prefix2}}
reqReplication := oss.PutBucketReplication{
Rule: []oss.ReplicationRule{
{
PrefixSet: &prefixSet,
//將源Bucket內Object的新增、更新操作復制到目標Bucket。
Action: "PUT",
Destination: &oss.ReplicationRuleDestination{
Bucket: destBucketName,
// 指定目標Bucket所在地域。源Bucket與目標Bucket必須處于不同的地域。
Location: "oss-cn-hangzhou",
},
// 默認復制歷史數據。此處設置為disabled,表示禁止復制歷史數據。
HistoricalObjectReplication: "disabled",
// 指定授權OSS進行數據復制的角色名稱,且該角色必須已被授予源Bucket執行同區域復制以及目標Bucket接收復制對象的權限。
SyncRole: "yourRole",
EncryptionConfiguration: &keyId,
SourceSelectionCriteria: &source,
},
},
}
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。