对象缓存与缓存数据库查询结果

6 caching

问题主要与数据库方面的缓存有关。说,我们进行了各种性能优化,包括查询调整,数据库分片,数据库反规范化等。我们仍然看到需要在数据库侧具有内存中缓存。我们有2个用于缓存的选项-缓存数据库查询结果与缓存数据库(OR)业务对象。

缓存对象(用户,产品,地址)与缓存查询返回的结果集的优缺点是什么?

Cri*_*eco 10

根据我的经验,缓存应用程序对象比缓存原始查询结果有相当多的好处。

如果您的应用程序已经构建了一个 DAO 层,它将业务逻辑与数据库访问分开,那么使用缓存代理模式(即提供一个实现相同接口的实体)在您的 DAO 之上添加一个微小的缓存层是很容易的的 DAO,处理从缓存中的存储/检索,并在需要时将数据库访问权限委托给实际的目标实体)。

这种方法导致了应用程序设计中的一系列关键考虑因素:

  • 数据库访问逻辑、缓存层和业务逻辑之间有明确的职责分离

  • 缓存逻辑的所有细节(密钥生成、存储策略和到期管理)都封装在一个单独的实体中

  • 您可以选择有选择地启用缓存设施,例如仅针对某些方法/DAO

  • DAO 和缓存代理共享相同的接口,例如在运行时也很容易打开/关闭缓存

  • 您可以分别测试 DAO 和缓存代理

更实用的是,缓存您的应用程序对象意味着:

  • 在存储或检索对象时,您需要支付单个序列化/反序列化开销,而在检索查询结果时,您仍然需要构建您的对象

  • 您的对象的复杂性(几乎)无关紧要(例如,缓存代理忽略了 DAO 使用 2 个不同数据源上的 3 个单独查询创建的对象)

  • 在某些情况下,生成缓存键可能很棘手,而散列查询字符串(您在缓存代理中不知道)要容易得多

  • 缓存中的序列化对象(例如 json 字符串)也可以从其他应用程序读取和使用(不需要,但有时需要)

  • 很有可能您的数据库已经实现了一个复杂且快速的缓存查询机制,您可能希望根据自己的需要进行调整,而不是在其上构建另一层

您可以自己为 DAO 构建缓存层。如果您的应用程序已经基于Spring等框架,则缓存支持可能已经内置,您只需要设置适当的配置(尽管并不总是像您想要的那样灵活)。

最后,我不能说使用查询缓存比深思熟虑的对象缓存有什么特别的缺点。尽管如此,我还是想知道一个流行的框架(如Hibernate)默认禁用查询缓存,并且需要在单个查询中选择性地启用它。