Caching 如何使Redis缓存中的数据层次结构(树)部分无效

Caching 如何使Redis缓存中的数据层次结构(树)部分无效,caching,redis,Caching,Redis,我有一些产品数据需要存储在Redis缓存中的多个版本。数据由JSON序列化对象组成。获取普通(基本)数据的过程很昂贵,将其定制为不同版本的过程也很昂贵,因此我希望缓存所有版本,以便尽可能优化。数据结构如下所示: BaseProduct /\ / \

我有一些产品数据需要存储在Redis缓存中的多个版本。数据由JSON序列化对象组成。获取普通(基本)数据的过程很昂贵,将其定制为不同版本的过程也很昂贵,因此我希望缓存所有版本,以便尽可能优化。数据结构如下所示:

                                    BaseProduct
                                         /\
                                      /      \
                                   /            \
                                /                  \
                             /                        \
           CustomisedProductA                          CustomisedProductB
                  /  \                                       /  \
CustomisedProductA1  CustomisedProductA2   CustomisedProductB1  CustomisedProductB2
这里的总体思路是:

  • 数据库中存储有一个基本产品
  • 本产品可采用一种定制级别-例如,关于某销售区域本产品特定版本的信息
  • 第二级定制可应用于该区域内,例如,在某个区域内的特定商店提供有关该产品的信息
数据以这种方式存储,因为数据检索/计算过程的每个步骤都很昂贵。第一次检索某个地区的特定产品时,将执行一组定制,以使其成为某个地区特定的产品。第一次为商店检索特定产品时,我需要基于区域产品执行定制以生成特定于商店的产品

出现问题的原因是,我可能需要通过以下几种方式使数据无效:

  • 如果基础产品数据发生更改,则需要使整个树失效,并重新生成所有内容
  • 如果产品的第一组定制发生了变化(即中间级别),那么我也需要使该级别下的节点无效。例如,如果CustomisedProductA的customisations受到更改的影响,我需要使CustomisedProductA、CustomisedProductA1和CustomisedProductA2过期
  • 如果产品的第二组定制发生了变化(即底层),则该节点需要失效。我可以通过调用
    HDEL键字段
    (例如
    HDEL-product-CustomisedProductA:CustomisedProductA1
    )在散列中实现这一点

因此,我的问题是:是否有一种方法来表示这种类型的多级数据结构,以允许在多个级别中存储数据的性能,同时只允许树的一部分失效?或者,我是否仅限于使整个树(
DEL key
)或特定节点(
HDEL key field
)过期,而不在这两者之间执行任何操作?

至少有3种不同的方法可以做到这一点,每种方法都有自己的优缺点

第一种方法是使用树的非原子即席扫描来识别树的第二级(第一组定制)并使其失效(删除)。要做到这一点,请对散列的字段使用分层命名方案,并使用进行迭代。例如,假设散列的键名是产品的ID(例如ProductA),则第一个自定义项的第一个版本使用类似“0001:0001”的字段名,第二个版本使用类似“0001:0002”的字段名,以此类推。同样,“0002:0001”将是第二个自定义第一个版本,等等。。。然后,找到customization 42的所有版本,使用
hs CAN ProductA 0 MATCH 0042::
,回复中的字段,然后重复,直到光标归零

相反的方法是主动“索引”每个定制的版本,以便您可以高效地获取它们,而不是执行哈希的完全扫描。解决方法是使用Redis的集合——您保留一个集合,其中包含给定产品版本的所有字段名。版本可以是连续的(如我的示例中所示),也可以是任何其他版本,只要它们是唯一的。成本在于维护这些索引—无论何时添加或删除产品的自定义项和/或版本,都需要保持与这些集合的一致性。例如,版本的创建类似于:

HSET ProductA 0001:0001 "<customization 1 version 1 JSON payload"
SADD ProductA:0001 0001

要读取自定义版本,请使用并拆分回复中的JSON,要删除整个自定义,请使用。

树将非常大。将有一个根节点(基本产品),约30个中间节点(区域定制产品),每个中间节点可能有多达1000个其他可能的定制。并非所有这些都会被使用,但在最坏的情况下,我们可能会在树中看到多达30000个节点。中间节点(区域定制产品)的失效可能每天发生两次。根节点的失效每天都会发生。理想情况下,我们希望更新是原子的,但是如果有必要的话,我很乐意考虑另一种选择。哇,这是一个难以置信的详细反应。谢谢这三个选项都很有意义(尽管我仍在学习Redis,所以一些细节还不太清楚)。在我看来,选项2是最简单的,但我将尝试其他选项,以便在性能和实现复杂性方面对它们进行比较。非常感谢你的回答。
ZADD ProductA 0 0001:0001:<JSON>