Caching 复杂查询的缓存策略/设计模式

Caching 复杂查询的缓存策略/设计模式,caching,design-patterns,redis,architecture,azure-sql-database,Caching,Design Patterns,Redis,Architecture,Azure Sql Database,我们有一个使用Redis的非常简单的缓存命中/未命中系统的现有API。它支持按键搜索。因此,转换为以下内容的查询很容易基于其主键进行缓存 从[Entities]中选择*,其中PrimaryKeyCol=@p1 任何后续请求都可以在REDIS中按主键查找实体,或故障返回到数据库,然后用该结果填充缓存 我们正在构建一个新的API,该API将允许通过更多参数进行搜索,将在结果中返回多个条目,并且将处于相当高的请求量(足以影响SQL Azure中现有DTU的利用率) 查询将可通过其他几个术语、一次搜索中

我们有一个使用Redis的非常简单的缓存命中/未命中系统的现有API。它支持按键搜索。因此,转换为以下内容的查询很容易基于其主键进行缓存

从[Entities]中选择*,其中PrimaryKeyCol=@p1

任何后续请求都可以在REDIS中按主键查找实体,或故障返回到数据库,然后用该结果填充缓存

我们正在构建一个新的API,该API将允许通过更多参数进行搜索,将在结果中返回多个条目,并且将处于相当高的请求量(足以影响SQL Azure中现有DTU的利用率)

查询将可通过其他几个术语、一次搜索中的多个PK、各种其他FK查找列进行搜索,如/包含关于文本的语句等

在此场景中,是否有任何设计模式或缓存策略可以考虑。Redis似乎不太适合这些类型的查询。我正在考虑简单地对查询参数进行散列,然后将该散列缓存为键,将整个结果集缓存为值

但考虑到Redis的键值特性,以及一个实体可能包含在多个查询哈希下的多个结果集中的事实,这感觉有点幼稚


(作为参考,此数据的来源目前是SQL Azure,我们正在使用Azure的托管Redis服务。我们也在寻找其他方法来访问数据库,包括对数据进行非规范化、将数据ETL到CosmosDB、在Azure搜索中托管数据,但这还有其他影响,包括实施时间,数据的“新鲜度”等等。

就我个人而言,我不会尝试缓存结果,只缓存单个实体。过去我做过类似的事情时,会从实时查询返回ID列表,然后从缓存层检索单个实体。这样,ID列表总是“新鲜的”,并且不会出现严重的缓存失效逻辑问题

如果确实有经常重复的搜索,可以缓存(ID的)结果,但可能会遇到分页等问题。缓存查询结果可能很棘手,因为您通常需要缓存所有结果,而不仅仅是第一个“页面”。这通常非常昂贵,并且传输成本很高,超过了缓存的价值

此外,缓存查询结果时绝对会出现新鲜度问题。当新记录出现时,它们将不在缓存列表中。使用仅实体缓存可以避免这种情况,因为ID列表总是最新的,只有实体本身可能会过时(但这有一种更简单的缓存过期方法)


如果您担心实体过时,您不仅可以返回一个ID,还可以返回一个“上次更新日期”,它允许您将每个实体的新鲜度与缓存进行比较。

感谢您的输入。当我写上面的原文时,还有一些事情我没有想到。1,如果我们的非规范化和分区策略正确,那么使用Cosmos将比SQL快几个数量级。2.这个API可以很容易地放在Azure API管理服务后面,这将允许我们进行请求/响应缓存。考虑到这两个事实,我想我会接受你的建议,放弃Redis的做法。干杯