gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 06:11:19 25 4
gpt4 key购买 nike

我有一些产品数据需要在 Redis 缓存中存储多个版本。数据由 JSON 序列化对象组成。获取普通(基本)数据的过程很昂贵,将其定制成不同版本的过程也很昂贵,所以我想缓存所有版本以尽可能优化。数据结构看起来像这样:

                                    BaseProduct
/\
/ \
/ \
/ \
/ \
CustomisedProductA CustomisedProductB
/ \ / \
CustomisedProductA1 CustomisedProductA2 CustomisedProductB1 CustomisedProductB2

这里的总体思路是:

  • 数据库中存储了一个基础产品。
  • 可对此产品应用一级定制 - 例如有关该产品在销售区域的特定版本的信息。
  • 可以在其中应用第二级定制 - 例如在某个地区的特定商店中有关此产品的信息。

数据以这种方式存储是因为数据检索/计算过程的每一步都是昂贵的。第一次为某个地区检索特定产品时,将执行一组定制以使其成为特定于地区的产品。第一次为商店检索特定产品时,我需要根据区域产品执行自定义以生成特定于商店的产品。

问题是由于我可能需要通过几种方式使数据无效:

  • 如果基础产品数据发生变化,则整棵树都需要失效,所有内容都需要重新生成。 I can achieve this by storing the whole structure in a hash and deleting the hash by its key .
  • 如果产品的第一组定制发生变化(即中间层),那么我也需要使该层下的节点失效。例如,如果 CustomisedProductA 的定制受到更改的影响,我需要使 CustomisedProductA、CustomisedProductA1 和 CustomisedProductA2 过期。
  • 如果产品的第二组定制发生变化(即底层),则该节点需要失效。我可以通过调用 HDEL key field(例如 HDEL product CustomisedProductA:CustomisedProductA1)在哈希中实现这一点。

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

最佳答案

至少有 3 种不同的方法,每种方法各有利弊。

第一种方法是使用树的非原子临时扫描来识别和使树的第 2 层(第 1 组定制)无效(删除)。为此,请为您的哈希字段使用分层命名方案,并使用 HSCAN 遍历它们。 .例如,假设您的哈希键名称是产品的 ID(例如 ProductA),您将使用类似“0001:0001”的名称作为第一个自定义版本的字段名称,“0001:0002”作为第二个版本的字段名称,等等。同样,'0002:0001' 将是第二个定制第一个版本,等等...然后,找到所有定制 42 的版本,使用 HSCAN ProductA 0 MATCH 0042:*, HDEL回复中的字段,并重复直到光标归零。

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

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

请注意,这两个操作应该在单个事务中(即使用 MULTI\EXEC block 或 EVAL Lua 脚本)。设置好后,使自定义无效只需调用 SMEMBERS 即可。在相关的 Set 上并从 Hash 中删除其中的版本(以及 Set 本身)。然而,需要注意的是,从大型 Set 中读取所有成员可能很耗时 - 1K 成员还不错,但对于较大的 Set 有 SSCAN .

最后,您可以考虑使用 Sorted Set 而不是 Hash。虽然在这个用例中可能不太直观,但 Sorted Set 可以让您执行所需的所有操作。然而,使用它的代价是,与哈希的 O(1) 相比,添加/删除/读取的 O(logN) 的复杂性增加了,但考虑到数字,差异并不显着。

要释放 Sorted Set 的力量,您将使用字典顺序,以便所有 Sorted Set 的成员都应具有相同的分数(例如使用 0)。每个产品都将由一个 Sorted Set 表示,就像哈希一样。 Set 的成员等同于 Hash 的字段,即自定义的版本。 “技巧”是以一种允许您执行范围搜索(或者如果您愿意的话,也可以执行 2 级失效)的方式构建成员。这是它应该是什么样子的示例(请注意,这里的关键 ProductA 不是哈希而是排序集):

ZADD ProductA 0 0001:0001:<JSON>

要读取自定义版本,请使用 ZRANGEBYLEX ProductA [0001:0001: [0001:0001:\xff并从回复中拆分 JSON 并删除整个自定义,使用 ZREMRANGEBYLEX .

关于caching - 如何使 Redis 缓存中数据的层次结构(树)的部分无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36743354/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com