构造唯一性由6个属性定义的缓存键的最佳方法

时间:2019-03-17 17:52:57

标签: caching redis

目前,我的任务是为电子商务之类的系统修复缓存,该系统的价格取决于许多因素。缓存后端是redis。对于给定的产品,影响价格的因素有:

sku

频道

子频道

计划

日期

当前,缓存在redis中的结构如下:

product1_channel1_subchannel1:  {sku_1:  {plan1: {2019-03-18: 2000}}}

API可以满足对多种产品,需求以及上述所有因素的要求。因此,他们决定在product_channel_subchannel级别上查询所有数据,并在应用程序中过滤速度非常慢的数据。他们还决定,在发生高速缓存未命中时,他们将为90天的所有数据构建所有高速缓存的高速缓存。这样,只有一个请求将面临愤怒,而其他请求则将从中受益(只有现在,我们只能更频繁地破坏缓存,这也拖累了系统)

将所有这些因素包括在密钥中的缺点是密钥太多。到球场上,有400种产品,每种产品由20种功能,20个渠道,200个子渠道,三种计划和400天的定价组成。为了避免在某个地方出现这么多键,我们必须对数据进行分组。

该系统目前大约接收10 rps,必须在100毫秒内响应。

问题是:

上面的缓存结构还好吗?还是我们要扁平化这个结构?

一般来说,缓存如何存储在定价系统中。尽管如此,我仍然觉得这是一项非常琐碎的任务

可以牺牲一个请求来预热大部分数据的缓存吗?还是有一个缓存预热策略更好?

1 个答案:

答案 0 :(得分:0)

任何一种缓存策略都是一种权衡的方法。而您需要进行的精确权衡将取决于您无法尝试的复杂领域逻辑,而无法尝试。

这意味着您实施的​​任何内容均应基于数据,并且应具有足够的灵活性以随着业务的变化而随时间变化。特别是这些问题的答案:

  

可以牺牲一个请求来预热大部分数据的缓存吗?还是有一个缓存预热策略更好?

取决于用户将如何查询数据以及高速缓存未命中将花费多长时间。如果查询倾向于以某种可预测的方式聚集在某些阶段或某些日期周围,那么您应该使用该信息来帮助指导缓存的命中和未命中。

如果没有进行适当的实验,我或其他任何人都无法给您正确的答案,但是我们可以为您提供一些指导。

在使用Redis进行缓存时,我会推荐一些最佳实践:

  1. 如果瓶颈是将数据从Redis发送到api,请考虑使用lua脚本在任何数据离开redis之前进行简单处理。但是请注意,不要使脚本过于复杂,因为长时间运行的lua脚本会阻止redis的所有其他部分
  2. 您似乎正在使用简单的获取/设置键来存储数据。考虑使用更复杂的方法:

    a。如果您希望按日期更好地访问数据(使用日期作为分数),请使用排序集(zset)。 b。使用哈希集获得对skus的更细粒度访问

  3. 根据您的问题,看起来您将拥有约160万把钥匙。这不是一个很大的数目,但是您需要确保redis有足够的内存来将所有内容存储在ram中,而无需将任何内容交换到磁盘上。这是我们必须学习的艰难方法。如果要在Linux上运行redis实例,则必须将系统的swappiness设置为0,以确保从不使用swap。

但是,最重要的是,您需要对所有内容进行试验,直到找到一个好的解决方案为止。