Compartir a través de


Datos adjuntos de Azure Cosmos DB

SE APLICA A: NoSQL MongoDB

Los datos adjuntos de Azure Cosmos DB son elementos especiales que contienen las referencias a los metadatos asociados con un archivo multimedia o blob externo.

Azure Cosmos DB admite dos tipos de datos adjuntos:

  • Los datos adjuntos no administrados son un contenedor alrededor de una referencia de URI a un blob que se almacena en un servicio externo (por ejemplo, Azure Storage, OneDrive, etc.). Este enfoque es similar al almacenamiento de una propiedad URI en un elemento de Azure Cosmos DB estándar.
  • Los datos adjuntos administrados son blobs administrados y almacenados internamente por Azure Cosmos DB y expuestos a través de un elemento mediaLink generado por el sistema.

Nota:

Los datos adjuntos son una característica heredada. Su compatibilidad se limita a ofrecer una funcionalidad continua si ya está usando esta característica.

En lugar de usar datos adjuntos, se recomienda usar Azure Blob Storage como un servicio de almacenamiento de blobs creado específicamente para almacenar los datos de blob. Puede continuar almacenando los metadatos relacionados con los blobs, junto con los vínculos de URI de referencia, en Azure Cosmos DB como propiedades de elementos. El almacenamiento de estos datos en Azure Cosmos DB proporciona la capacidad de consultar los metadatos y los vínculos a los blobs almacenados en Azure Blob Storage.

Microsoft se compromete a proporcionar un aviso, como mínimo, 36 meses antes de que los datos adjuntos estén totalmente en desuso, lo que se anunciará en una fecha posterior.

Restricciones conocidas

Los datos adjuntos administrados de Azure Cosmos DB se distinguen de la compatibilidad con los elementos estándar, para los que ofrece escalabilidad ilimitada, distribución global e integración con otros servicios de Azure.

  • Los datos adjuntos no se admiten en todas las versiones de los SDK de Azure Cosmos DB.
  • Los datos adjuntos administrados se limitan a 2 GB de almacenamiento por cuenta de base de datos.
  • Los datos adjuntos administrados no son compatibles con la distribución global de Azure Cosmos DB y no se replican entre regiones.

Nota:

Azure Cosmos DB for MongoDB, versión 3.2, emplea datos adjuntos administrados para GridFS y están sujetos a las mismas limitaciones.

Se recomienda a los desarrolladores que usan el conjunto de características de MongoDB GridFS actualizar a la versión 3.6 o superior de Azure Cosmos DB for MongoDB, que está desacoplada de los datos adjuntos y proporciona una mejor experiencia. Como alternativa, los desarrolladores que usan el conjunto de características de MongoDB GridFS también deben considerar el uso de Azure Blob Storage, que está diseñado específicamente para almacenar contenido de blobs y ofrece una funcionalidad ampliada con un coste menor en comparación con GridFS.

Migración de datos adjuntos a Azure Blob Storage

Se recomienda migrar los datos adjuntos de Azure Cosmos DB a Azure Blob Storage siguiendo estos pasos:

  1. Copie los datos adjuntos del contenedor de Azure Cosmos DB de origen en el contenedor de Azure Blob Storage de destino.
  2. Valide los datos del blob cargado en el contenedor de Azure Blob Storage de destino.
  3. Si es aplicable, agregue referencias de URI a los blobs contenidos en Azure Blob Storage como propiedades de cadena dentro del conjunto de datos de Azure Cosmos DB.
  4. Refactorice el código de aplicación para leer y escribir blobs en el nuevo contenedor de Azure Blob Storage.

En el ejemplo de código siguiente se muestra cómo copiar datos adjuntos de Azure Cosmos DB en Azure Blob Storage como parte de un flujo de migración mediante el SDK de .NET de Azure Cosmos DB v2 y el SDK de .NET de Azure Blob Storage v12. Asegúrese de reemplazar <placeholder values> para la cuenta de Azure Cosmos DB de origen y el contenedor de Azure Blob Storage de destino.


using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;

namespace attachments
{
    class Program
    {
        private static string cosmosAccount = "<Your_Azure_Cosmos_account_URI>";
        private static string cosmosKey = "<Your_Azure_Cosmos_account_PRIMARY_KEY>";
        private static string cosmosDatabaseName = "<Your_Azure_Cosmos_database>";
        private static string cosmosCollectionName = "<Your_Azure_Cosmos_collection>";
        private static string storageConnectionString = "<Your_Azure_Storage_connection_string>";
        private static string storageContainerName = "<Your_Azure_Storage_container_name>";
        private static DocumentClient cosmosClient = new DocumentClient(new Uri(cosmosAccount), cosmosKey);
        private static BlobServiceClient storageClient = new BlobServiceClient(storageConnectionString);
        private static BlobContainerClient storageContainerClient = storageClient.GetBlobContainerClient(storageContainerName);

        static void Main(string[] args)
        {
            CopyAttachmentsToBlobsAsync().Wait();
        }

        private async static Task CopyAttachmentsToBlobsAsync()
        {
            Console.WriteLine("Copying Azure Cosmos DB Attachments to Azure Blob Storage ...");

            int totalCount = 0;
            string docContinuation = null;

            // Iterate through each item (document in v2) in the Azure Cosmos DB container (collection in v2) to look for attachments.
            do
            {
                FeedResponse<dynamic> response = await cosmosClient.ReadDocumentFeedAsync(
                    UriFactory.CreateDocumentCollectionUri(cosmosDatabaseName, cosmosCollectionName),
                    new FeedOptions
                    {
                        MaxItemCount = -1,
                        RequestContinuation = docContinuation
                    });
                docContinuation = response.ResponseContinuation;

                foreach (Document document in response)
                {
                    string attachmentContinuation = null;
                    PartitionKey docPartitionKey = new PartitionKey(document.Id);

                    // Iterate through each attachment within the item (if any).
                    do
                    {
                        FeedResponse<Attachment> attachments = await cosmosClient.ReadAttachmentFeedAsync(
                            document.SelfLink,
                            new FeedOptions
                            {
                                PartitionKey = docPartitionKey,
                                RequestContinuation = attachmentContinuation
                            }
                        );
                        attachmentContinuation = attachments.ResponseContinuation;

                        foreach (var attachment in attachments)
                        {
                            // Download the attachment in to local memory.
                            MediaResponse content = await cosmosClient.ReadMediaAsync(attachment.MediaLink);

                            byte[] buffer = new byte[content.ContentLength];
                            await content.Media.ReadAsync(buffer, 0, buffer.Length);

                            // Upload the locally buffered attachment to blob storage
                            string blobId = String.Concat(document.Id, "-", attachment.Id);

                            Azure.Response<BlobContentInfo> uploadedBob = await storageContainerClient.GetBlobClient(blobId).UploadAsync(
                                new MemoryStream(buffer, writable: false),
                                true
                            );

                            Console.WriteLine("Copied attachment ... Item Id: {0} , Attachment Id: {1}, Blob Id: {2}", document.Id, attachment.Id, blobId);
                            totalCount++;

                            // Clean up attachment from Azure Cosmos DB.
                            // Warning: please verify you've succesfully migrated attachments to blog storage prior to cleaning up Azure Cosmos DB.
                            // await cosmosClient.DeleteAttachmentAsync(
                            //     attachment.SelfLink,
                            //     new RequestOptions { PartitionKey = docPartitionKey }
                            // );

                            // Console.WriteLine("Cleaned up attachment ... Document Id: {0} , Attachment Id: {1}", document.Id, attachment.Id);
                        }

                    } while (!string.IsNullOrEmpty(attachmentContinuation));
                }
            }
            while (!string.IsNullOrEmpty(docContinuation));

            Console.WriteLine("Finished copying {0} attachments to blob storage", totalCount);
        }
    }
}

Pasos siguientes