Go를 사용하여 비동기 일정으로 Blob 복사

이 문서에서는 Go용 Azure Storage 클라이언트 모듈을 사용하여 비동기 스케줄링으로 Blob을 복사하는 방법을 보여 줍니다. 동일한 스토리지 계정 내의 원본, 다른 스토리지 계정의 원본 또는 지정된 URL의 HTTP GET 요청을 통해 검색되어 액세스 가능한 개체에서 Blob을 복사할 수 있습니다. 보류 중인 복사 작업을 중단할 수도 있습니다.

이 문서에서 다루는 방법은 Blob 복사 REST API 작업을 사용하며, 비동기 일정으로 복사를 수행하려는 경우 사용할 수 있습니다. 데이터를 스토리지 계정으로 이동하고 원본 개체에 대한 URL을 포함하려는 대부분의 복사 시나리오에 대해서는 Go를 사용하여 원본 개체 URL에서 Blob 복사를 참조하세요.

필수 조건

환경 설정

기존 프로젝트가 없는 경우 이 섹션에서는 Go용 Azure Blob Storage 클라이언트 모듈을 사용하도록 프로젝트를 설정하는 방법을 보여 줍니다. 단계에는 모듈 설치, import 경로 추가 및 권한이 있는 클라이언트 개체 만들기가 포함됩니다. 자세한 내용은 Azure Blob Storage 및 Go 시작을 참조하세요.

모듈 설치

다음 명령을 사용하여 azblob 모듈을 설치합니다.

go get github.com/Azure/azure-sdk-for-go/sdk/storage/azblob

Microsoft Entra ID로 인증(권장)하려면 다음 명령을 사용하여 azidentity 모듈을 설치합니다.

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

가져오기 경로 추가

코드 파일에 다음 가져오기 경로를 추가합니다.

import (
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

이러한 가져오기 경로는 시작하는 데 필요한 최소한의 경로를 나타냅니다. 이 문서의 일부 코드 예제에는 추가 가져오기 경로가 필요할 수 있습니다. 구체적인 세부 정보와 사용 예를 보려면 코드 샘플을 참조하세요.

클라이언트 개체 만들기

앱을 Blob Storage에 연결하려면 azblob.NewClient를 사용하여 클라이언트 개체를 만듭니다. 다음 예에서는 권한 부여를 위해 DefaultAzureCredential을 사용하여 클라이언트 개체를 만드는 방법을 설명합니다.

func getServiceClientTokenCredential(accountURL string) *azblob.Client {
    // Create a new service client with token credential
    credential, err := azidentity.NewDefaultAzureCredential(nil)
    handleError(err)

    client, err := azblob.NewClient(accountURL, credential, nil)
    handleError(err)

    return client
}

권한 부여

권한 부여 메커니즘에는 복사 작업을 수행하거나 보류 중인 복사를 중단하는 데 필요한 권한이 있어야 합니다. Microsoft Entra ID로 권한을 부여하려면(권장) Azure RBAC 기본 제공 역할 Storage Blob 데이터 기여자 이상이 필요합니다. 자세한 내용은 Blob 복사 또는 Blob 복사 중단에 대한 권한 부여 지침을 참조하세요.

비동기 일정으로 Blob 복사 정보

Copy Blob 작업은 비동기적으로 완료될 수 있으며 최선의 노력으로 수행됩니다. 즉, 작업이 즉시 시작되거나 지정된 시간 프레임 내 완료된다고 보장되지 않습니다. 복사 작업은 백그라운드에서 예약되고 서버에 사용 가능한 리소스가 있을 때 수행됩니다. 복사가 동일한 스토리지 계정 내에서 발생하는 경우 작업은 동기적으로 완료할 수 있습니다.

Copy Blob 작업은 다음 작업을 수행할 수 있습니다.

  • 다른 이름을 사용해서 원본 Blob을 대상 Blob에 복사합니다. 대상 Blob은 동일한 Blob 유형(블록, 추가 또는 페이지)의 기존 Blob이거나 복사 작업으로 생성된 새 Blob일 수 있습니다.
  • 동일한 이름을 사용해 원본 Blob을 대상 Blob으로 복사하여 대상 Blob을 바꿀 수 있습니다. 이 유형의 복사 작업은 커밋되지 않은 블록을 제거하고 대상 Blob의 메타데이터를 덮어씁니다.
  • Azure 파일 서비스의 원본 파일을 대상 Blob에 복사합니다. 대상 blob은 기존 블록 Blob이거나 복사 작업을 통해 만든 새 블록 Blob일 수 있습니다. 파일에서 페이지 Blob 또는 추가 Blob으로 복사하는 것은 지원되지 않습니다.
  • 기본 Blob에 대해 스냅샷을 복사합니다. 스냅샷의 수준을 기본 Blob 위치로 올리면 이전 Blob 버전을 복원할 수 있습니다.
  • 스냅샷을 다른 이름으로 대상 Blob에 복사합니다. 복사된 대상 Blob는 쓰기 가능한 Blob이고 스냅샷이 아닙니다.

복사 작업의 원본 Blob은 블록 Blob, 추가 Blob, 페이지 Blob, Blob 스냅샷 또는 Blob 버전 중 하나일 수 있습니다. 복사 작업은 항상 전체 원본 BLOB 또는 파일을 복사합니다. 바이트 범위 또는 블록 세트 복사는 지원되지 않습니다.

대상 BLOB이 이미 있는 경우 원본 BLOB과 동일한 BLOB 형식이어야 하며 기존 대상 BLOB을 덮어씁니다. 복사 작업이 진행되는 동안에는 대상 BLOB을 수정할 수 없으며 대상 BLOB에는 하나의 미해결 복사 작업만 있을 수 있습니다.

속성, 인덱스 태그, 메타데이터 및 청구에 대한 정보를 포함하여 Copy Blob 작업에 대한 자세한 내용은 BLOB 설명 복사를 참조하세요.

비동기 일정으로 BLOB 복사

이 섹션에서는 Go용 Azure Storage 클라이언트 모듈이 비동기 일정으로 복사 작업을 수행하는 데 제공하는 방법에 대해 간략하게 설명합니다.

다음 메서드는 BLOB 복사 REST API 작업을 래핑하고 원본 BLOB에서 데이터의 비동기 복사를 시작합니다.

Azure 내 원본에서 Blob 복사

동일한 스토리지 계정 내에서 Blob을 복사하는 경우 작업을 동기적으로 완료할 수 있습니다. 원본 Blob에 대한 액세스는 Microsoft Entra ID(권장), SAS(공유 액세스 서명) 또는 계정 키를 통해 권한 부여될 수 있습니다. 다른 동기 복사 작업에 대해서는 Go로 원본 개체 URL에서 Blob 복사를 참조하세요.

복사 원본이 다른 스토리지 계정의 BLOB인 경우 작업을 비동기적으로 완료할 수 있습니다. 원본 Blob은 공용이거나 SAS 토큰을 통해 권한이 부여되어야 합니다. SAS 토큰에는 읽기(‘r’) 권한이 포함되어야 합니다. SAS 토큰에 대한 자세한 내용은 공유 액세스 서명을 사용하여 액세스 위임을 참조하세요.

다음 예제에서는 비동기 일정으로 다른 스토리지 계정에서 원본 Blob을 복사하는 시나리오를 보여 줍니다. 이 예제에서는 추가된 사용자 위임 SAS 토큰을 사용하여 원본 Blob URL을 만듭니다. 이 예에서는 사용자가 자체 SAS를 제공한다고 가정합니다. 또한 이 예제에서는 복사 작업 중에 원본 Blob을 임대하여 다른 클라이언트에서 Blob에 대한 변경 내용을 방지하는 방법을 보여줍니다. Copy Blob 작업은 복사 작업이 시작될 때 원본 Blob의 ETag 값을 저장합니다. 복사 작업이 완료되기 전에 ETag 값이 변경되면 작업이 실패합니다. 또한 StartCopyFromURLOptions 구조체를 사용하여 대상 blob의 액세스 계층을 Cool로 설정했습니다.

func copyFromSourceAsync(srcBlob *blockblob.Client, destBlob *blockblob.Client) {
    // Lease the source blob during copy to prevent other clients from modifying it
    blobLeaseClient, err := lease.NewBlobClient(srcBlob, nil)
    handleError(err)

    _, err = blobLeaseClient.AcquireLease(context.TODO(), int32(60), nil)
    handleError(err)

    // Retrieve the SAS token for the source blob and append it to the URL
    sas := "<sas-token>"
    url := srcBlob.URL() + "?" + sas

    // Set copy options
    copyOptions := blob.StartCopyFromURLOptions{
        Tier: to.Ptr(blob.AccessTierCool),
    }

    // Copy the blob from the source URL to the destination blob
    startCopy, err := destBlob.StartCopyFromURL(context.TODO(), url, &copyOptions)
    handleError(err)

    // If startCopy.CopyStatus returns a status of "pending", the operation has started asynchronously
    // You can optionally add logic to poll the copy status and wait for the operation to complete
    // Example:
    copyStatus := *startCopy.CopyStatus
    for copyStatus == blob.CopyStatusTypePending {
        time.Sleep(time.Second * 2)

        properties, err := destBlob.GetProperties(context.TODO(), nil)
        handleError(err)

        copyStatus = *properties.CopyStatus
    }

    // Release the lease on the source blob
    _, err = blobLeaseClient.ReleaseLease(context.TODO(), nil)
    handleError(err)
}

다음 예에서는 샘플 사용법을 보여 줍니다.

// TODO: replace <storage-account-name> placeholders with actual storage account names
srcURL := "https://<src-storage-account-name>.blob.core.windows.net/"
destURL := "https://<dest-storage-account-name>.blob.core.windows.net/"

credential, err := azidentity.NewDefaultAzureCredential(nil)
handleError(err)

srcClient, err := azblob.NewClient(srcURL, credential, nil)
handleError(err)
destClient, err := azblob.NewClient(destURL, credential, nil)
handleError(err)

srcBlob := srcClient.ServiceClient().NewContainerClient("source-container").NewBlockBlobClient("source-blob")
destBlob := destClient.ServiceClient().NewContainerClient("destination-container").NewBlockBlobClient("destination-blob-1")

copyFromSourceAsync(srcBlob, destBlob)

참고 항목

사용자 위임 SAS 토큰은 계정 키 대신 Microsoft Entra 자격 증명으로 서명되므로 더 강력한 보안을 제공합니다. 사용자 위임 SAS 토큰을 만들려면 Microsoft Entra 보안 주체에 적절한 권한이 필요합니다. 권한 부여 요구 사항은 사용자 위임 키 가져오기를 참조하세요.

Azure 외부의 원본에서 Blob 복사

Azure 외부의 액세스 가능한 개체를 포함하여 지정된 URL에서 HTTP GET 요청을 통해 검색할 수 있는 모든 원본 개체에 대해 복사 작업을 수행할 수 있습니다. 다음 예제에서는 액세스 가능한 원본 개체 URL에서 Blob을 복사하는 시나리오를 보여줍니다.

func copyFromExternalSourceAsync(srcURL string, destBlob *blockblob.Client) {
    // Set copy options
    copyOptions := blob.StartCopyFromURLOptions{
        Tier: to.Ptr(blob.AccessTierCool),
    }

    // Copy the blob from the source URL to the destination blob
    startCopy, err := destBlob.StartCopyFromURL(context.TODO(), srcURL, &copyOptions)
    handleError(err)

    // If startCopy.CopyStatus returns a status of "pending", the operation has started asynchronously
    // You can optionally add logic to poll the copy status and wait for the operation to complete
    // Example:
    copyStatus := *startCopy.CopyStatus
    for copyStatus == blob.CopyStatusTypePending {
        time.Sleep(time.Second * 2)

        properties, err := destBlob.GetProperties(context.TODO(), nil)
        handleError(err)

        copyStatus = *properties.CopyStatus
    }
}

다음 예에서는 샘플 사용법을 보여 줍니다.

externalURL := "<source-url>"

destBlob = destClient.ServiceClient().NewContainerClient("destination-container").NewBlockBlobClient("destination-blob-2")

copyFromExternalSourceAsync(externalURL, destBlob)

복사 작업의 상태 확인

비동기 Copy Blob 작업의 상태를 확인하려면 GetProperties 메서드를 폴링하고 복사 상태를 확인할 수 있습니다.

다음 코드 예제에서는 복사 작업의 상태를 확인하는 방법을 보여 줍니다.

func checkCopyStatus(destBlob *blockblob.Client) {
    // Retrieve the properties from the destination blob
    properties, err := destBlob.GetProperties(context.TODO(), nil)
    handleError(err)

    copyID := *properties.CopyID
    copyStatus := *properties.CopyStatus

    fmt.Printf("Copy operation %s is %s\n", copyID, copyStatus)
}

복사 작업 중단

보류 중인 Copy Blob 작업을 중단하면 대상 Blob의 길이가 0이 됩니다. 하지만 대상 Blob의 메타데이터는 원본 Blob에서 복사되었거나 복사 작업 중에 명시적으로 설정된 새 값을 가집니다. 복사 전의 원본 메타데이터를 보존하려면 복사 메서드 중 하나를 호출하기 전에 대상 Blob의 스냅샷을 만듭니다.

보류 중인 복사 작업을 중단하려면 다음 작업을 호출합니다.

이 메서드는 Blob 복사 중단 REST API 작업을 래핑하여, 보류 중인 Copy Blob 작업을 취소합니다. 다음 코드 예제에서는 보류 중인 Copy Blob 작업을 중단하는 방법을 보여줍니다.

func abortCopy(destBlob *blockblob.Client) {
    // Retrieve the copy ID from the destination blob
    properties, err := destBlob.GetProperties(context.TODO(), nil)
    handleError(err)

    copyID := *properties.CopyID
    copyStatus := *properties.CopyStatus

    // Abort the copy operation if it's still pending
    if copyStatus == blob.CopyStatusTypePending {
        _, err := destBlob.AbortCopyFromURL(context.TODO(), copyID, nil)
        handleError(err)

        fmt.Printf("Copy operation %s aborted\n", copyID)
    }
}

리소스

Go용 Azure Blob Storage 클라이언트 모듈을 사용하여 비동기 일정으로 Blob을 복사하는 방법에 대해 자세히 알아보려면 다음 리소스를 참조하세요.

코드 샘플

REST API 작업

Go용 Azure SDK에는 Azure REST API를 기반으로 빌드되는 라이브러리가 포함되어 있어 익숙한 Go 패러다임을 통해 REST API 작업과 상호 작용할 수 있습니다. 이 문서에서 다루는 방법은 다음과 같은 REST API 작업을 사용합니다.

클라이언트 모듈 리소스

  • 이 문서는 Go용 Blob Storage 개발자 가이드의 일부입니다. 자세한 내용은 Go 앱 빌드에서 개발자 가이드 문서의 전체 목록을 참조하세요.