Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
O Azure Cosmos DB é um banco de dados escalonável, distribuído globalmente e totalmente gerenciado. Ele fornece acesso garantido de baixa latência aos seus dados. Para saber mais sobre o Azure Cosmos DB, veja o artigo de visão geral. Este artigo fornece instruções para migrar aplicativos Java conectados ao Couchbase para uma conta da API para NoSQL no Azure Cosmos DB.
Diferenças na nomenclatura
Veja a seguir os principais recursos que funcionam de forma diferente no Azure Cosmos DB quando comparados ao Couchbase:
| Couchbase | Azure Cosmos DB |
|---|---|
| Servidor Couchbase | Conta |
| Bucket | Base de dados |
| Bucket | Contêiner/coleção |
| Documento JSON | Item/Documento |
Principais diferenças
O Azure Cosmos DB tem um campo "ID" dentro do documento, enquanto o Couchbase tem a ID como parte do bucket. O campo "ID" é exclusivo na partição.
O Azure Cosmos DB é dimensionado usando a técnica de particionamento ou fragmentação. O que significa que ele divide os dados em vários fragmentos/partições. Essas partições/fragmentos são criados com base na propriedade de chave de partição que você fornece. Você pode selecionar a chave de partição para otimizar as operações de leitura e gravação ou também a leitura/gravação otimizada. Para saber mais, confira o artigo de particionamento .
No Azure Cosmos DB, não é necessário que a hierarquia de nível superior denote a coleção porque o nome da coleção já existe. Esse recurso torna a estrutura JSON mais simples. Veja a seguir um exemplo que mostra as diferenças no modelo de dados entre o Couchbase e o Azure Cosmos DB:
Couchbase: ID do documento = "99FF4444"
{ "TravelDocument": { "Country":"India", "Validity" : "2022-09-01", "Person": { "Name": "Manish", "Address": "AB Road, City-z" }, "Visas": [ { "Country":"India", "Type":"Multi-Entry", "Validity":"2022-09-01" }, { "Country":"US", "Type":"Single-Entry", "Validity":"2022-08-01" } ] } }Azure Cosmos DB: consulte o “ID” dentro do documento, conforme mostrado abaixo
{ "id" : "99FF4444", "Country":"India", "Validity" : "2022-09-01", "Person": { "Name": "Manish", "Address": "AB Road, City-z" }, "Visas": [ { "Country":"India", "Type":"Multi-Entry", "Validity":"2022-09-01" }, { "Country":"US", "Type":"Single-Entry", "Validity":"2022-08-01" } ] }
Suporte ao SDK do Java
O Azure Cosmos DB tem os seguintes SDKs (kits de desenvolvimento de software) para dar suporte a diferentes estruturas Java:
- SDK assíncrono
- Spring Boot SDK
As seções a seguir descrevem quando usar cada um desses SDKs. Considere um exemplo em que temos três tipos de cargas de trabalho:
Couchbase como repositório de documentos e consultas personalizadas baseadas em dados do Spring
Se a carga de trabalho que você está migrando for baseada no SDK baseado no Spring Boot, você poderá usar as seguintes etapas:
Adicione o pai ao arquivo POM.xml:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath/> </parent>Adicione propriedades ao arquivo POM.xml:
<azure.version>2.1.6</azure.version>Adicione dependências ao arquivo POM.xml:
<dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure-cosmosdb-spring-boot-starter</artifactId> <version>2.1.6</version> </dependency>Adicione propriedades de aplicativo em recursos e especifique o seguinte. Substitua os parâmetros url, chave e nome do banco de dados:
azure.cosmosdb.uri=<your-cosmosDB-URL> azure.cosmosdb.key=<your-cosmosDB-key> azure.cosmosdb.database=<your-cosmosDB-dbName>Defina o nome da coleção no modelo. Você também pode especificar outras anotações. Por exemplo, ID, chave de partição para denotá-los explicitamente:
@Document(collection = "mycollection") public class User { @id private String id; private String firstName; @PartitionKey private String lastName; }
Veja a seguir os snippets de código para operações CRUD:
Operações de inserção e atualização
Onde _repo é o objeto do repositório e doc é o objeto da classe POJO. Você pode usar .save para inserir ou atualizar (se o documento com o ID especificado for encontrado). O snippet de código a seguir mostra como inserir ou atualizar um objeto doc:
_repo.save(doc);
Operação de exclusão
Considere o seguinte trecho de código, em que o objeto doc terá o ID e a chave de partição obrigatórios para localizar e excluir o objeto:
_repo.delete(doc);
Operação de leitura
Você pode ler o documento com ou sem especificar a chave de partição. Se você não especificar a chave de partição, ela será tratada como uma consulta entre partições. Considere os exemplos de código a seguir, o primeiro executará a operação usando a ID e o campo de chave de partição. O segundo exemplo usa um campo regular e sem especificar o campo de chave de partição.
_repo.findByIdAndName(objDoc.getId(),objDoc.getName());_repo.findAllByStatus(objDoc.getStatus());
É isso, agora você pode usar seu aplicativo com o Azure Cosmos DB. O exemplo de código completo para o exemplo descrito neste documento está disponível no repositório GitHub CouchbaseToCosmosDB-SpringCosmos .
Couchbase como um repositório de documentos e usando consultas N1QL
Consultas N1QL são a maneira de definir consultas no Couchbase.
| Consulta N1QL | Consulta do Azure Cosmos DB |
|---|---|
SELECT META(TravelDocument).id AS id, TravelDocument.* FROM TravelDocument WHERE _type = "com.xx.xx.xx.xxx.xxx.xxxx " and country = 'India’ and ANY m in Visas SATISFIES m.type == 'Multi-Entry' and m.Country IN ['India', Bhutan’] ORDER BY Validity DESC LIMIT 25 OFFSET 0 |
SELECT c.id,c FROM c JOIN m in c.country=’India’ WHERE c._type = " com.xx.xx.xx.xxx.xxx.xxxx" and c.country = 'India' and m.type = 'Multi-Entry' and m.Country IN ('India', 'Bhutan') ORDER BY c.Validity DESC OFFSET 0 LIMIT 25 |
Você pode observar as seguintes alterações em suas consultas N1QL:
Você não precisa usar a palavra-chave META ou fazer referência ao documento de primeiro nível. Em vez disso, você pode criar sua própria referência ao contêiner. Neste exemplo, consideramos isso como "c" (pode ser qualquer coisa). Essa referência é usada como um prefixo para todos os campos de primeiro nível. Por exemplo, c.id, c.country, etc.
Em vez de “ANY”, agora você pode fazer uma junção no subdocumento e consultá-lo com um alias dedicado, como “m”. Depois de criar o alias para um subdocumento, você precisará usar o alias. Por exemplo, m.Country.
A sequência de OFFSET é diferente na consulta do Azure Cosmos DB, primeiro você precisa especificar OFFSET e LIMIT. É recomendável não usar o SDK do Spring Data se você estiver usando o máximo de consultas personalizadas definidas, pois ele pode ter uma sobrecarga desnecessária no lado do cliente ao passar a consulta para o Azure Cosmos DB. Em vez disso, temos um SDK de Java Assíncrono direto, que pode ser utilizado com muita eficiência nesse caso.
Operação de leitura
Use o SDK do Java Assíncrono com as seguintes etapas:
Configure a seguinte dependência no arquivo POM.xml:
<!-- https://mvnrepository.com/artifact/com.microsoft.azure/azure-cosmosdb --> <dependency> <groupId>com.microsoft.azure</groupId> <artifactId>azure-cosmos</artifactId> <version>3.0.0</version> </dependency>Crie um objeto de conexão para o Azure Cosmos DB usando o
ConnectionBuildermétodo, conforme mostrado no exemplo a seguir. Certifique-se de colocar essa declaração no bean de modo que o código a seguir deve ser executado apenas uma vez:ConnectionPolicy cp=new ConnectionPolicy(); cp.connectionMode(ConnectionMode.DIRECT); if(client==null) client= CosmosClient.builder() .endpoint(Host)//(Host, PrimaryKey, dbName, collName).Builder() .connectionPolicy(cp) .key(PrimaryKey) .consistencyLevel(ConsistencyLevel.EVENTUAL) .build(); container = client.getDatabase(_dbName).getContainer(_collName);Para executar a consulta, você precisa executar o seguinte snippet de código:
Flux<FeedResponse<CosmosItemProperties>> objFlux= container.queryItems(query, fo);
Agora, com a ajuda do método acima, você pode passar várias consultas e executar sem nenhum incômodo. Caso você tenha o requisito de executar uma consulta grande, que pode ser dividida em várias consultas, tente o seguinte snippet de código em vez da anterior:
for(SqlQuerySpec query:queries)
{
objFlux= container.queryItems(query, fo);
objFlux .publishOn(Schedulers.elastic())
.subscribe(feedResponse->
{
if(feedResponse.results().size()>0)
{
_docs.addAll(feedResponse.results());
}
},
Throwable::printStackTrace,latch::countDown);
lstFlux.add(objFlux);
}
Flux.merge(lstFlux);
latch.await();
}
Com o código anterior, você pode executar consultas em paralelo e aumentar as execuções distribuídas para otimizar. Além disso, você também pode executar as operações de inserção e atualização:
Operação de inserção
Para inserir o documento, execute o seguinte código:
Mono<CosmosItemResponse> objMono= container.createItem(doc,ro);
Em seguida, assine o Mono como:
CountDownLatch latch=new CountDownLatch(1);
objMono .subscribeOn(Schedulers.elastic())
.subscribe(resourceResponse->
{
if(resourceResponse.statusCode()!=successStatus)
{
throw new RuntimeException(resourceResponse.toString());
}
},
Throwable::printStackTrace,latch::countDown);
latch.await();
Operação upsert
A operação upsert exige que você especifique o documento que precisa ser atualizado. Para buscar o documento completo, você pode usar o snippet mencionado na operação de leitura de título e modificar os campos necessários. O seguinte snippet de código upserts o documento:
Mono<CosmosItemResponse> obs= container.upsertItem(doc, ro);
Em seguida, assine o mono. Consulte o snippet de assinatura do mono na operação de inserção.
Operação de exclusão
O snippet a seguir executará a operação de exclusão:
CosmosItem objItem= container.getItem(doc.Id, doc.Tenant);
Mono<CosmosItemResponse> objMono = objItem.delete(ro);
Em seguida, assine mono, consulte o snippet de assinatura mono na operação de inserção. O exemplo de código completo está disponível no repositório GitHub CouchbaseToCosmosDB-AsyncInSpring .
Couchbase como um par chave/valor
Esse é um tipo simples de carga de trabalho na qual você pode executar pesquisas em vez de consultas. Use as seguintes etapas para pares chave/valor:
Considere ter "/ID" como chave primária, o que garantirá que você possa executar a operação de pesquisa diretamente na partição específica. Crie uma coleção e especifique "/ID" como chave de partição.
Desligue completamente a indexação. Como você executará operações de pesquisa, não faz sentido carregar a sobrecarga de indexação. Para desativar a indexação, entre no portal do Azure e acesse a conta do Azure Cosmos DB. Abra o Data Explorer, selecione o Banco de Dados e o Contêiner. Abra a guia Escala > Configurações e selecione a Política de Indexação. Atualmente, a política de indexação tem a seguinte aparência:
{ "indexingMode": "consistent", "automatic": true, "includedPaths": [ { "path": "/*" } ], "excludedPaths": [ { "path": "/\"_etag\"/?" } ] }Substitua a política de indexação acima pela seguinte política:
{ "indexingMode": "none", "automatic": false, "includedPaths": [], "excludedPaths": [] }Use o snippet de código a seguir para criar o objeto de conexão. Objeto de conexão (a ser colocado em @Bean ou torná-lo estático):
ConnectionPolicy cp=new ConnectionPolicy(); cp.connectionMode(ConnectionMode.DIRECT); if(client==null) client= CosmosClient.builder() .endpoint(Host)//(Host, PrimaryKey, dbName, collName).Builder() .connectionPolicy(cp) .key(PrimaryKey) .consistencyLevel(ConsistencyLevel.EVENTUAL) .build(); container = client.getDatabase(_dbName).getContainer(_collName);
Agora você pode executar as operações CRUD da seguinte maneira:
Operação de leitura
Para ler o item, use o seguinte snippet:
CosmosItemRequestOptions ro=new CosmosItemRequestOptions();
ro.partitionKey(new PartitionKey(documentId));
CountDownLatch latch=new CountDownLatch(1);
var objCosmosItem= container.getItem(documentId, documentId);
Mono<CosmosItemResponse> objMono = objCosmosItem.read(ro);
objMono .subscribeOn(Schedulers.elastic())
.subscribe(resourceResponse->
{
if(resourceResponse.item()!=null)
{
doc= resourceResponse.properties().toObject(UserModel.class);
}
},
Throwable::printStackTrace,latch::countDown);
latch.await();
Operação de inserção
Para inserir um item, você pode executar o seguinte código:
Mono<CosmosItemResponse> objMono= container.createItem(doc,ro);
Em seguida, assine o serviço Mono como:
CountDownLatch latch=new CountDownLatch(1);
objMono.subscribeOn(Schedulers.elastic())
.subscribe(resourceResponse->
{
if(resourceResponse.statusCode()!=successStatus)
{
throw new RuntimeException(resourceResponse.toString());
}
},
Throwable::printStackTrace,latch::countDown);
latch.await();
Operação upsert
Para atualizar o valor de um item, consulte o snippet de código abaixo:
Mono<CosmosItemResponse> obs= container.upsertItem(doc, ro);
Em seguida, assine mono, consulte o snippet de assinatura mono na operação de inserção.
Operação de exclusão
Use o snippet a seguir para executar a operação de exclusão:
CosmosItem objItem= container.getItem(id, id);
Mono<CosmosItemResponse> objMono = objItem.delete(ro);
Em seguida, assine mono, consulte o snippet de assinatura mono na operação de inserção. O exemplo de código completo está disponível no repositório GitHub CouchbaseToCosmosDB-AsyncKeyValue .
Migração de dados
Use Azure Data Factory para migrar dados. Esse é o método mais recomendado para migrar os dados. Configure a origem como Couchbase e o coletor como Azure Cosmos DB for NoSQL. Consulte o artigo Conector do Data Factory do Azure Cosmos DB do Azure para obter as etapas detalhadas.
Próximas etapas
- Para realizar testes de desempenho, consulte o artigo Teste de desempenho e escala com o Azure Cosmos DB.
- Para otimizar o código, consulte o artigo Dicas de desempenho para o Azure Cosmos DB.
- Explore o SDK do Java assíncrono V3, repositório de Referência do SDK do GitHub.