Importare in blocco i dati nell'account Azure Cosmos DB per NoSQL usando .NET SDK

APPLICABILE A: NoSQL

In questa esercitazione viene illustrato come creare un'applicazione console .NET per ottimizzare la velocità effettiva con provisioning (UR/sec) necessaria per importare dati in Azure Cosmos DB.

In questo articolo i dati verranno letti da un’origine dati campione e importati in un contenitore Azure Cosmos DB. Questa esercitazione usa la versione 3.0+ di Azure Cosmos DB .NET SDK, che può essere destinata a .NET Framework o a .NET Core.

Contenuto dell'esercitazione:

  • Creazione di un account di Azure Cosmos DB
  • Configurazione del progetto
  • Connessione a un account Azure Cosmos DB con il supporto dell'esecuzione in blocco abilitato
  • Eseguire un'importazione dati tramite operazioni di creazione simultanee

Prerequisiti

Prima di seguire le istruzioni di questo articolo, verificare di avere le risorse seguenti:

Passaggio 1: Creare un account di Azure Cosmos DB

Creare un account Azure Cosmos DB per NoSQL dal portale di Azure, oppure creare l'account usando l'emulatore Azure Cosmos DB.

Passaggio 2: Configurare il progetto .NET

Aprire il prompt dei comandi di Windows o una finestra del terminale dal computer locale. Tutti i comandi delle sezioni successive dovranno essere eseguiti dal prompt dei comandi o dal terminale. Eseguire il comando dotnet new riportato di seguito per creare una nuova app denominata bulk-import-demo.

dotnet new console -n bulk-import-demo

Spostarsi nella cartella dell'app appena creata. È possibile compilare l'applicazione con il comando seguente:

cd bulk-import-demo
dotnet build

L'output previsto al termine della creazione dovrebbe essere simile al seguente:

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

Passaggio 3: Aggiungere il pacchetto Azure Cosmos DB

Sempre nella directory dell'applicazione, installare la libreria client di Azure Cosmos DB per .NET Core usando il comando dotnet add package.

dotnet add package Microsoft.Azure.Cosmos

Passaggio 4: Ottenere le credenziali dell'account Azure Cosmos DB

L'applicazione di esempio deve eseguire l'autenticazione all'account Azure Cosmos DB. Per eseguire l'autenticazione, è necessario passare le credenziali dell'account Azure Cosmos DB all'applicazione. Ottenere le credenziali dell'account Azure Cosmos DB seguendo questa procedura:

  1. Accedere al portale di Azure.
  2. Accedere all'account Azure Cosmos DB.
  3. Aprire il riquadro Chiavi e copiare l'URI e la CHIAVE PRIMARIA dell'account.

Se si usa l'emulatore Azure Cosmos DB, ottenere le credenziali dell'emulatore da questo articolo.

Passaggio 5: Inizializzare l'oggetto CosmosClient con supporto dell'esecuzione in blocco

Aprire, in un editor del codice, il file Program.cs generato. Verrà creata una nuova istanza di CosmosClient con esecuzione in blocco abilitata; tale istanza verrà usata per eseguire operazioni su Azure Cosmos DB.

Si inizierà sovrascrivendo il metodo Main predefinito e definendo le variabili globali. Queste variabili globali includeranno gli endpoint e le chiavi di autorizzazione, il nome del database, il contenitore creato e il numero di elementi che verranno inseriti in blocco. Assicurarsi di sostituire i valori endpointURL e AuthorizationKey in base all'ambiente in uso.

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)
     {

     }
}

All'interno del metodo Main aggiungere il codice seguente per inizializzare l'oggetto CosmosClient:

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

Nota

Una volta specificata l'esecuzione in blocco in CosmosClientOptions, queste variabili non cambieranno per tutta la durata di CosmosClient. La modifica dei valori non avrà alcun effetto.

Dopo l'abilitazione dell'esecuzione in blocco, CosmosClient raggruppa internamente le operazioni simultanee in singole chiamate del servizio. In questo modo, ottimizza l'utilizzo della velocità effettiva distribuendo le chiamate del servizio tra le partizioni e assegnando infine i singoli risultati ai chiamanti originari.

È quindi possibile creare un contenitore per archiviare tutti gli elementi. Definire /pk come chiave di partizione, 50000 UR/sec come velocità effettiva con provisioning e un criterio di indicizzazione personalizzato che escluda tutti i campi per ottimizzare la velocità effettiva in scrittura. Aggiungere il codice seguente dopo l'istruzione di inizializzazione di 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);

Passaggio 6: Compilare un elenco di attività simultanee

Per sfruttare i vantaggi del supporto dell'esecuzione in blocco, creare un elenco di attività asincrone in base all'origine dei dati e alle operazioni che si intende eseguire e usare Task.WhenAll per eseguirle contemporaneamente. Per iniziare, usare i dati "Bogus" per generare un elenco di elementi dal modello di dati. In un'applicazione reale gli elementi provengono dall'origine dati desiderata.

Prima di tutto aggiungere il pacchetto Bogus alla soluzione usando il comando dotnet add package.

dotnet add package Bogus

Definire la definizione degli elementi che si intende salvare. È necessario definire la classe Item all'interno del file Program.cs:

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

    public string username{get;set;}
}

Creare quindi una funzione helper all'interno della classe Program. Questa funzione helper otterrà il numero di elementi definiti per l'inserimento e genererà dati casuali:

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);
}

Usare la funzione helper per inizializzare un elenco di documenti da usare:

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

Usare quindi l'elenco dei documenti per creare attività simultanee e compilare l'elenco delle attività per inserire gli elementi nel contenitore. Per eseguire questa operazione, aggiungere il codice seguente alla classe 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);

Tutte queste operazioni punto simultanee verranno eseguite insieme, ovvero in blocco, come descritto nella sezione introduttiva.

Passaggio 7: Eseguire il campione

Per eseguire l'esempio, è sufficiente usare il comando dotnet:

dotnet run

Ottenere l'esempio completo

Se non si ha tempo per completare le procedure dell'esercitazione o se si vogliono solo scaricare gli esempi di codice, è possibile ottenerli da GitHub.

Dopo aver clonato il progetto, assicurarsi di aggiornare le credenziali desiderate all'interno di Program.cs.

È possibile eseguire l'esempio passando alla directory del repository e usando dotnet:

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

Passaggi successivi

In questa esercitazione sono stati eseguiti i passaggi seguenti:

  • Creazione di un account di Azure Cosmos DB
  • Configurazione del progetto
  • Connessione a un account Azure Cosmos DB con il supporto dell'esecuzione in blocco abilitato
  • Eseguire un'importazione dati tramite operazioni di creazione simultanee

È ora possibile passare all'esercitazione successiva:

Si sta tentando di pianificare la capacità per una migrazione ad Azure Cosmos DB? È possibile usare le informazioni del cluster di database esistente per la pianificazione della capacità.