Поделиться через


Копирование большого двоичного объекта с асинхронным планированием с помощью Go

В этой статье показано, как скопировать блоб с асинхронным расписанием с помощью модуля клиента Azure Storage для Go. Блоб можно скопировать из источника в той же учетной записи хранения, из источника в другой учетной записи хранения или из любого доступного объекта, полученного с помощью HTTP GET-запроса по указанному URL. Кроме того, можно прервать ожидающие операции копирования.

Методы, описанные в этой статье, используют операцию REST API Copy Blob и могут быть использованы при выполнении копирования с асинхронным планированием. В большинстве сценариев копирования, когда требуется переместить данные в учетную запись хранения и иметь URL-адрес для исходного объекта, см. статью «Копирование бинарного объекта из URL-адреса исходного объекта с помощью Go».

Предпосылки

Настройка среды

Если у вас нет существующего проекта, в этом разделе показано, как настроить проект для работы с клиентским модулем Хранилище BLOB-объектов Azure для Go. Ниже приведены действия по установке модуля, добавлению import путей и созданию авторизованного клиентского объекта. Дополнительные сведения см. в статье «Начало работы с хранилищем BLOB-объектов Azure и Go».

Установка модулей

Установите модуль azblob с помощью следующей команды:

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

Чтобы выполнить проверку подлинности с помощью идентификатора Microsoft Entra (рекомендуется), установите 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-объектов, создайте клиентский объект с помощью 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 Data Contributor или более высокая. Дополнительные сведения см. в руководстве по авторизации для копирования BLOB-объектов или прерывания копирования BLOB-объектов.

О копировании больших двоичных объектов с помощью асинхронного планирования

Операция Copy Blob может завершиться асинхронно и выполняется по мере возможностей, что означает, что ее начало или завершение в течение указанного времени не гарантируется. Операция копирования запланирована в фоновом режиме и выполняется, так как сервер имеет доступные ресурсы. Операция может выполняться синхронно, если копия происходит в той же учетной записи хранения.

Операция Copy Blob может выполнять любое из следующих действий:

  • Копирование исходного блоба в целевой блоб с другим именем. Целевой большой двоичный объект может быть существующим BLOB-объектом одного типа (блокировать, добавить или страницу) или быть новым BLOB-объектом, созданным операцией копирования.
  • Скопируйте исходный большой двоичный объект в целевой большой двоичный объект с тем же именем, который заменяет целевой большой двоичный объект. Этот тип операции копирования удаляет все незафиксированные блоки и перезаписывает метаданные целевого BLOB-объекта.
  • Копирование исходного файла из службы файлов Azure в целевой объект Blob. Целевой BLOB-объект может быть существующим блочным BLOB-объектом или новым блочным BLOB-объектом, созданным операцией копирования. Копирование из файлов в страничные большие двоичные объекты или добавление больших двоичных объектов не поддерживается.
  • Копирование моментального снимка на его базовый объект данных. Повысив моментальный снимок до уровня базового блоба, вы можете восстановить более раннюю версию блоба.
  • Скопировать моментальный снимок на целевой блоб с другим именем. Полученный целевой блоб будет доступным для записи и не станет снимком.

Исходный BLOB для операции копирования может быть одним из следующих типов: блочный BLOB, BLOB для добавления, страничный BLOB, моментальный снимок BLOB или версия BLOB. Операция копирования всегда копирует весь исходный большой двоичный объект или файл. Копирование диапазона байтов или набора блоков не поддерживается.

Если целевой большой двоичный объект уже существует, он должен иметь тот же тип большого двоичного объекта, что и исходный большой двоичный объект, а существующий целевой большой двоичный объект перезаписывается. Целевой большой двоичный объект нельзя изменить во время выполнения операции копирования, а целевой большой двоичный объект может иметь только одну неугашенную операцию копирования.

Дополнительные сведения об операции, включая сведения о свойствах, тегах индекса, метаданных и выставлении счетов, см. в примечаниях Copy Blobкопирования BLOB-объектов.

Копирование большого двоичного объекта с асинхронным планированием

В этом разделе представлен обзор методов, предоставляемых клиентским модулем службы хранилища Azure для Go для выполнения операции копирования с асинхронным планированием.

Следующие методы упаковывают операцию REST API копирования BLOB-объектов и начинают асинхронную копию данных из исходного BLOB-объекта:

Скопируйте большой двоичный объект из источника внутри Azure

Если вы копируете объект BLOB в той же учетной записи, операция может выполняться синхронно. Доступ к исходному объекту Blob можно авторизовать с помощью Microsoft Entra ID (рекомендуется), общей подписи доступа (SAS) или ключа учетной записи. Чтобы использовать альтернативную синхронную операцию копирования, см. Копирование blob из URL-адреса исходного объекта с использованием Go.

Если источник копирования является блобом в другом аккаунте хранения, операция может выполняться асинхронно. Исходный объект Blob должен быть общедоступным или авторизованным с помощью маркера SAS. Маркер SAS должен включать разрешение на чтение ('r'). Дополнительные сведения о маркерах SAS см. в статье "Делегирование доступа с подписанными URL-адресами".

В следующем примере показан сценарий копирования исходного BLOB-объекта из другой учетной записи хранилища с асинхронным планированием. В этом примере мы создадим URL-адрес исходного BLOB-объекта с добавленным маркером SAS делегирования пользователей. В этом примере предполагается, что вы предоставляете собственный SAS. В примере также показано, как арендовать исходный Блоб во время операции копирования, чтобы предотвратить изменения Блоба от другого клиента. Операция Copy Blob сохраняет значение ETag исходного блоба, когда начинается операция копирования. ETag Если значение изменяется до завершения операции копирования, операция завершается ошибкой. Также мы зададим уровень доступа для целевого BLOB-объекта Cool с помощью структуры StartCopyFromURLOptions.

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 должны быть необходимые разрешения. Сведения о требованиях к авторизации см. в разделе "Получение ключа делегирования пользователей".

Копирование BLOB из внешнего источника за пределами Azure

Вы можете выполнить операцию копирования для любого исходного объекта, который можно получить через HTTP-запрос GET по указанному URL-адресу, включая доступные объекты за пределами Azure. В следующем примере показан сценарий копирования объекта BLOB из доступного URL-адреса исходного объекта:

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 имеет нулевую длину. Однако метаданные для целевого большого двоичного объекта имеют новые значения, скопированные из исходного большого двоичного объекта или явно заданные во время операции копирования. Чтобы сохранить исходные метаданные, существовавшие до копирования, создайте моментальный снимок целевого объекта blob перед вызовом методов копирования.

Чтобы прервать ожидающую операцию копирования, вызовите следующую операцию:

Этот метод оборачивает операцию Abort Copy 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)
    }
}

Ресурсы

Дополнительные сведения о копировании больших двоичных объектов с асинхронным планированием с помощью клиентского модуля хранилища BLOB-объектов Azure для Go см. в следующих ресурсах.

Примеры кода

Операции REST API

Пакет SDK Azure для Go содержит библиотеки, которые создаются на основе REST API Azure, что позволяет взаимодействовать с операциями REST API через знакомые парадигмы Go. Методы, описанные в этой статье, используют следующие операции REST API:

Ресурсы модуля клиента

  • Эта статья является частью руководства разработчика Blob Storage для Go. Дополнительные сведения см. в полном списке статей руководства разработчика по созданию приложения Go.