Importar dados em massa para a conta NoSQL do Azure Cosmos DB com o SDK .NET

APLICA-SE A: NoSQL

Este tutorial mostra como criar uma aplicação de consola .NET que otimiza o débito aprovisionado (RU/s) necessário para importar dados para o Azure Cosmos DB.

Neste artigo, irá ler dados de uma origem de dados de exemplo e importá-los para um contentor do Azure Cosmos DB. Este tutorial utiliza a Versão 3.0+ do SDK .NET do Azure Cosmos DB, que pode ser direcionado para .NET Framework ou .NET Core.

Este tutorial aborda:

  • Criar uma conta do Azure Cosmos DB
  • Configurar o projeto
  • Ligar a uma conta do Azure Cosmos DB com suporte em massa ativado
  • Efetuar uma importação de dados através de operações de criação simultâneas

Pré-requisitos

Antes de seguir as instruções neste artigo, certifique-se de que tem os seguintes recursos:

Passo 1: Criar uma conta do Azure Cosmos DB

Crie uma conta do Azure Cosmos DB para NoSQL a partir do portal do Azure ou pode criar a conta com o Emulador do Azure Cosmos DB.

Passo 2: Configurar o projeto .NET

Abra a linha de comandos do Windows ou uma janela de Terminal a partir do seu computador local. Irá executar todos os comandos nas secções seguintes a partir da linha de comandos ou terminal. Execute o seguinte comando dotnet novo para criar uma nova aplicação com o nome bulk-import-demo.

dotnet new console -n bulk-import-demo

Altere o diretório para a pasta da aplicação criada recentemente. Pode criar a aplicação com:

cd bulk-import-demo
dotnet build

O resultado esperado da compilação deve ter um aspeto semelhante ao seguinte:

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

Passo 3: adicionar o pacote do Azure Cosmos DB

Ainda no diretório de aplicações, instale a biblioteca de cliente do Azure Cosmos DB para .NET Core com o comando dotnet add package.

dotnet add package Microsoft.Azure.Cosmos

Passo 4: Obter as credenciais da conta do Azure Cosmos DB

A aplicação de exemplo tem de se autenticar na sua conta do Azure Cosmos DB. Para autenticar, deve transmitir as credenciais da conta do Azure Cosmos DB para a aplicação. Obtenha as credenciais da conta do Azure Cosmos DB ao seguir estes passos:

  1. Inicie sessão no portal do Azure.
  2. Navegue para a sua conta do Azure Cosmos DB.
  3. Abra o painel Chaves e copie o URI e a CHAVE PRIMÁRIA da sua conta.

Se estiver a utilizar o Emulador do Azure Cosmos DB, obtenha as credenciais do emulador neste artigo.

Passo 5: inicializar o objeto CosmosClient com suporte de execução em massa

Abra o ficheiro gerado Program.cs num editor de código. Irá criar uma nova instância do CosmosClient com a execução em massa ativada e utilizá-la para realizar operações no Azure Cosmos DB.

Vamos começar por substituir o método predefinido Main e definir as variáveis globais. Estas variáveis globais incluirão o ponto final e as chaves de autorização, o nome da base de dados, o contentor que irá criar e o número de itens que irá inserir em massa. Confirme que substitui o endpointURL e os valores da chave de autorização de acordo com o seu ambiente.

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 do Main método , adicione o seguinte código para inicializar o objeto CosmosClient:

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

Nota

Depois de especificar a execução em massa nas CosmosClientOptions, são efetivamente imutáveis para a duração do CosmosClient. Alterar os valores não terá qualquer efeito.

Depois de ativar a execução em massa, o CosmosClient agrupa internamente operações simultâneas em chamadas de serviço único. Desta forma, otimiza a utilização do débito ao distribuir chamadas de serviço entre partições e, por fim, atribuir resultados individuais aos autores de chamadas originais.

Em seguida, pode criar um contentor para armazenar todos os nossos itens. Defina /pk como a chave de partição, 50 000 RU/s como débito aprovisionado e uma política de indexação personalizada que excluirá todos os campos para otimizar o débito de escrita. Adicione o seguinte código após a instrução de inicialização 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);

Passo 6: preencher uma lista de tarefas simultâneas

Para tirar partido do suporte de execução em massa, crie uma lista de tarefas assíncronas com base na origem de dados e nas operações que pretende executar e utilize Task.WhenAll para executá-las em simultâneo. Vamos começar por utilizar dados "Bogus" para gerar uma lista de itens a partir do nosso modelo de dados. Numa aplicação do mundo real, os itens viriam da origem de dados pretendida.

Primeiro, adicione o pacote Bogus à solução com o comando dotnet add package.

dotnet add package Bogus

Defina a definição dos itens que pretende guardar. Tem de definir a Item classe no Program.cs ficheiro:

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

    public string username{get;set;}
}

Em seguida, crie uma função auxiliar dentro da Program classe . Esta função auxiliar irá obter o número de itens que definiu para inserir e gera dados aleatórios:

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

Utilize a função auxiliar para inicializar uma lista de documentos para trabalhar com:

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

Em seguida, utilize a lista de documentos para criar tarefas simultâneas e preencher a lista de tarefas para inserir os itens no contentor. Para efetuar esta operação, adicione o seguinte código à Program classe :

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 operações simultâneas de pontos serão executadas em conjunto (ou seja, em massa), conforme descrito na secção de introdução.

Passo 7: Executar o exemplo

Para executar o exemplo, pode fazê-lo simplesmente pelo dotnet comando :

dotnet run

Obter o exemplo completo

Se não tiver tempo de completar os passos deste tutorial, ou apenas pretender transferir os exemplos de código, pode obtê-los a partir do GitHub.

Depois de clonar o projeto, certifique-se de que atualiza as credenciais pretendidas dentro de Program.cs.

O exemplo pode ser executado ao mudar para o diretório do repositório e ao utilizar dotnet:

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

Passos seguintes

Neste tutorial, efetuou os seguintes passos:

  • Criar uma conta do Azure Cosmos DB
  • Configurar o projeto
  • Ligar a uma conta do Azure Cosmos DB com suporte em massa ativado
  • Efetuar uma importação de dados através de operações de criação simultâneas

Agora, pode avançar para o próximo tutorial:

Está a tentar planear a capacidade de uma migração para o Azure Cosmos DB? Pode utilizar informações sobre o cluster de bases de dados existentes para o planeamento de capacidade.