java - Redis 使用对象引用吗?

标签 java caching redis

我正在尝试评估缓存技术的多种选择。我最终决定使用 Redis/Elasticache 配合 Redis。在了解了 Redis 的持久化、复制机制、分片/集群、命令和 Redis 内存管理之后,我最终决定使用 Redis 来设计我的缓存引擎。

但一开始我就遇到了一个关键的设计问题

我的应用程序处理森林类型数据结构(即树的树)。增强我的缓存。我决定设计 3 个缓存'

  1. 将维护林列表的第一个缓存
  2. 当用户从一棵树遍历森林到另一棵树时。指向当前树的指针将保存在第二个缓存中
  3. 当用户遍历每棵树的节点时,指向当前节点的指针将保存在第三个缓存中

简单来说,第三个缓存(节点)的元素必须指向第二个缓存(树)的元素,第二个缓存(树)的元素必须指向第一个缓存(森林)的元素。

但问题是 Redis 并不像 Java 那样维护对象的引用。换句话说,如果我在 Java 或 Spring 中创建了相同的缓存,那么我的第一个缓存将保存森林,第二个缓存将仅维护一个指向第一个缓存中当前树的指针,而第三个缓存将维护一个指向第二个缓存指向的树中的节点。

以这种使用引用的方式,我会节省大量内存,因为我只是在第一个缓存中加载森林的一个实例,而其他缓存元素仅保存指向第一个缓存的指针/引用。

如果在redis中执行相同的操作,每个 keystore 实际上都会存储对象的完整实例,这意味着第一个缓存将存储完整的森林,第二个缓存将保存当前树的不同实例,而渴望将保存当前实例树节点。

考虑一个大小为 10 GB 的森林,每棵树大小为 500 MB,当前节点的平均大小为 50 MB,那么对于遍历该树的一个用户,redis 将在任何情况下保持 10 GB + 500 MB + 50 MB = 100550 MB 平均内存片刻。假设我有 100 个当前用户登录并使用同一个林,那么我的内存使用量将为 10 GB + (500 MB x 10) + (50 MB x 10) = 150500 MB

但是,如果我使用基于 Java 的缓存引擎,那么无论有多少用户,我的利用率都将始终为 10GB,因为一旦加载了林,其他缓存将仅保存消耗的空间可以忽略不计的对象引用。

对此有什么想法吗?可以使用 Redis 来存储对已存储对象的引用而不是创建新实例吗?

最佳答案

在最基本的层面上,Redis 存储标量值,所以不,它不会像您想象的那样工作。但是,您可以使用集合和哈希(或字符串)的组合来伪造它。假设您使用 12345|TREE(其中 12345 是树的 ID)等缓存键将每个单独的树项存储为哈希(或 JSON 字符串,以更适合您的情况为准)。然后您就有了一个存储所有树 ID 的集合。

sadd TREES 12345 12346 12347 (etc)
hset 12345|TREE node1 node1value
hset 12345|TREE node2 node2value

类似地,为当前树的用户和各个项目创建一个集合,并对各个节点执行相同的操作。

sadd USERS mgandhi froosevelt nmandela
set mgandhi|TREEID 12345
set froosevelt|TREEID 12346

set mgandhi|NODEID 1
set froosevelt|NODEID 2

然后就可以使用SORT命令找出每个用户的位置:https://redis.io/commands/sort (即使您不需要对结果进行排序):

sort TREES by nosort get *|TREEID get *|NODEID

希望这对您有用。

关于java - Redis 使用对象引用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57639686/

相关文章:

java - Antlr4 中未找到 getType() 方法

css - Google Cloud CDN 不从存储桶中缓存?

java - 自动清除 Java Web Start 缓存

java - 无法始终在单击和悬停时加载图片

java - HikeriCP : java. sql.SQLException:关闭与显式目录的连接时目录不能为空

java - 通过 OSMDroid 使用在线存储中的 MBTiles

reactjs - 有没有办法检测查询使用的数据何时从 Apollo 客户端缓存中逐出?

java - Redis - 存储和获取带有详细信息的有限 key

spring-boot - Redis put() 语句中使用的键和散列键参数有什么区别?

flask - 多个同时使用的单个 Redis 实例