概览
内存数据缓存是提高应用程序整体性能以及降低数据库成本最为有效的战略之一。
缓存可应用到任何类型的数据库,包括诸如 Amazon RDS 之类的关系数据库,或诸如 Amazon DynamoDB、MongoDB 和 Apache Cassandra 之类的 NoSQL 数据库。缓存的最大优点在于对实施产生的影响最小,这样可以在规模和速度方面显著提高应用程序的性能。
您将在下面找到在解决基于磁盘的数据库的相关限制和挑战过程中,可以采用的部分缓存策略和实施方法。
数据库带来的挑战
构建需要低延迟和可扩展性的分布式应用程序时,基于磁盘的数据库可能会给应用程序带来许多挑战。以下是其中几个常见的挑战:
- 查询处理速度慢:尽管有许多查询优化技术和架构设计有助于提升查询性能,但从磁盘检索数据加上额外的查询处理时间往往需要至少数十毫秒的查询响应时间,这还是在假设您的负载稳定且数据库以最佳状态运行的情况下。
- 扩展成本:不管数据是通过基于磁盘的 NoSQL 数据库分发还是在关系数据库中垂直扩展,要扩展为具有极高的读取速率都需要付出高昂成本,需要许多数据库只读副本才能应对单个内存缓存节点每秒的请求量。
- 需要简化数据访问:尽管关系数据库为数据模型关系提供了极好的方法,但这些方法并不是用于数据访问的最佳方法。在某些情况下,应用程序可能需要访问特定结构或视图中的数据,以简化数据检索和提高应用程序性能。
实施数据库缓存之前,许多架构师和工程师竭尽全力以期发挥出数据库的最大性能。尽管预期是合理的,但如果使用错误的工具来解决问题,可能会适得其反。例如,假如您想降低数据库查询的延迟,带着这样的合理预期来操作当属明智,但如果违背了从磁盘检索数据的相关物理定律,那就是浪费时间。
缓存如何发挥作用
数据库缓存消除了主数据库面临的不必要的压力(通常是频繁访问的读取数据),对其功能有所助益。缓存本身可存在于数据库、应用程序等许多区域中,也可作为独立层存在。
下面是三种最常用的数据库缓存类型:
- 数据库集成缓存:一些数据库(例如 Amazon Aurora)提供集成缓存,该缓存在数据库引擎中托管,具有内置直写功能。当数据库表中的底层数据更改时,数据库会自动更新其缓存,这种方式非常好。无需动用应用层内的任何资源就可以利用此缓存。集成缓存的不足之处在于规模和功能。集成缓存通常受限制于数据库实例分配给缓存的可用内存,也不能用于与其他实例共享数据等其他用途。
- 本地缓存:本地缓存可存储应用程序中经常使用的数据。这不仅加快了数据检索速度,而且消除了与之相关的网络流量,使其速度快于其他缓存架构。主要缺点在于:应用程序内的每个节点都有自己的驻留缓存,这些缓存彼此孤立,并不连贯。单个缓存节点内存储的信息无法与其他本地缓存共享,不管这些信息是数据库缓存数据、Web 会话还是用户购物车。这给信息共享对于支持可扩展动态环境至关重要的分布式环境带来了挑战。由于大多数应用程序利用多个应用程序服务器,因此如果每个服务器都有自己的缓存,那么在这些缓存之间协调值就成为了一个巨大的挑战。
此外,出现中断时,本地缓存中的数据会丢失,需要有效补充,这就会给缓存造成不利影响。利用远程缓存可克服其中的大多数缺点。远程缓存 (或称为“端缓存”) 是专门用于存储内存中缓存数据的单独实例 (或多个实例)。
对于介意网络延迟的环境,可以采用同时利用本地缓存和远程缓存的双层缓存策略。我们不会详细介绍此策略,但一般只有在绝对必要时才会使用,因为这种策略会增加复杂性。假如远程缓存的请求一般能以亚毫秒级性能实现,对于大多数应用程序来说,使用远程缓存时增加的网络开销便不值一提。
- 远程缓存:远程缓存存储在专用服务器上,通常基于 Redis 和 Memcached 等键/值 NoSQL 存储构建而成。其中的每个缓存节点每秒可提供数十万到百万条请求。诸如 Amazon ElastiCache for Redis 之类的许多解决方案也可为关键工作负载提供所需的高可用性。
另外,远程缓存的平均请求延迟实现了亚毫秒级,其传输数量级比基于磁盘的数据库更快。在这种速度下,极少需要使用本地缓存。由于远程缓存可用作供所有不同系统使用的连接集群,因此非常适用于分布式环境。
借助远程缓存,数据缓存和数据有效性管理之间的编排工作由利用远程缓存的应用程序和/或进程进行管理。缓存本身未直接连接到数据库,但使用时就好像与之相邻。我们重点关注如何利用远程缓存(尤其是 Amazon ElastiCache for Redis)来缓存关系数据库数据。
如需了解缓存模式的更多信息,请访问实施注意事项页面。