Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Azure Cosmos DB — это масштабируемая, глобально распределенная, полностью управляемая база данных. Он обеспечивает гарантированный доступ к данным с низкой задержкой.
В этой статье описывается перенос приложения .NET из Amazon DynamoDB в Azure Cosmos DB с минимальными изменениями кода. Дополнительные сведения об Azure Cosmos DB см. в этой обзорной статье.
Концептуальные различия
В следующей таблице перечислены основные основные различия между Azure Cosmos DB и DynamoDB:
| DynamoDB | Azure Cosmos DB (облачная база данных) |
|---|---|
| Неприменимо | База данных |
| Таблица | Коллекция |
| Item | Документ |
| Свойство | Поле |
| Младший индекс | Младший индекс |
| Первичный ключ > ключ секции | Ключ партиционирования |
| Первичный ключ > ключ сортировки | Не требуется |
| Stream | Лента изменений |
| Записать вычислительный блок | Единица запроса (гибкая, можно использовать для операций чтения или записи) |
| Чтение вычислительного блока | Единица запроса (гибкая, можно использовать для операций чтения или записи) |
| Глобальная таблица | Необязательно. Вы можете напрямую выбрать регион при подготовке учетной записи Azure Cosmos DB. (Вы можете изменить регион позже.) |
Структурные различия
Структура JSON Azure Cosmos DB проще, чем структура JSON в DynamoDB. В следующем примере показаны различия.
DynamoDB
Следующий объект JSON представляет формат данных в DynamoDB:
{
"TableName": "Music",
"KeySchema": [
{
"AttributeName": "Artist",
"KeyType": "HASH",
},
{
"AttributeName": "SongTitle",
"KeyType": "RANGE"
}
],
"AttributeDefinitions": [
{
"AttributeName": "Artist",
"AttributeType": "S"
},
{
"AttributeName": "SongTitle",
"AttributeType": "S"
}
],
"ProvisionedThroughput": {
"ReadCapacityUnits": 1,
"WriteCapacityUnits": 1
}
}
С Artist ключом секции и SongTitle ключом сортировки.
Azure Cosmos DB (облачная база данных)
Следующий объект JSON представляет формат данных в Azure Cosmos DB:
{
"Artist": "",
"SongTitle": "",
"AlbumTitle": "",
"Year": 9999,
"Price": 0.0,
"Genre": "",
"Tags": ""
}
Перенос кода
В этой статье рассматривается перенос кода приложения в Azure Cosmos DB, который является критически важным аспектом миграции базы данных. Чтобы понять, как работает процесс миграции, в следующих разделах сравнивается код между Amazon DynamoDB и Azure Cosmos DB.
Чтобы скачать исходный код, выполните клонирование следующего репозитория.
git clone https://github.com/Azure-Samples/DynamoDB-to-CosmosDB
Предпосылки
- .NET Framework 4.7.2.
- Последняя версия Visual Studio с рабочей нагрузкой разработки Azure. Вы можете начать с бесплатной среды разработки Visual Studio Community. При установке Visual Studio включите рабочую нагрузку разработки для Azure.
- Доступ к учетной записи Azure Cosmos DB для NoSQL.
- Локальная установка Amazon DynamoDB.
- Java 8.
- Скачиваемая версия Amazon DynamoDB. Запустите его через порт 8000. (Вы можете изменить и настроить код.)
Настройка кода
Добавьте в проект следующий пакет NuGet:
Install-Package Microsoft.Azure.Cosmos
Установка подключения
DynamoDB
В Amazon DynamoDB используется следующий код для подключения:
AmazonDynamoDBConfig addbConfig = new AmazonDynamoDBConfig();
addbConfig.ServiceURL = "endpoint";
try
{
aws_dynamodbclient = new AmazonDynamoDBClient(addbConfig);
}
catch { }
Azure Cosmos DB (облачная база данных)
Для подключения к Azure Cosmos DB измените код следующим образом.
client_documentDB = new CosmosClient(
"<nosql-account-endpoint>",
tokenCredential
);
Оптимизация подключения в Azure Cosmos DB
В Azure Cosmos DB можно оптимизировать подключение с помощью следующих параметров.
ConnectionMode: используйте режим прямого подключения для подключения к узлам данных в службе Azure Cosmos DB. Используйте режим шлюза только для инициализации и кэширования логических адресов и выполняйте обновление в случае изменений. Дополнительные сведения см. в режимах подключения пакета SDK SQL для Azure Cosmos DB.ApplicationRegion: используйте этот параметр, чтобы задать предпочтительный геореплицированный регион для взаимодействия с Azure Cosmos DB. Дополнительные сведения см. в статье "Глобальное распространение данных с помощью Azure Cosmos DB".ConsistencyLevel: используйте этот параметр для переопределения уровня согласованности по умолчанию. Дополнительные сведения см. в разделе "Уровни согласованности" в Azure Cosmos DB.BulkExecutionMode: используйте этот параметр для выполнения массовых операций, задав свойствуAllowBulkExecutionзначениеtrue. Дополнительные сведения см. в статье о массовом импорте данных в учетную запись Azure Cosmos DB для NoSQL с помощью пакета SDK для .NET.client_cosmosDB = new CosmosClient("Your connection string", new CosmosClientOptions() { ConnectionMode = ConnectionMode.Direct, ApplicationRegion = Regions.EastUS2, ConsistencyLevel = ConsistencyLevel.Session, AllowBulkExecution = true, });
Создание контейнера
DynamoDB
Чтобы сохранить данные в Amazon DynamoDB, сначала необходимо создать таблицу. Определите схему, тип ключа и атрибуты, как показано в следующем коде:
// movies_key_schema
public static List<KeySchemaElement> moviesKeySchema =
new List<KeySchemaElement>
{
new KeySchemaElement
{
AttributeName = partitionKeyName,
KeyType = "HASH"
},
new KeySchemaElement
{
AttributeName = sortKeyName,
KeyType = "RANGE"
},
};
// key names for the Movies table
public const string partitionKeyName = "year";
public const string sortKeyName = "title";
public const int readUnits = 1, writeUnits = 1;
// movie_items_attributes
public static List<AttributeDefinition> movieItemsAttributes =
new List<AttributeDefinition>
{
new AttributeDefinition
{
AttributeName = partitionKeyName,
AttributeType = "N"
},
new AttributeDefinition
{
AttributeName = sortKeyName,
AttributeType = "S"
}
};
CreateTableRequest request;
CreateTableResponse response;
// Build the 'CreateTableRequest' structure for the new table
request = new CreateTableRequest
{
TableName = tableName,
AttributeDefinitions = tableAttributes,
KeySchema = tableKeySchema,
// Provisioned-throughput settings are always required,
// although the local test version of DynamoDB ignores them.
ProvisionedThroughput = new ProvisionedThroughput(readUnits, writeUnits)
};
Azure Cosmos DB (облачная база данных)
В Amazon DynamoDB необходимо подготовить единицы вычислений чтения и вычислительные единицы записи. В Azure Cosmos DB укажите пропускную способность в виде единиц запросов в секунду (ЕЗ/с). Вы можете динамически использовать RU/s для выполнения любых операций. Данные организованы как база данных, контейнер и элемент. Пропускную способность можно указать на уровне базы данных, на уровне коллекции или обоих.
Создание базы данных:
await client_cosmosDB.CreateDatabaseIfNotExistsAsync(movies_table_name);
Чтобы создать контейнер, выполните приведенные действия.
await cosmosDatabase.CreateContainerIfNotExistsAsync(new ContainerProperties()
{
PartitionKeyPath = "/" + partitionKey,
Id = newCollectionName
},
provisionedThroughput);
Загрузка данных
DynamoDB
В приведенном ниже коде показано, как необходимо загружать данные в Amazon DynamoDB. В коде moviesArray перечислены документы JSON, а затем необходимо выполнить итерацию и загрузить документы JSON в 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;
}
catch { }
}
Azure Cosmos DB (облачная база данных)
В Azure Cosmos DB вы можете выполнить потоковую передачу и запись с помощью moviesContainer.CreateItemStreamAsync(). Однако в этом примере JSON десериализуется в тип MovieModel, чтобы продемонстрировать возможность приведения типов. Код многопоточный и использует распределенную архитектуру в Azure Cosmos DB для ускорения загрузки.
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)));
if (i >= j)
{
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);
Создание документа
DynamoDB
Написание нового документа в Amazon DynamoDB не является безопасным. В следующем примере используется newItem тип документа:
Document writeNew = await moviesTable.PutItemAsync(newItem, token);
Azure Cosmos DB (облачная база данных)
Azure Cosmos DB обеспечивает безопасность типов с помощью модели данных. В этом примере используется модель данных с именем 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; }
[JsonProperty("info")]
public MovieInfo MovieInfo { get; set; }
public MovieModel(string title, int year)
{
this.Title = title;
this.Year = year;
}
public MovieModel() { }
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);
}
}
В Azure Cosmos DB newItem это 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 }
};
await moviesContainer.CreateItemAsync(movieModel, new Microsoft.Azure.Cosmos.PartitionKey(movieModel.Year));
Чтение документа
DynamoDB
Для чтения данных в Amazon DynamoDB необходимо определить примитивы.
// 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);
Document movieRecord = await moviesTable.GetItemAsync(hash, range, token);
Azure Cosmos DB (облачная база данных)
При использовании Azure Cosmos DB запрос является естественным (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;
}
Коллекция документов в предыдущем примере является типобезопасной и предоставляет естественную возможность запроса.
Обновление элемента
DynamoDB
Обновление элемента в Amazon DynamoDB:
updateResponse = await client.UpdateItemAsync(updateRequest);
Azure Cosmos DB (облачная база данных)
В Azure Cosmos DB обновление обрабатывается как Upsert операция (т. е. вставьте документ, если он не существует):
await moviesContainer.UpsertItemAsync<MovieModel>(updatedMovieModel);
Удаление документа
DynamoDB
Чтобы удалить элемент в Amazon DynamoDB, необходимо еще раз обратиться к примитивам.
Primitive hash = new Primitive(year.ToString(), true);
Primitive range = new Primitive(title, false);
DeleteItemOperationConfig deleteConfig = new DeleteItemOperationConfig();
deleteConfig.ConditionalExpression = condition;
deleteConfig.ReturnValues = ReturnValues.AllOldAttributes;
Document deletedItem = await table.DeleteItemAsync(hash, range, deleteConfig);
Azure Cosmos DB (облачная база данных)
В Azure Cosmos DB вы можете получить документ и удалить его асинхронно:
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));
}
}
Поиск документов
DynamoDB
В Amazon DynamoDB функции API необходимы для запроса данных:
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 (облачная база данных)
В Azure Cosmos DB можно выполнять проекцию и фильтрацию в простом SQL-запросе:
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'))");
Для операций с диапазоном (например, betweenнеобходимо выполнить сканирование в 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();
В Azure Cosmos DB можно использовать SQL-запрос и однострочный оператор:
var result = moviesContainer.GetItemQueryIterator<MovieModel>(
"SELECT c.title, c.info.actors[0], c.info.directors, c.info.running_time_secs FROM c WHERE c.year BETWEEN 1960 AND 1969");
Удаление контейнера
DynamoDB
Для удаления таблицы в Amazon DynamoDB можно указать следующую инструкцию.
await client.DeleteTableAsync(tableName);
Azure Cosmos DB (облачная база данных)
Для удаления коллекции в Azure Cosmos DB укажите следующую инструкцию.
await moviesContainer.DeleteContainerAsync();
При необходимости удалите базу данных:
await cosmosDatabase.DeleteAsync();
Сводка
Как показано в предыдущих примерах, Azure Cosmos DB поддерживает естественные запросы (SQL), а операции являются асинхронными. Вы можете легко перенести сложный код в Azure Cosmos DB. Код становится проще после миграции.
Связанный контент
- Дополнительные сведения об оптимизации производительности.
- Узнайте, как оптимизировать операции чтения и записи.
- Сведения о мониторинге в Azure Cosmos DB.