Redis缓存设计

Redis cache design

我想在我的 node.js API 中集成一个缓存层。我以前从未建造过所以我有几个问题。

我有对象叫做 "containers"

我想按 id 查找这些容器。通常一次有多个容器。查找不一致,每个用户都会有一组不同的查找 ID。

我暂时不需要查询数据。所以我开始使用 key/value 存储,其中的键类似于 "container_1",数据是序列化的 json 表示。

但我必须高效地同时查找多个容器。我注意到散列数据类型,所以现在我这样做了“hmset containers [id] [serialized json]。这样我就可以对 return 容器 1、3、4 执行 hmget containers 1 3 4

hmset containers:1 name test-container一样将散列存储在redis中作为真实对象会更好吗? 这是处理数据的有效方式还是正常方式?从时间复杂度的角度来看,这种策略如何扩展到数万或数十万条目?我可以在集合上使用 expire 键吗?

谢谢

这里有几个问题。我会尽量一一解答。

听起来您提出了三种可能的存储方案。以下是关于每种后果的一些说明。

选项 #1:将每个序列化容器存储在字符串键中

您可以使用 MGET 轻松地一次检索多个容器。此选项在性能上应与将所有容器存储在单个哈希中相同。此选项将需要稍微多一点的内存,因为顶级键比散列字段有更多的开销。您可以获得使用顶级密钥的优势,因此您可以单独使容器过期并在单个容器上使用其他密钥命令,如 DUMP/RESTORE/OBJECT/MIGRATE .

选项 #2:将所有序列化容器存储在一个散列中,每个容器都在散列中的一个单独字段中

如您所述,HMGET 可让您一次检索多个容器。此选项比选项 #1 的内存效率略高。这也允许您的顶级密钥 space 保持较小,因为它不会随着每个容器而增长。这个优势并不显着,但却是一个小的管理帮助,因为您可以更轻松地使用 KEYS 命令。它应该和选项 #1 一样快。

选项 #3:将每个容器存储在散列中,以某种非序列化的格式,散列字段对应于容器属性

如果每个容器都是一个 JSON 对象,这应该可以很好地映射。当对象的值不是简单字符串时,您仍然必须决定要做什么。您可能仍然需要将每个值存储为 JSON 或其他一些序列化格式。这个解决方案可以说是最复杂的。尝试在 javascript 中重新创建原始容器时可能会影响性能,因为每个 属性 都需要独立解析并重组为最终对象,除非驱动程序在某处为您执行此操作。

这种方法可以使检索容器的特定字段变得更加容易和高效。

使用这种方法在一个命令中检索多个容器会更加困难,因为它需要 pipelining or Lua scripting

结论

每种方法的适用性、可扩展性和时间复杂性在很大程度上取决于您的访问模式。您是否正在尝试按容器属性的值进行搜索?然后,选项 #3 开始看起来很有吸引力。否则,选项 #1 和 #2 看起来最有吸引力。理想情况下,您将使用额外的键为各种用例构建数据索引。您可能有一个包含属于用户的容器 ID 的集合,或者一个包含按上次更新时间排序的容器 ID 的列表。

所有这些方法都是合理的,使用额外的索引可以帮助确保其中任何一个都可以扩展。

Can I use the expire key on sets?

是的。无论类型如何,您都可以使任何密钥过期。字符串、散列、列表、集合等