使用缓存来减少数据库需求 - AWS 规范性指导

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用缓存来减少数据库需求

概述

您可以使用缓存作为有效的策略来帮助降低成本。 NET应用程序。当应用程序需要频繁访问数据时,许多应用程序都使用后端数据库,例如SQL服务器。维护这些后端服务以满足需求的成本可能很高,但是您可以使用有效的缓存策略,通过降低大小和扩展要求来减少后端数据库的负载。这可以帮助您降低成本并提高应用程序的性能。

缓存是一种有用的技术,可以节省与读取繁重的工作负载相关的成本,这些工作负载使用更昂贵的资源,例如SQL服务器。为你的工作量使用正确的技巧很重要。例如,本地缓存不可扩展,需要您为应用程序的每个实例维护一个本地缓存。您应该权衡性能影响与潜在成本的比较,以便底层数据源的较低成本抵消与缓存机制相关的任何额外成本。

成本影响

SQL服务器要求您在调整数据库大小时将读取请求考虑在内。这可能会影响成本,因为您可能需要引入只读副本以适应负载。如果您使用的是只读副本,请务必了解它们仅在 SQL Server Enterprise 版上可用。此版本需要比SQL服务器标准版更昂贵的许可证。

下图旨在帮助您了解缓存的有效性。它显示了 Amazon f RDS or SQL Server 有四个 db.m4.2xlarge 节点运行服务器企业版。SQL它部署在具有一个只读副本的多可用区配置中。独占读取流量(例如SELECT查询)将定向到只读副本。相比之下,亚马逊 DynamoDB 使用的是 r4.2xlarge 双节点 DynamoDB 加速器 () 集群。DAX

下图显示了不再需要处理高读取流量的专用只读副本的结果。

显示移除专用只读副本结果的图表

您可以通过使用不带只读副本的本地缓存或与 SQL Server on Amazon RDS 并行引入DAX缓存层来实现显著的成本节约。该层从SQL服务器卸载并减小了运行数据库所需的SQL服务器的大小。

成本优化建议

本地缓存

本地缓存是为本地环境或云端托管的应用程序缓存内容的最常用方法之一。这是因为它实现起来相对容易和直观。本地缓存包括从数据库或其他来源获取内容,然后在内存或磁盘上本地缓存以实现更快的访问。这种方法虽然易于实现,但对于某些用例来说并不理想。例如,这包括缓存内容需要随着时间的推移而持续存在的用例,例如保留应用程序状态或用户状态。另一个用例是需要从其他应用程序实例访问缓存的内容。

下图说明了具有四个节点和两个只读副本的高可用性SQL服务器群集。

具有 4 个节点和 2 个只读副本的高可用性SQL服务器群集

使用本地缓存,您可能需要对多个EC2实例的流量进行负载平衡。每个实例都必须维护自己的本地缓存。如果缓存存储有状态信息,则需要定期向数据库提交,并且可能需要将用户转发到每个后续请求(粘性会话)的同一个实例。在尝试扩展应用程序时,这会带来挑战,因为有些实例可能被过度利用,而有些实例则由于流量分布不均而未得到充分利用。

您可以将本地缓存(内存中缓存或使用本地存储)用于。 NET应用程序。为此,您可以添加功能来将对象存储在磁盘上并在需要时检索它们,或者从数据库中查询数据并将其保存在内存中。例如,要在 C# 中对来自SQL服务器的数据进行内存和本地存储的本地缓存,可以使用MemoryCacheLiteDB库的组合。 MemoryCache提供内存缓存,而LiteDB是一个嵌入式的 No SQL 基于磁盘的数据库,既快速又轻巧。

要执行内存缓存,请使用。 NET图书馆System.Runtime.MemoryCache。以下代码示例说明如何使用该System.Runtime.Caching.MemoryCache类在内存中缓存数据。该类提供了一种将数据临时存储在应用程序内存中的方法。这可以减少从更昂贵的资源(例如数据库或)获取数据的需求,从而帮助提高应用程序的性能API。

以下是代码的工作原理:

  1. 已创建一个 named 的私MemoryCache_memoryCache有静态实例。给缓存起一个名字 (dataCache) 来标识它。然后,缓存存储和检索数据。

  2. GetData方法是一个通用方法,它有两个参数:一个string键和一个名为的Func<T>委托getData。密钥用于标识缓存的数据,而getData委托代表当缓存中不存在数据时执行的数据检索逻辑。

  3. 该方法首先使用该_memoryCache.Contains(key)方法检查缓存中是否存在数据。如果数据在缓存中,则该方法使用检索数据,_memoryCache.Get(key)并将其转换为预期的类型 T

  4. 如果数据不在缓存中,则该方法会调用getData委托来获取数据。然后,它使用将数据添加到缓存中_memoryCache.Add(key, data, DateTimeOffset.Now.AddMinutes(10))。此调用指定缓存条目应在 10 分钟后过期,此时数据将自动从缓存中删除。

  5. ClearCache方法将string密钥作为参数,并使用从缓存中删除与该密钥关联的数据_memoryCache.Remove(key)

using System; using System.Runtime.Caching; public class InMemoryCache { private static MemoryCache _memoryCache = new MemoryCache("dataCache"); public static T GetData<T>(string key, Func<T> getData) { if (_memoryCache.Contains(key)) { return (T)_memoryCache.Get(key); } T data = getData(); _memoryCache.Add(key, data, DateTimeOffset.Now.AddMinutes(10)); return data; } public static void ClearCache(string key) { _memoryCache.Remove(key); } }

你可以使用以下代码:

public class Program { public static void Main() { string cacheKey = "sample_data"; Func<string> getSampleData = () => { // Replace this with your data retrieval logic return "Sample data"; }; string data = InMemoryCache.GetData(cacheKey, getSampleData); Console.WriteLine("Data: " + data); } }

以下示例向您展示如何使用 LiteDB 在本地存储中缓存数据。您可以使用 LiteDB 作为内存缓存的替代或补充。以下代码演示了如何使用 LiteDB 库在本地存储中缓存数据。该LocalStorageCache类包含用于管理缓存的主要函数。

using System; using LiteDB; public class LocalStorageCache { private static string _liteDbPath = @"Filename=LocalCache.db"; public static T GetData<T>(string key, Func<T> getData) { using (var db = new LiteDatabase(_liteDbPath)) { var collection = db.GetCollection<T>("cache"); var item = collection.FindOne(Query.EQ("_id", key)); if (item != null) { return item; } } T data = getData(); using (var db = new LiteDatabase(_liteDbPath)) { var collection = db.GetCollection<T>("cache"); collection.Upsert(new BsonValue(key), data); } return data; } public static void ClearCache(string key) { using (var db = new LiteDatabase(_liteDbPath)) { var collection = db.GetCollection("cache"); collection.Delete(key); } } } public class Program { public static void Main() { string cacheKey = "sample_data"; Func<string> getSampleData = () => { // Replace this with your data retrieval logic return "Sample data"; }; string data = LocalStorageCache.GetData(cacheKey, getSampleData); Console.WriteLine("Data: " + data); } }

如果您有不经常更改的静态缓存或静态文件,也可以将这些文件存储在亚马逊简单存储服务 (Amazon S3) Service 对象存储中。应用程序可以在启动时检索静态缓存文件以供本地使用。有关如何使用从 Amazon S3 检索文件的更多详细信息。 NET,请参阅 Amazon S3 文档中的下载对象

使用缓存 DAX

您可以使用可在所有应用程序实例之间共享的缓存层。D@@ ynamoDB Accelerator DAX () 是一款适用于 DynamoDB 的完全托管、高度可用的内存缓存,可以将性能提高十倍。您可以使用DAX减少在 DynamoDB 表中过度配置读取容量单位的需求,从而降低成本。这对于读取量大、需要重复读取单个密钥的工作负载特别有用。

DynamoDB 按需定价或按预配置容量定价,因此每月的读取和写入次数会影响成本。如果您有大量的读取负载,DAX集群可以减少 DynamoDB 表的读取次数,从而帮助降低成本。有关如何设置的说明DAX,请参阅 DynamoDB 文档中的使用 DynamoDB 加速器 DAX () 进行内存加速。有关信息。 NET应用程序集成,请观看将 Amazon DynamoDB 集成到DAX你的。ASP NET申请已启用 YouTube。

其他资源