Uw toepassing migreren van Amazon DynamoDB naar Azure Cosmos DB
VAN TOEPASSING OP: NoSQL
Azure Cosmos DB is een schaalbare, wereldwijd gedistribueerde, volledig beheerde database. Het biedt gegarandeerde toegang tot lage latentie tot uw gegevens. Zie het overzichtsartikel voor meer informatie over Azure Cosmos DB. In dit artikel wordt beschreven hoe u uw .NET-toepassing migreert van DynamoDB naar Azure Cosmos DB met minimale codewijzigingen.
Conceptuele verschillen
Hier volgen de belangrijkste conceptuele verschillen tussen Azure Cosmos DB en DynamoDB:
DynamoDB | Azure Cosmos DB |
---|---|
Niet van toepassing | Database |
Tabel | Verzameling |
Artikel | Document |
Kenmerk | Veld |
Secundaire index | Secundaire index |
Primaire sleutel : partitiesleutel | Partitiesleutel |
Primaire sleutel : sorteersleutel | Niet vereist |
Stream | ChangeFeed |
Rekeneenheid schrijven | Aanvraageenheid (Flexibel, kan worden gebruikt voor lees- of schrijfbewerkingen) |
Rekeneenheid lezen | Aanvraageenheid (Flexibel, kan worden gebruikt voor lees- of schrijfbewerkingen) |
Globale tabellen | Niet vereist. U kunt de regio rechtstreeks selecteren tijdens het inrichten van het Azure Cosmos DB-account (u kunt de regio later wijzigen) |
Structurele verschillen
Azure Cosmos DB heeft een eenvoudigere JSON-structuur in vergelijking met die van DynamoDB. In het volgende voorbeeld ziet u de verschillen
DynamoDB:
Het volgende JSON-object vertegenwoordigt de gegevensindeling in DynamoDB
{
TableName: "Music",
KeySchema: [
{
AttributeName: "Artist",
KeyType: "HASH", //Partition key
},
{
AttributeName: "SongTitle",
KeyType: "RANGE" //Sort key
}
],
AttributeDefinitions: [
{
AttributeName: "Artist",
AttributeType: "S"
},
{
AttributeName: "SongTitle",
AttributeType: "S"
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 1,
WriteCapacityUnits: 1
}
}
Azure Cosmos DB:
Het volgende JSON-object vertegenwoordigt de gegevensindeling in Azure Cosmos DB
{
"Artist": "",
"SongTitle": "",
"AlbumTitle": "",
"Year": 9999,
"Price": 0.0,
"Genre": "",
"Tags": ""
}
Uw code migreren
Dit artikel is bedoeld voor het migreren van de code van een toepassing naar Azure Cosmos DB. Dit is het kritieke aspect van databasemigratie. Om de leercurve te verminderen, bevatten de volgende secties een vergelijking van code naast elkaar tussen Amazon DynamoDB en het equivalente codefragment van Azure Cosmos DB.
Kloon de volgende opslagplaats om de broncode te downloaden:
git clone https://github.com/Azure-Samples/DynamoDB-to-CosmosDB
Vereisten
- .NET Framework 4.7.2
- Nieuwste Visual Studio met de Azure-ontwikkelworkload. U kunt aan de slag met de gratis Visual Studio Community IDE. Schakel de Azure-ontwikkelworkload in tijdens het instellen van Visual Studio.
- Toegang tot Azure Cosmos DB for NoSQL-account
- Lokale installatie van Amazon DynamoDB
- Java 8
- Voer de downloadbare versie van Amazon DynamoDB uit op poort 8000 (u kunt de code wijzigen en configureren)
Uw code instellen
Voeg het volgende NuGet-pakket toe aan uw project:
Install-Package Microsoft.Azure.Cosmos
Verbinding maken
DynamoDB:
In Amazon DynamoDB wordt de volgende code gebruikt om verbinding te maken:
AmazonDynamoDBConfig addbConfig = new AmazonDynamoDBConfig() ;
addbConfig.ServiceURL = "endpoint";
try { aws_dynamodbclient = new AmazonDynamoDBClient( addbConfig ); }
Azure Cosmos DB:
Werk uw code bij om Azure Cosmos DB te verbinden met:
client_documentDB = new CosmosClient(
"<nosql-account-endpoint>",
tokenCredential
);
De verbinding optimaliseren in Azure Cosmos DB
Met Azure Cosmos DB kunt u de volgende opties gebruiken om uw verbinding te optimaliseren:
ConnectionMode : gebruik de modus directe verbinding om verbinding te maken met de gegevensknooppunten in de Azure Cosmos DB-service. Gebruik de gatewaymodus alleen om de logische adressen te initialiseren en in de cache te plaatsen en bij updates te vernieuwen. Zie de connectiviteitsmodi voor meer informatie.
ApplicationRegion : deze optie wordt gebruikt om de voorkeursregio voor geo-replicatie in te stellen die wordt gebruikt om te communiceren met Azure Cosmos DB. Zie de wereldwijde distributie voor meer informatie.
ConsistencyLevel : deze optie wordt gebruikt om het standaardconsistentieniveau te overschrijven. Zie consistentieniveaus voor meer informatie.
BulkExecutionMode : deze optie wordt gebruikt om bulkbewerkingen uit te voeren door de eigenschap AllowBulkExecution in te stellen op true. Zie bulkimport voor meer informatie.
client_cosmosDB = new CosmosClient(" Your connection string ",new CosmosClientOptions() { ConnectionMode=ConnectionMode.Direct, ApplicationRegion=Regions.EastUS2, ConsistencyLevel=ConsistencyLevel.Session, AllowBulkExecution=true });
De container maken
DynamoDB:
Als u de gegevens wilt opslaan in Amazon DynamoDB, moet u eerst de tabel maken. In het proces voor het maken van tabellen; u het schema, het sleuteltype en de kenmerken definieert, zoals wordt weergegeven in de volgende code:
// movies_key_schema
public static List<KeySchemaElement> movies_key_schema
= new List<KeySchemaElement>
{
new KeySchemaElement
{
AttributeName = partition_key_name,
KeyType = "HASH"
},
new KeySchemaElement
{
AttributeName = sort_key_name,
KeyType = "RANGE"
}
};
// key names for the Movies table
public const string partition_key_name = "year";
public const string sort_key_name = "title";
public const int readUnits=1, writeUnits=1;
// movie_items_attributes
public static List<AttributeDefinition> movie_items_attributes
= new List<AttributeDefinition>
{
new AttributeDefinition
{
AttributeName = partition_key_name,
AttributeType = "N"
},
new AttributeDefinition
{
AttributeName = sort_key_name,
AttributeType = "S"
}
CreateTableRequest request;
CreateTableResponse response;
// Build the 'CreateTableRequest' structure for the new table
request = new CreateTableRequest
{
TableName = table_name,
AttributeDefinitions = table_attributes,
KeySchema = table_key_schema,
// Provisioned-throughput settings are always required,
// although the local test version of DynamoDB ignores them.
ProvisionedThroughput = new ProvisionedThroughput( readUnits, writeUnits );
};
Azure Cosmos DB:
In Amazon DynamoDB moet u de lees-rekeneenheden inrichten en rekeneenheden schrijven. Terwijl u in Azure Cosmos DB de doorvoer opgeeft als aanvraageenheden (RU/s), die dynamisch kunnen worden gebruikt voor bewerkingen. De gegevens zijn ingedeeld als database --> container--> item. U kunt de doorvoer opgeven op databaseniveau of op verzamelingsniveau of beide.
Een database maken:
await client_cosmosDB.CreateDatabaseIfNotExistsAsync(movies_table_name);
De container maken:
await cosmosDatabase.CreateContainerIfNotExistsAsync(new ContainerProperties() { PartitionKeyPath = "/" + partitionKey, Id = new_collection_name }, provisionedThroughput);
De gegevens laden
DynamoDB:
De volgende code laat zien hoe u de gegevens in Amazon DynamoDB laadt. De filmsArray bestaat uit een lijst met JSON-documenten, dan moet u het JSON-document herhalen en laden in Amazon DynamoDB:
int n = moviesArray.Count;
for( int i = 0, j = 99; i < n; i++ )
{
try
{
string itemJson = moviesArray[i].ToString();
Document doc = Document.FromJson(itemJson);
Task putItem = moviesTable.PutItemAsync(doc);
if( i >= j )
{
j++;
Console.Write( "{0,5:#,##0}, ", j );
if( j % 1000 == 0 )
Console.Write( "\n " );
j += 99;
}
await putItem;
Azure Cosmos DB:
In Azure Cosmos DB kunt u kiezen voor stream en schrijven met moviesContainer.CreateItemStreamAsync()
. In dit voorbeeld wordt de JSON echter gedeserialiseerd in het type MovieModel om de functie type casting te demonstreren. De code is multithreaded, die gebruikmaakt van de gedistribueerde architectuur van Azure Cosmos DB en de laadbewerking versnelt:
List<Task> concurrentTasks = new List<Task>();
for (int i = 0, j = 99; i < n; i++)
{
try
{
MovieModel doc= JsonConvert.DeserializeObject<MovieModel>(moviesArray[i].ToString());
doc.Id = Guid.NewGuid().ToString();
concurrentTasks.Add(moviesContainer.CreateItemAsync(doc,new PartitionKey(doc.Year)));
{
j++;
Console.Write("{0,5:#,##0}, ", j);
if (j % 1000 == 0)
Console.Write("\n ");
j += 99;
}
}
catch (Exception ex)
{
Console.WriteLine("\n ERROR: Could not write the movie record #{0:#,##0}, because:\n {1}",
i, ex.Message);
operationFailed = true;
break;
}
}
await Task.WhenAll(concurrentTasks);
Een document maken
DynamoDB:
Het schrijven van een nieuw document in Amazon DynamoDB is niet veilig. In het volgende voorbeeld wordt newItem gebruikt als documenttype:
Task<Document> writeNew = moviesTable.PutItemAsync(newItem, token);
await writeNew;
Azure Cosmos DB:
Azure Cosmos DB biedt u typeveiligheid via het gegevensmodel. We gebruiken het gegevensmodel met de naam MovieModel:
public class MovieModel
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("title")]
public string Title{ get; set; }
[JsonProperty("year")]
public int Year { get; set; }
public MovieModel(string title, int year)
{
this.Title = title;
this.Year = year;
}
public MovieModel()
{
}
[JsonProperty("info")]
public MovieInfo MovieInfo { get; set; }
internal string PrintInfo()
{
if(this.MovieInfo!=null)
return string.Format("\nMovie with title:{1}\n Year: {2}, Actors: {3}\n Directors:{4}\n Rating:{5}\n", this.Id, this.Title, this.Year, String.Join(",",this.MovieInfo.Actors), this.MovieInfo, this.MovieInfo.Rating);
else
return string.Format("\nMovie with title:{0}\n Year: {1}\n", this.Title, this.Year);
}
}
In Azure Cosmos DB newItem wordt MovieModel:
MovieModel movieModel = new MovieModel()
{
Id = Guid.NewGuid().ToString(),
Title = "The Big New Movie",
Year = 2018,
MovieInfo = new MovieInfo() { Plot = "Nothing happens at all.", Rating = 0 }
};
var writeNew= moviesContainer.CreateItemAsync(movieModel, new Microsoft.Azure.Cosmos.PartitionKey(movieModel.Year));
await writeNew;
Een document lezen
DynamoDB:
Als u in Amazon DynamoDB wilt lezen, moet u primitieven definiëren:
// Create Primitives for the HASH and RANGE portions of the primary key
Primitive hash = new Primitive(year.ToString(), true);
Primitive range = new Primitive(title, false);
Task<Document> readMovie = moviesTable.GetItemAsync(hash, range, token);
movie_record = await readMovie;
Azure Cosmos DB:
Met Azure Cosmos DB is de query echter natuurlijk (LINQ):
IQueryable<MovieModel> movieQuery = moviesContainer.GetItemLinqQueryable<MovieModel>(true)
.Where(f => f.Year == year && f.Title == title);
// The query is executed synchronously here, but can also be executed asynchronously via the IDocumentQuery<T> interface
foreach (MovieModel movie in movieQuery)
{
movie_record_cosmosdb = movie;
}
De verzameling documenten in het bovenstaande voorbeeld is:
- type veilig
- geef een natuurlijke queryoptie op.
Een item bijwerken
DynamoDB: Het item bijwerken in Amazon DynamoDB:
updateResponse = await client.UpdateItemAsync( updateRequest );
Azure Cosmos DB:
In Azure Cosmos DB wordt de update behandeld als Upsert-bewerking, wat betekent dat het document wordt ingevoegd als het niet bestaat:
await moviesContainer.UpsertItemAsync<MovieModel>(updatedMovieModel);
Een document verwijderen
DynamoDB:
Als u een item in Amazon DynamoDB wilt verwijderen, moet u opnieuw vallen op primitieven:
Primitive hash = new Primitive(year.ToString(), true);
Primitive range = new Primitive(title, false);
DeleteItemOperationConfig deleteConfig = new DeleteItemOperationConfig( );
deleteConfig.ConditionalExpression = condition;
deleteConfig.ReturnValues = ReturnValues.AllOldAttributes;
Task<Document> delItem = table.DeleteItemAsync( hash, range, deleteConfig );
deletedItem = await delItem;
Azure Cosmos DB:
In Azure Cosmos DB kunnen we het document ophalen en asynchroon verwijderen:
var result= ReadingMovieItem_async_List_CosmosDB("select * from c where c.info.rating>7 AND c.year=2018 AND c.title='The Big New Movie'");
while (result.HasMoreResults)
{
var resultModel = await result.ReadNextAsync();
foreach (var movie in resultModel.ToList<MovieModel>())
{
await moviesContainer.DeleteItemAsync<MovieModel>(movie.Id, new PartitionKey(movie.Year));
}
}
Query's uitvoeren voor documenten
DynamoDB:
In Amazon DynamoDB zijn API-functies vereist om een query uit te voeren op de gegevens:
QueryOperationConfig config = new QueryOperationConfig( );
config.Filter = new QueryFilter( );
config.Filter.AddCondition( "year", QueryOperator.Equal, new DynamoDBEntry[ ] { 1992 } );
config.Filter.AddCondition( "title", QueryOperator.Between, new DynamoDBEntry[ ] { "B", "Hzz" } );
config.AttributesToGet = new List<string> { "year", "title", "info" };
config.Select = SelectValues.SpecificAttributes;
search = moviesTable.Query( config );
Azure Cosmos DB:
In Azure Cosmos DB kunt u projectie uitvoeren en filteren in een eenvoudige SQL-query:
var result = moviesContainer.GetItemQueryIterator<MovieModel>(
"select c.Year, c.Title, c.info from c where Year=1998 AND (CONTAINS(Title,'B') OR CONTAINS(Title,'Hzz'))");
Voor bereikbewerkingen, bijvoorbeeld 'between', moet u een scan uitvoeren in Amazon DynamoDB:
ScanRequest sRequest = new ScanRequest
{
TableName = "Movies",
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#yr", "year" }
},
ExpressionAttributeValues = new Dictionary<string, AttributeValue>
{
{ ":y_a", new AttributeValue { N = "1960" } },
{ ":y_z", new AttributeValue { N = "1969" } },
},
FilterExpression = "#yr between :y_a and :y_z",
ProjectionExpression = "#yr, title, info.actors[0], info.directors, info.running_time_secs"
};
ClientScanning_async( sRequest ).Wait( );
In Azure Cosmos DB kunt u SQL-query en een instructie met één regel gebruiken:
var result = moviesContainer.GetItemQueryIterator<MovieModel>(
"select c.title, c.info.actors[0], c.info.directors,c.info.running_time_secs from c where BETWEEN year 1960 AND 1969");
Een container verwijderen
DynamoDB:
Als u de tabel in Amazon DynamoDB wilt verwijderen, kunt u het volgende opgeven:
client.DeleteTableAsync( tableName );
Azure Cosmos DB:
Als u de verzameling in Azure Cosmos DB wilt verwijderen, kunt u het volgende opgeven:
await moviesContainer.DeleteContainerAsync();
Verwijder vervolgens ook de database als u het volgende nodig hebt:
await cosmosDatabase.DeleteAsync();
Zoals u ziet, biedt Azure Cosmos DB ondersteuning voor natuurlijke query's (SQL), zijn bewerkingen asynchroon en veel eenvoudiger. U kunt uw complexe code eenvoudig migreren naar Azure Cosmos DB, wat na de migratie eenvoudiger wordt.
Volgende stappen
- Meer informatie over prestatieoptimalisatie.
- Meer informatie over het optimaliseren van lees- en schrijfbewerkingen
- Meer informatie over bewaking in Azure Cosmos DB