Compartir por


Importación masiva de datos a la cuenta de Azure Cosmos DB for NoSQL mediante el SDK para .NET

SE APLICA A: NoSQL

En este tutorial se muestra cómo compilar una aplicación de consola de .NET que optimice la capacidad de proceso aprovisionada (RU/s) necesaria para importar datos en Azure Cosmos DB.

En este artículo, se leerán los datos de un origen de datos de ejemplo y se importarán en un contenedor de Azure Cosmos DB. Este tutorial usa la versión 3.0+ del SDK de .NET de Azure Cosmos DB, cuyo destino puede ser .NET Framework o .NET Core.

Esta tutorial abarca lo siguiente:

  • Creación de una cuenta de Azure Cosmos DB
  • Configuración del proyecto
  • Conexión a una cuenta de Azure Cosmos DB con compatibilidad para la ejecución en bloque habilitada
  • Realización de una importación de datos mediante operaciones simultáneas de creación

Requisitos previos

Antes de seguir las instrucciones del presente artículo, asegúrese de tener los siguientes recursos:

Paso 1: Creación de una cuenta de Azure Cosmos DB

Cree una cuenta de Azure Cosmos DB for NoSQL desde Azure Portal o bien créela mediante el emulador de Azure Cosmos DB.

Paso 2: Configuración del proyecto .NET

Abra el símbolo del sistema de Windows o una ventana de Terminal desde el equipo local. En las secciones siguientes todos los comandos se ejecutarán desde el símbolo del sistema o desde el terminal. Ejecute el siguiente comando dotnet new para crear una nueva aplicación con el nombre bulk-import-demo.

dotnet new console -n bulk-import-demo

Cambie el directorio a la carpeta de aplicaciones recién creada. Para compilar la aplicación:

cd bulk-import-demo
dotnet build

El resultado esperado de la compilación debe parecerse a lo siguiente:

Restore completed in 100.37 ms for C:\Users\user1\Downloads\CosmosDB_Samples\bulk-import-demo\bulk-import-demo.csproj.
  bulk -> C:\Users\user1\Downloads\CosmosDB_Samples\bulk-import-demo \bin\Debug\netcoreapp2.2\bulk-import-demo.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:34.17

Paso 3: Incorporación del paquete de Azure Cosmos DB

Mientras sigue en el directorio de aplicaciones, instale el paquete de la biblioteca cliente de Azure Cosmos DB para .NET Core con el comando dotnet add package.

dotnet add package Microsoft.Azure.Cosmos

Paso 4: Obtención de las credenciales de la cuenta de Azure Cosmos DB

La aplicación de ejemplo debe autenticarse para la cuenta de Azure Cosmos DB. Para hacer la autenticación, debe pasar las credenciales de cuenta de Azure Cosmos DB a la aplicación. Para obtener las credenciales de cuenta de Azure Cosmos DB, siga estos pasos:

  1. Inicie sesión en Azure Portal.
  2. Vaya a la cuenta de Azure Cosmos DB.
  3. Abra el panel Claves y copia el URI y la CLAVE PRINCIPAL de la cuenta.

Si usa el emulador de Azure Cosmos DB, obtenga las credenciales del emulador de este artículo.

Paso 5: Inicialización del objeto CosmosClient con compatibilidad de ejecución en bloque

Abra el archivo Program.cs generado en un editor de código. Creará una instancia de CosmosClient con la ejecución en bloque habilitada y la usará para realizar operaciones en Azure Cosmos DB.

Comencemos por sobrescribir el método Main predeterminado y definir las variables globales. Estas variables globales incluirán el punto de conexión y las claves de autorización, el nombre de la base de datos, el contenedor que creará y el número de elementos que se van a insertar en bloque. Asegúrese de reemplazar los valores de URL de punto de conexión y clave de autorización según su entorno.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Azure.Cosmos;

public class Program
{
     private const string EndpointUrl = "https://<your-account>.documents.azure.com:443/";
     private const string AuthorizationKey = "<your-account-key>";
     private const string DatabaseName = "bulk-tutorial";
     private const string ContainerName = "items";
     private const int AmountToInsert = 300000;

     static async Task Main(string[] args)
     {

     }
}

Dentro del método Main, agregue el siguiente código para inicializar el objeto CosmosClient:

CosmosClient cosmosClient = new CosmosClient(EndpointUrl, AuthorizationKey, new CosmosClientOptions() { AllowBulkExecution = true });

Nota

Una vez especificada la ejecución masiva en CosmosClientOptions, son inmutables de forma eficaz durante la vigencia del objeto CosmosClient. Cambiar los valores no tendrá ningún efecto.

Una vez habilitada la ejecución en bloque, CosmosClient agrupa internamente las operaciones simultáneas en llamadas de servicio únicas. De este modo, optimiza el uso de la capacidad de proceso, ya que distribuye las llamadas de servicio entre las particiones y, por último, asigna los resultados individuales a los llamadores originales.

Después, se puede crear un contenedor para almacenar todos los elementos. Defina /pk como la clave de partición, 50 000 RU/s como capacidad de proceso aprovisionada y una directiva de indexación personalizada que excluya todos los campos para optimizar el proceso de escritura. Agregue el siguiente código después de la instrucción de inicialización de CosmosClient:

Database database = await cosmosClient.CreateDatabaseIfNotExistsAsync(Program.DatabaseName);

await database.DefineContainer(Program.ContainerName, "/pk")
        .WithIndexingPolicy()
            .WithIndexingMode(IndexingMode.Consistent)
            .WithIncludedPaths()
                .Attach()
            .WithExcludedPaths()
                .Path("/*")
                .Attach()
        .Attach()
    .CreateAsync(50000);

Paso 6: Rellenado de una lista de tareas simultáneas

Para aprovechar las ventajas de la compatibilidad con la ejecución en bloque, cree una lista de tareas asincrónicas en función del origen de los datos y de las operaciones que desee realizar, y use Task.WhenAll para ejecutarlas simultáneamente. Comencemos usando datos de "Bogus" para generar una lista de elementos de nuestro modelo de datos. En una aplicación real, los elementos procederían del origen de datos deseado.

En primer lugar, agregue el paquete Bogus a la solución mediante el comando dotnet add package.

dotnet add package Bogus

Establezca la definición de los elementos que desea guardar. Debe definir la clase Item en el archivo Program.cs:

public class Item
{
    public string id {get;set;}
    public string pk {get;set;}

    public string username{get;set;}
}

A continuación, cree una función auxiliar dentro de la clase Program. Esta función auxiliar obtendrá el número de elementos que definió para insertar y generará datos aleatorios:

private static IReadOnlyCollection<Item> GetItemsToInsert()
{
    return new Bogus.Faker<Item>()
    .StrictMode(true)
    //Generate item
    .RuleFor(o => o.id, f => Guid.NewGuid().ToString()) //id
    .RuleFor(o => o.username, f => f.Internet.UserName())
    .RuleFor(o => o.pk, (f, o) => o.id) //partitionkey
    .Generate(AmountToInsert);
}

Use la función auxiliar para inicializar una lista de documentos con los que trabajar:

IReadOnlyCollection<Item> itemsToInsert = Program.GetItemsToInsert();

A continuación, use la lista de documentos para crear tareas simultáneas y rellenar la lista de tareas de modo que se inserten los elementos en el contenedor. Para realizar esta operación, agregue el siguiente código a la clase Program:

Container container = database.GetContainer(ContainerName);
List<Task> tasks = new List<Task>(AmountToInsert);
foreach (Item item in itemsToInsert)
{
    tasks.Add(container.CreateItemAsync(item, new PartitionKey(item.pk))
        .ContinueWith(itemResponse =>
        {
            if (!itemResponse.IsCompletedSuccessfully)
            {
                AggregateException innerExceptions = itemResponse.Exception.Flatten();
                if (innerExceptions.InnerExceptions.FirstOrDefault(innerEx => innerEx is CosmosException) is CosmosException cosmosException)
                {
                    Console.WriteLine($"Received {cosmosException.StatusCode} ({cosmosException.Message}).");
                }
                else
                {
                    Console.WriteLine($"Exception {innerExceptions.InnerExceptions.FirstOrDefault()}.");
                }
            }
        }));
}

// Wait until all are done
await Task.WhenAll(tasks);

Todas estas operaciones de punto simultáneas se ejecutarán juntas (es decir, en bloque) tal como se describe en la sección de introducción.

Paso 7: Ejecución de la muestra

Puede ejecutar el ejemplo simplemente con el comando dotnet:

dotnet run

Obtención del ejemplo completo

Si no dispuso de tiempo para completar los pasos de este tutorial, o simplemente desea descargar los ejemplos de código, puede obtenerlos de GitHub.

Después de clonar el proyecto, asegúrese de actualizar las credenciales que desee en Program.cs.

El ejemplo se puede ejecutar cambiando al directorio del repositorio y usando dotnet:

cd cosmos-dotnet-bulk-import-throughput-optimizer
dotnet run

Pasos siguientes

En este tutorial ha llevado a cabo los siguientes pasos:

  • Creación de una cuenta de Azure Cosmos DB
  • Configuración del proyecto
  • Conexión a una cuenta de Azure Cosmos DB con compatibilidad para la ejecución en bloque habilitada
  • Realización de una importación de datos mediante operaciones simultáneas de creación

Ahora puede continuar en el siguiente tutorial:

¿Intenta planear la capacidad de una migración a Azure Cosmos DB? Para ello, puede usar información sobre el clúster de bases de datos existente.