Cosmos DB 是微软的新 NoSQL 存储在 Azure 云中发布。 与关系数据库不同,它是可扩展的,因为它是托管数据库服务,因此在高事务 .NET 和 .NET Core 应用程序。 但是,使用 Cosmos DB 时,您需要警惕性能瓶颈和访问数据库的成本开销,因为 Microsoft 会针对数据库的每个事务向您收费。
虽然 Cosmos DB 在事务容量方面具有可扩展性,但速度并不快,因为与应用程序相比,数据库服务位于单独的 VNet 或订阅中。 因此,即使你的应用程序运行在 Azure 云中,跨 VNet 访问数据库也会对性能造成巨大的打击。
为了解决这两个问题,理想的做法是将缓存引入您的 Cosmos DB 应用程序。 您将看到应用程序性能的显着提高,同时运营成本显着降低,因为 80-90% 的时间,您的应用程序将从缓存而不是数据库中获取数据。
NCache 更多信息 与 Cosmos DB 同步缓存 在 Cosmos DB 网络研讨会中使用缓存
对 Cosmos DB 使用缓存
以下代码片段说明了如何将缓存与 Cosmos DB 结合使用。 据推测,一个 Cosmos DB 实例包含一个 Customers 集合。
- 根据缓存key在缓存中查找指定客户。
- 如果该项不在缓存中,则查询 Cosmos DB 以搜索客户。
- 如果客户存在于数据库集合中,则检索该项目。
- 将指定客户加入缓存,有效期为5分钟,保证数据一致性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
// Generate a unique cache key string key = $"Customer:ALFKI"; // First look for data in cache var retrievedItem = cache.Get<Customer>(key); // If not found in the cache, fetch data from the database and add it to the cache if (retrievedItem == null) { // New instance of CosmosClient class using a primary connection string CosmosClient client = new CosmosClient("connection-string-from-portal"); // Get container object Container container = client.GetContainer("Northwind", "Customer"); // Create partition key and id // Here, the id is CustomerID and Partition Key is City in the Customer class PartitionKey partitionKey = new PartitionKey("Seattle"); String id = "ALFKI"; // Read item from the container using the id and partitionKey var itemResponse = container.ReadItemAsync<Customer>(id, partitionKey).Result; // get customer object from database response Customer customer = itemResponse.Resource; // Initialize cache item with customer data and set expiration var cacheItem = new CacheItem(customer); cacheItem.Expiration = new Expiration(ExpirationType.Absolute, TimeSpan.FromMinutes(5)); // Insert cacheItem in cache against the given key cache.Insert(key, cacheItem); } |
NCache 更多信息 通知可扩展依赖 NCache 配套文档
运用 NCache 作为具有 Cosmos DB 的分布式缓存
使用 Cosmos DB 时,您的应用程序很可能是通过负载均衡器在多服务器环境中运行的高事务应用程序,进行大量数据库调用。 此外,独立缓存在这种环境中是不可能的,所以你需要一个分布式缓存,比如 NCache 在应用程序和数据库之间。
A 分布式缓存 允许您随着事务负载的增长添加更多缓存服务器,因此缓存永远不会成为瓶颈。 因此,您的应用程序服务器的数量并不重要,因为您可以在应用程序和数据库之间拥有足够的缓存服务器,这与关系数据库不同,关系数据库是任何可扩展性的主要瓶颈。
虽然 Cosmos DB 的扩展效率比关系数据库高得多,但它仍然无法与内存中的分布式缓存相提并论,例如 NCache 位于应用程序的 VNet 中。 事实上,缓存的一部分将驻留在应用程序进程本身(称为 客户端缓存), 给你 进程缓存 速度。
NCache 更多信息 缓存操作 NCache NCache 配套文档
缓存数据库项的集合
通过使用分布式缓存,您可以减少跨网络的数据库访问,尤其是读取操作,从而极大地提高 Cosmos DB 应用程序的性能。 因此,虽然您可以从数据库中检索单个实体,但在吞吐量和减少 R/U(每单位请求)方面更经济的方法是从数据库中检索项目集合并在缓存层应用操作。
以此目的, NCache 允许将集合缓存为单个缓存项以及缓存集合的各个元素,每个元素都针对其自己指定的缓存键。 集合状态的任何更改稍后都可以在操作结束时推送到数据库。
NCache 更多信息 与 Cosmos DB 同步缓存 NCache 配套文档
将缓存集合作为单个项目
如果您想要共同加载集合项,例如所有德国客户,您可以将集合缓存为单个项。 您可以为德国的所有客户查询 Cosmos DB,并将结果作为单个列表返回,然后可以将其添加到缓存以供进一步使用。
以下代码示例显示如何执行此操作以从数据库中检索德国客户列表。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
string key = $"CustomersFromGermany"; // First look for data in cache IDistributedList<Customer>germanCustomers = cache.DataTypeManager.GetList<Customer>(key); // If not found in the cache, fetch data from the database and add it to the cache if (germanCustomers == null) { // Create a query var query = new QueryDefinition("SELECT * FROM Customers c WHERE c.Country = 'Germany'"); // Get query iterator FeedIterator<Customer>feedIterator = container.GetItemQueryIterator<Customer>(query); // Specify expiration attribute for List var attributes = new DataTypeAttributes(); attributes.Expiration = new Expiration(ExpirationType.Absolute, TimeSpan.FromMinutes(5)); // Create a list to store customers as a collection germanCustomers = cache.DataTypeManager.CreateList<Customer>(key, attributes); // Read DB data using feed while (feedIterator.HasMoreResults) { var response = feedIterator.ReadNextAsync().Result.Resource; foreach (Customer customer in response) { germanCustomers.Add(customer); } } } |
单独缓存收集项目
您可以将元数据与缓存项相关联 NCache 通过唯一标识符对数据进行分类,例如 标签. 这样,您可以根据单个标识符从缓存中检索多个项目,例如,属于德国的客户。
为此,您可以在 Cosmos DB 中查询德国客户,并将诸如客户:国家/地区:德国之类的标签与结果项相关联。 单独缓存这些项目将使它们可用于各种查询组合,甚至可以更快地获取单个客户。
使用前面的示例,我们首先在缓存中搜索带有标签 Customer: Country: Germany 的客户。 如果缓存中不存在项目,则在 Cosmos DB 中查询 Customer 集合中的项目 - 将其“国家/地区”属性指定为“德国”。 但是,由于我们现在要单独缓存集合项,因此我们执行以下操作:
- 从数据库中获取项目后,指定项目的过期值。
- 针对每个缓存项指定标签客户:国家/地区:德国。
- 将项目批量添加到缓存中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
// Create a dictionary to add bulk items in the cache var collectionItems = new Dictionary<string, CacheItem>(); CacheItem cacheItem = null; var expiration = new Expiration(ExpirationType.Absolute, TimeSpan.FromMinutes(5)); // Read DB data using feed while (feedIterator.HasMoreResults) { var response = feedIterator.ReadNextAsync().Result.Resource; foreach (Customer customer in response) { cacheItem = new CacheItem(customer); cacheItem.Expiration = expiration; //Create a unique key for each item in collection string itemKey = $"Customer:{customer.CustomerID}"; // Add cacheItem to dictionary collectionItems.Add(itemKey, cacheItem); } } // Insert customer collection items seperately using bulk operation if (collectionItems.Count > 0) { cache.InsertBulk(collectionItems); } |
NCache 更多信息 缓存中的标签 缓存操作 NCache
NCache 在 Azure 中部署
主要云市场报价 NCache,如 Azure 和 AWS,并下载以供现场使用。 对于所有其他云系统,您可以下载并安装 NCache 在自带许可证 (BYOL) 模式的虚拟机上。 NCache 通过以下方式部署在 Azure 中:
- 部署 NCache Cloud 在天蓝色
- 部署 NCache 作为虚拟机
- 运用 NCache 在 Azure 中的平台即服务 (PaaS) 产品中。
有关这些选项的更多详细信息,请查看 云部署选项 NCache.
NCache 更多信息 NCache 在AWS中 NCache Cloud Service
结论
总而言之,在 Cosmos DB 应用程序中引入缓存可以提高速度、可靠性和可用性。 通过使用 NCache 借助 Cosmos DB,应用程序的性能得到了重大提升,因为缓存驻留在应用程序进程中。 其次,成本大幅降低,因为 80-90% 的数据都可以访问,而无需花费昂贵的数据库访问 Cosmos DB。