Ingerir dados em massa no Gremlin do Azure Cosmos DB usando uma biblioteca de executor em massa

APLICA-SE A: Gremlin

Os bancos de dados de grafo geralmente precisam ingerir dados em massa para atualizar um grafo inteiro ou atualizar uma parte dele. O Azure Cosmos DB, um banco de dados distribuído e o backbone do Gremlin do Azure Cosmos DB, é destinado a funcionar melhor quando as cargas estão bem-distribuídas. As bibliotecas de executor em massa no Azure Cosmos DB foram projetadas para explorar essa capacidade exclusiva do Azure Cosmos DB e fornecer um desempenho ideal. Para obter mais informações, consulte Introdução ao suporte em massa no SDK do .NET.

Neste tutorial, você aprende como usar a biblioteca do executor em massa do Azure Cosmos DB para importar e atualizar objetos de grafo em um contêiner Gremlin do Azure Cosmos DB. Durante esse processo, você usa a biblioteca para criar objetos de vértice e borda programaticamente e, em seguida, inserir vários objetos por solicitação de rede.

Em vez de enviar consultas do Gremlin para um banco de dados, onde os comandos são avaliados e, em seguida, executados um a um, você usa a biblioteca do executor em massa para criar e validar os objetos localmente. Depois de a biblioteca inicializar os objetos de grafo, ela permitirá que você os envie para o serviço de banco de dados em sequência.

Usando esse método, você pode aumentar as velocidades de ingestão de dados até cem vezes, o que o torna uma maneira ideal de executar migrações de dados iniciais ou operações periódicas de movimentação de dados.

A biblioteca de executor em massa agora vem nas seguintes variedades.

.NET

Pré-requisitos

Antes de começar, certifique-se do seguinte:

Clone

Para usar esta amostra, execute o seguinte comando:

git clone https://github.com/Azure-Samples/azure-cosmos-graph-bulk-executor.git

Para obter o exemplo, acesse o .\azure-cosmos-graph-bulk-executor\dotnet\src\.

Amostra


IGraphBulkExecutor graphBulkExecutor = new GraphBulkExecutor("MyConnectionString", "myDatabase", "myContainer");

List<IGremlinElement> gremlinElements = new List<IGremlinElement>();
gremlinElements.AddRange(Program.GenerateVertices(Program.documentsToInsert));
gremlinElements.AddRange(Program.GenerateEdges(Program.documentsToInsert));
BulkOperationResponse bulkOperationResponse = await graphBulkExecutor.BulkImportAsync(
    gremlinElements: gremlinElements,
    enableUpsert: true);

Execute (executar)

Modifique os parâmetros, conforme descrito na tabela a seguir:

Parâmetro Descrição
ConnectionString Sua cadeia de conexão de serviço, que você encontrará na seção Chaves da sua conta do Azure Cosmos DB para Gremlin. Está formatado como AccountEndpoint=https://<account-name>.documents.azure.com:443/;AccountKey=<account-key>;.
DatabaseName, ContainerName Os nomes do banco de dados de destino e do contêiner.
DocumentsToInsert O número de documentos a serem gerados (relevantes apenas para dados sintéticos).
PartitionKey Garante que uma chave de partição seja especificada com cada documento durante a ingestão de dados.
NumberOfRUs Só será relevante se um contêiner ainda não existir e precisar ser criado durante a execução.

Baixe o aplicativo de exemplo completo no .NET.

Java

Amostra de uso

O seguinte aplicativo de exemplo ilustra como usar o pacote GraphBulkExecutor. Os exemplos usam as anotações de objeto de domínio ou os objetos POJO (objeto Java simples e antigo) diretamente. Recomendamos tentar as duas abordagens para determinar qual atende melhor às suas demandas de implementação e desempenho.

Clone

Para usar o exemplo, execute o seguinte comando:

git clone https://github.com/Azure-Samples/azure-cosmos-graph-bulk-executor.git

Para obter o exemplo, acesse o .\azure-cosmos-graph-bulk-executor\java\.

Pré-requisitos

Para executar esse exemplo, você precisa ter o seguinte software:

  • OpenJDK 11
  • Maven
  • Uma conta do Azure Cosmos DB configurada para usar a API do Gremlin

Amostra

private static void executeWithPOJO(Stream<GremlinVertex> vertices,
                                        Stream<GremlinEdge> edges,
                                        boolean createDocs) {
        results.transitionState("Configure Database");
        UploadWithBulkLoader loader = new UploadWithBulkLoader();
        results.transitionState("Write Documents");
        loader.uploadDocuments(vertices, edges, createDocs);
    }

Configuração

Para executar o exemplo, consulte a configuração a seguir e modifique conforme o necessário.

O arquivo /resources/application.properties define os dados necessários para configurar o Azure Cosmos DB. Os valores necessários são descritos na tabela a seguir:

Propriedade Descrição
sample.sql.host O valor que é fornecido pelo Azure Cosmos DB. Verifique se você está usando o URI do SDK do .NET, que você encontrará na seção Visão geral da conta do Azure Cosmos DB.
sample.sql.key Você pode obter a chave primária ou secundária na seção Chaves da conta do Azure Cosmos DB.
sample.sql.database.name O nome do banco de dados na conta do Azure Cosmos DB na qual executar o exemplo. Se o banco de dados não for encontrado, o código de exemplo o criará.
sample.sql.container.name O nome do contêiner no banco de dados no qual executar o exemplo. Se o contêiner não for encontrado, o código de exemplo o criará.
sample.sql.partition.path Se você precisar criar o contêiner, use esse valor para definir o caminho partitionKey.
sample.sql.allow.throughput O contêiner será atualizado para usar o valor de taxa de transferência definido aqui. Se você estiver explorando várias opções de taxa de transferência para atender às suas demandas de desempenho, redefina a taxa de transferência no contêiner quando terminar a exploração. Há custos associados à saída do contêiner provisionado com uma taxa de transferência mais alta.

Execute (executar)

Depois de modificar a configuração de acordo com seu ambiente, execute o seguinte comando:

mvn clean package 

Para maior segurança, você também pode executar os testes de integração alterando o valor skipIntegrationTests no arquivo pom.xml para false.

Depois de executar os testes de unidade com êxito, você poderá executar o código de exemplo:

java -jar target/azure-cosmos-graph-bulk-executor-1.0-jar-with-dependencies.jar -v 1000 -e 10 -d

Executar o comando anterior executa o exemplo com um lote pequeno (1.000 vértices e aproximadamente 5.000 bordas). Use os argumentos de linha de comando nas seções a seguir para ajustar os volumes executados e qual versão de exemplo será executada.

Argumentos de linha de comando

Vários argumentos de linha de comando estão disponíveis enquanto você executa este exemplo, conforme descrito na tabela a seguir:

Argumento Descrição
--vertexCount (-v) Informa ao aplicativo quantos vértices de pessoa gerar.
--edgeMax (-e) Informa ao aplicativo o número máximo de bordas a serem geradas para cada vértice. O gerador seleciona aleatoriamente um número de 1 para o valor fornecido.
--domainSample (-d) Informa ao aplicativo para executar o exemplo usando as estruturas de domínio de pessoa e relacionamento em vez dos POJOs GraphBulkExecutors, GremlinVertex e GremlinEdge.
--createDocuments (-c) Informa ao aplicativo para usar operações create. Se o argumento não estiver presente, o aplicativo usará operações upsert.

Informações de exemplo detalhadas

Vértice de pessoa

A classe de pessoa é um objeto de domínio simples que foi decorado com várias anotações para ajudar uma transformação na classe GremlinVertex, conforme descrito na tabela a seguir:

Anotação de classe Descrição
GremlinVertex Usa o parâmetro opcional label para definir todos os vértices que você cria usando essa classe.
GremlinId Usado para definir qual campo será usado como o valor ID. O nome do campo na classe de pessoa é ID, mas não é necessário.
GremlinProperty Usado no campo email para alterar o nome da propriedade quando armazenado no banco de dados.
GremlinPartitionKey Usado para definir qual campo na classe contém a chave de partição. O nome do campo fornecido deve corresponder ao valor definido pelo caminho de partição no contêiner.
GremlinIgnore Usado para excluir o campo isSpecial da propriedade que está sendo gravada no banco de dados.

A classe RelationshipEdge

A classe RelationshipEdge é um objeto de domínio versátil. Usando a anotação de rótulo de nível de campo, você pode criar uma coleção dinâmica de tipos de borda, conforme mostrado na tabela a seguir:

Anotação de classe Descrição
GremlinEdge A decoração GremlinEdge na classe define o nome do campo para a chave de partição especificada. Quando você cria um documento de borda, o valor atribuído vem das informações de vértice de origem.
GremlinEdgeVertex Duas instâncias de GremlinEdgeVertex são definidas, uma para cada lado da borda (origem e destino). Nosso exemplo tem o tipo de dados do campo como GremlinEdgeVertexInfo. As informações fornecidas pela classe GremlinEdgeVertex são necessárias para que a borda seja criada corretamente no banco de dados. Outra opção seria fazer com que o tipo de dados dos vértices fosse uma classe decorada com as anotações de GremlinVertex.
GremlinLabel A borda de exemplo usa um campo para definir o valor label. Ela permite que vários rótulos sejam definidos, pois usa a mesma classe de domínio base.

Saída explicada

O console terminará sua execução com uma cadeia de caracteres JSON que descreve os tempos de execução do exemplo. A cadeia de caracteres JSON contém as informações a seguir:

cadeia de caracteres JSON Descrição
startTime System.nanoTime() quando o processo foi iniciado.
endTime System.nanoTime() quando o processo foi concluído.
durationInNanoSeconds A diferença entre os valores endTime e startTime.
durationInMinutes O valor durationInNanoSeconds, convertido em minutos. O valor durationInMinutes é representado como um número flutuante, não um valor temporal. Por exemplo, um valor de 2,5 representa dois minutos e 30 segundos.
vertexCount O volume de vértices gerados que deve corresponder ao valor passado para a execução da linha de comando.
edgeCount O volume de bordas gerado que não é estático e é criado com um elemento de aleatoriedade.
exception Preenchido somente se uma exceção for lançada quando você tentar fazer a execução.

Matriz de estados

A matriz de estados fornece informações sobre o tempo usado por cada etapa dentro da execução. As etapas são descritas na tabela a seguir:

Etapa de execução Descrição
Compilar vértices de exemplo O tempo necessário para fabricar o volume solicitado de objetos de pessoa.
Criar bordas de exemplo O tempo necessário para fabricar os objetos de relacionamento.
Configurar o banco de dados O tempo necessário para configurar o banco de dados, com base nos valores fornecidos em application.properties.
Gravar documentos O tempo necessário para gravar os documentos no banco de dados.

Cada estado contém os seguintes valores:

Valor de estado Descrição
stateName O nome do estado que está sendo relatado.
startTime O valor System.nanoTime() quando o estado foi iniciado.
endTime O valor System.nanoTime() quando o estado foi concluído.
durationInNanoSeconds A diferença entre os valores endTime e startTime.
durationInMinutes O valor durationInNanoSeconds, convertido em minutos. O valor durationInMinutes é representado como um número flutuante, não um valor temporal. Por exemplo, um valor de 2,5 representa dois minutos e 30 segundos.

Próximas etapas