Dela via


Migrera från CouchBase till Azure Cosmos DB för NoSQL

GÄLLER FÖR: NoSQL

Azure Cosmos DB är en skalbar, globalt distribuerad, fullständigt hanterad databas. Det ger garanterad åtkomst till dina data med låg latens. Mer information om Azure Cosmos DB finns i översiktsartikeln. Den här artikeln innehåller instruktioner för att migrera Java-program som är anslutna till Couchbase till ett API för NoSQL-konto i Azure Cosmos DB.

Skillnader i nomenklatur

Följande är de viktigaste funktionerna som fungerar annorlunda i Azure Cosmos DB jämfört med Couchbase:

Couchbase Azure Cosmos DB
Couchbase-server Konto
Hink Databas
Hink Container/samling
JSON-dokument Objekt/dokument

Viktiga skillnader

  • Azure Cosmos DB har ett "ID"-fält i dokumentet medan Couchbase har ID:t som en del av bucketen. Fältet "ID" är unikt i partitionen.

  • Azure Cosmos DB skalar med hjälp av partitionerings- eller horisontell partitioneringstekniken. Det innebär att data delas upp i flera shards/partitioner. Dessa partitioner/shards skapas baserat på den partitionsnyckelegenskap som du anger. Du kan välja partitionsnyckeln för att optimera läs- och skrivåtgärder eller läs-/skrivoptimerad också. Mer information finns i partitioneringsartikeln.

  • I Azure Cosmos DB krävs det inte att hierarkin på den översta nivån anger samlingen eftersom samlingsnamnet redan finns. Den här funktionen gör JSON-strukturen enklare. Följande är ett exempel som visar skillnader i datamodellen mellan Couchbase och Azure Cosmos DB:

    Couchbase: Dokument-ID = "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: Referera till "ID" i dokumentet enligt nedan

    {
      "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"
          }
        ]
      }
    

Stöd för Java SDK

Azure Cosmos DB har följande programutvecklingspaket (SDK:er) för att stödja olika Java-ramverk:

  • Async SDK
  • Spring Boot SDK

I följande avsnitt beskrivs när du ska använda var och en av dessa SDK:er. Tänk dig ett exempel där vi har tre typer av arbetsbelastningar:

Couchbase som dokumentlagringsplats och springdatabaserade anpassade frågor

Om den arbetsbelastning som du migrerar baseras på Spring Boot Based SDK kan du använda följande steg:

  1. Lägg till överordnad i filen POM.xml:

    <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.1.5.RELEASE</version>
       <relativePath/>
    </parent>
    
  2. Lägg till egenskaper i filen POM.xml:

    <azure.version>2.1.6</azure.version>
    
  3. Lägg till beroenden i POM.xml-filen:

    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-cosmosdb-spring-boot-starter</artifactId>
        <version>2.1.6</version>
    </dependency>
    
  4. Lägg till programegenskaper under resurser och ange följande. Ersätt parametrarna URL, nyckel och databasnamn:

       azure.cosmosdb.uri=<your-cosmosDB-URL>
       azure.cosmosdb.key=<your-cosmosDB-key>
       azure.cosmosdb.database=<your-cosmosDB-dbName>
    
  5. Definiera namnet på samlingen i modellen. Du kan också ange ytterligare anteckningar. Till exempel ID, partitionsnyckel för att uttryckligen ange dem:

    @Document(collection = "mycollection")
        public class User {
            @id
            private String id;
            private String firstName;
            @PartitionKey
            private String lastName;
        }
    

Följande är kodfragmenten för CRUD-åtgärder:

Infoga och uppdatera åtgärder

Där _repo är objektet för lagringsplatsen och dokumentet är POJO-klassens objekt. Du kan använda .save för att infoga eller upsert (om dokumentet med angivet ID hittades). Följande kodfragment visar hur du infogar eller uppdaterar ett dokumentobjekt:

_repo.save(doc);

Ta bort åtgärd

Överväg följande kodfragment, där dokumentobjektet har ID och partitionsnyckel obligatoriskt för att hitta och ta bort objektet:

_repo.delete(doc);

Läsåtgärd

Du kan läsa dokumentet med eller utan att ange partitionsnyckeln. Om du inte anger partitionsnyckeln behandlas den som en fråga mellan partitioner. Tänk på följande kodexempel. Först utför du åtgärden med hjälp av ID och partitionsnyckelfältet. Det andra exemplet använder ett vanligt fält & utan att ange partitionsnyckelfältet.

  • _repo.findByIdAndName(objDoc.getId(),objDoc.getName());
  • _repo.findAllByStatus(objDoc.getStatus());

Nu kan du använda ditt program med Azure Cosmos DB. Komplett kodexempel för exemplet som beskrivs i det här dokumentet finns i GitHub-lagringsplatsen CouchbaseToCosmosDB-SpringCosmos .

Couchbase som dokumentlagringsplats och med N1QL-frågor

N1QL-frågor är ett sätt att definiera frågor i Couchbase.

N1QL-fråga Azure Cosmos DB-fråga
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" och c.country = 'India' and m.type = 'Multi-Entry' and m.Country IN ('India', 'Bhutan') ORDER BY c.Validity DESC OFFSET 0 LIMIT 25

Du kan se följande ändringar i dina N1QL-frågor:

  • Du behöver inte använda nyckelordet META eller referera till dokumentet på första nivån. I stället kan du skapa en egen referens till containern. I det här exemplet har vi betraktat det som "c" (det kan vara vad som helst). Den här referensen används som ett prefix för alla fält på första nivån. Fr exempel, c.id, c.country osv.

  • I stället för "ANY" nu kan du göra en koppling i underdokumentet och referera till det med ett dedikerat alias som "m". När du har skapat alias för ett underdokument måste du använda alias. Till exempel m.Country.

  • Sekvensen för OFFSET skiljer sig i Azure Cosmos DB-frågan, först måste du ange OFFSET och sedan LIMIT. Vi rekommenderar att du inte använder Spring Data SDK om du använder maximalt antal anpassade definierade frågor eftersom det kan ha onödiga omkostnader på klientsidan när du skickar frågan till Azure Cosmos DB. I stället har vi en direkt Async Java SDK, som kan användas mycket effektivt i det här fallet.

Läsåtgärd

Använd Async Java SDK med följande steg:

  1. Konfigurera följande beroende på POM.xml-filen:

    <!-- 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>
    
  2. Skapa ett anslutningsobjekt för Azure Cosmos DB med hjälp av metoden ConnectionBuilder som visas i följande exempel. Se till att du placerar den här deklarationen i bönan så att följande kod bara ska köras en gång:

    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);
    
  3. För att köra frågan måste du köra följande kodfragment:

    Flux<FeedResponse<CosmosItemProperties>> objFlux= container.queryItems(query, fo);
    

Nu kan du med hjälp av ovanstående metod skicka flera frågor och köra utan krångel. Om du har kravet på att köra en stor fråga, som kan delas upp i flera frågor, kan du prova följande kodfragment i stället för det föregående:

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

Med den tidigare koden kan du köra frågor parallellt och öka de distribuerade körningarna för att optimera. Du kan också köra infognings- och uppdateringsåtgärderna:

Infoga åtgärd

Om du vill infoga dokumentet kör du följande kod:

Mono<CosmosItemResponse> objMono= container.createItem(doc,ro);

Prenumerera sedan på Mono som:

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

Upsert-åtgärd

Upsert-åtgärden kräver att du anger det dokument som måste uppdateras. Om du vill hämta det fullständiga dokumentet kan du använda kodfragmentet som nämns under rubrikläsningsåtgärden och sedan ändra de obligatoriska fälten. Följande kodfragment upserts dokumentet:

Mono<CosmosItemResponse> obs= container.upsertItem(doc, ro);

Prenumerera sedan på mono. Se monoprenumerationsfragmentet i insert-åtgärden.

Ta bort åtgärd

Följande kodfragment utför borttagningsåtgärden:

CosmosItem objItem= container.getItem(doc.Id, doc.Tenant);
Mono<CosmosItemResponse> objMono = objItem.delete(ro);

Prenumerera sedan på mono, referera till monoprenumerationsfragment i insert-åtgärden. Det fullständiga kodexemplet är tillgängligt i GitHub-lagringsplatsen CouchbaseToCosmosDB-AsyncInSpring .

Couchbase som ett nyckel/värde-par

Det här är en enkel typ av arbetsbelastning där du kan utföra sökningar i stället för frågor. Använd följande steg för nyckel/värde-par:

  1. Överväg att ha "/ID" som primärnyckel, vilket säkerställer att du kan utföra uppslagsåtgärden direkt i den specifika partitionen. Skapa en samling och ange "/ID" som partitionsnyckel.

  2. Stäng av indexeringen helt. Eftersom du kommer att köra uppslagsåtgärder finns det ingen poäng med att bära indexeringskostnader. Om du vill inaktivera indexering loggar du in på Azure Portal, goto Azure Cosmos DB-konto. Öppna Datautforskaren och välj din databas och containern. Öppna fliken Skalning och inställningar och välj indexeringsprincipen. För närvarande ser indexeringsprincipen ut så här:

    {
     "indexingMode": "consistent",
     "automatic": true,
     "includedPaths": [
         {
             "path": "/*"
         }
     ],
     "excludedPaths": [
         {
             "path": "/\"_etag\"/?"
         }
     ]
     }
    

    Ersätt indexeringsprincipen ovan med följande princip:

    {
     "indexingMode": "none",
     "automatic": false,
     "includedPaths": [],
     "excludedPaths": []
     }
    
  3. Använd följande kodfragment för att skapa anslutningsobjektet. Anslutningsobjekt (som ska placeras i @Bean eller göra det statiskt):

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

Nu kan du köra CRUD-åtgärderna på följande sätt:

Läsåtgärd

Om du vill läsa objektet använder du följande kodfragment:

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

Infoga åtgärd

Om du vill infoga ett objekt kan du utföra följande kod:

Mono<CosmosItemResponse> objMono= container.createItem(doc,ro);

Prenumerera sedan på mono som:

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

Upsert-åtgärd

Om du vill uppdatera värdet för ett objekt läser du kodfragmentet nedan:

Mono<CosmosItemResponse> obs= container.upsertItem(doc, ro);

Prenumerera sedan på mono, referera till monoprenumerationsfragment i insert-åtgärden.

Ta bort åtgärd

Använd följande kodfragment för att köra borttagningsåtgärden:

CosmosItem objItem= container.getItem(id, id);
Mono<CosmosItemResponse> objMono = objItem.delete(ro);

Prenumerera sedan på mono, referera till monoprenumerationsfragment i insert-åtgärden. Det fullständiga kodexemplet är tillgängligt i GitHub-lagringsplatsen CouchbaseToCosmosDB-AsyncKeyValue .

Datamigrering

Använd Azure Data Factory för att migrera data. Det här är den mest rekommenderade metoden för att migrera data. Konfigurera källan som Couchbase och mottagare som Azure Cosmos DB för NoSQL. Mer information finns i azure Azure Cosmos DB Data Factory-anslutningsappen .

Nästa steg