首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有什么更好的数据结构可以用redis存储用户配置文件?

有什么更好的数据结构可以用redis存储用户配置文件?
EN

Stack Overflow用户
提问于 2017-01-17 12:50:30
回答 3查看 2.6K关注 0票数 5

我想将用户的配置文件存储在redis中,因为我必须经常读取多个用户的配置文件.。我认为目前有两种选择:

选项1: -根据用户配置文件存储单独的散列键

  • 散列- u1配置文件{id: u1,名称:user1 1,email:user1@domain.com,照片:u1}
  • 散列- u2配置文件{id: u2,名称:user2 2,email:user2@domain.com,照片:u2}
  • 其中,每个用户的id是散列键和配置文件字段,值为JSON序列化的配置文件对象。(或代替json用户字段-值对)

选项2: -使用单个散列键存储所有用户配置文件

  • 哈希-用户-配置文件u1 {id: u1,名称:user1 1,email:user1@domain.com,照片:url}
  • 散列-用户-配置文件u2 {id:u2,名称:user2 2,email:user2@domain.com,照片:url}
  • 在用户配置文件哈希键中,用户in字段和值JSON序列化的配置文件对象。

请告诉我考虑以下哪一种选择是最好的:

  1. 性能
  2. 内存利用
  3. 读取多个用户的配置文件-对于批处理,我应该能够同时读取1-100,101-200用户的配置文件
  4. 更大的数据集--如果有数百万用户配置文件呢?
EN

回答 3

Stack Overflow用户

发布于 2018-09-06 14:05:46

正如Sergio所指出的,以任何方式将所有用户的数据(特别是数据集很大)存储在一个散列中是不好的。

如果您正在寻找内存优化(如本博客帖子中所指出的),则也不希望将用户数据存储为单独的键。

使用分页机制读取用户的数据需要使用数据库,而不是像redis这样简单的缓存系统。因此,建议为此使用NoSQL数据库(如mongoDB )。

但是每次从数据库中读取数据是一项昂贵的操作,特别是当您正在读取大量记录时。

因此,最好的解决方案是在redis中缓存最活跃用户的数据,以消除数据库获取开销。

我建议你调查一下海象

它基本上遵循以下模式:

代码语言:javascript
复制
@cache.cached(timeout=expiry_in_secs)
def function_name(param1, param2, ...., param_n):
    # perform database fetch
    # return user data

这确保频繁访问或请求的用户数据在redis中,并且函数会自动从redis返回值,而不是进行数据库调用。此外,如果在很长一段时间内未被访问,则密钥将过期。

您将其设置如下:

代码语言:javascript
复制
from walrus import *
db = Database(host='localhost', port=6379, db=0)

主机可以使用远程运行的redis集群的域名。

希望这能有所帮助。

票数 2
EN

Stack Overflow用户

发布于 2018-09-05 13:41:53

备选案文1。

  • Performance:通常它取决于您的用例,但假设您希望读取特定的用户(登录/注销、授权目的等等)。使用选项1,您只需计算用户哈希并获取用户配置文件。使用选项2,您将需要获得所有用户配置文件并解析json (尽管您可以使其高效,但它永远不会像选项1那样高效和简单);
  • 内存利用率:您可以使选项1和选项2在redis中保持相同的大小(在选项1上,可以避免将散列/用户id存储为json的一部分)。但是,在选择相同的示例来加载特定用户时,只需要在代码/内存中使用单个用户配置文件json,而不是具有一组用户配置文件的更大的json。
  • 读取多个用户的配置文件--对于批处理,我应该能够在时读取1-100、101-200用户的配置文件:为此,就像通常在关系数据库中所做的那样,您希望进行分页。在是使用redis进行分页的不同方式。中使用扫描操作是一种简单的方法,可以迭代一组用户。
  • 更大的数据集-如果有数百万用户配置文件

Redis是内存中的,但在磁盘数据库中是持久化的,因此它代表了一种不同的折衷方法,在这种情况下,可以实现非常高的写入和读取速度,但不能超过内存的数据集的限制。

如果“无法拥有更大的内存数据集”,则可以将分区视为Redis FAQ建议。在Redis FAQ上,您还可以检查其他指标,如“单个Redis实例可容纳的最大键数”或"Redis内存占用量“。

票数 1
EN

Stack Overflow用户

发布于 2018-09-07 12:44:50

备选方案1的利弊

(但不要使用散列,使用单键。(如SET profile:4d094f58c96767d7a0099d49 {...}__)

  • 迭代键比迭代散列稍微快一些。(这也是为什么您应该修改选项1以使用SET,而不是HSET)
  • 检索键值略快于检索哈希字段。

备选方案2的利弊

  • 您可以使用HMGET在一个单独的调用中获得所有用户,但前提是您的用户基础不是很大。否则,服务器很难为您提供结果。
  • 您可以在一个命令中刷新所有用户。如果您有后台DB,那么很有用。

备选方案3的利弊

选项3是在由散列从用户id确定的散列桶中破坏用户数据。如果你有很多用户,并且经常做批次的话,效果会很好。如下所示:

代码语言:javascript
复制
HSET profiles:<bucket> <id> {json object}
HGET profiles:<bucket> <id>
HMGET profiles:<bucket> 

最后一个得到一整桶档案的人。建议不要超过100万桶。使用顺序ids很好,而对散列则不太好,因为它们的可能会增长太多。如果您在散列中使用它,并且它增长得太快,以致您的红宝石速度减慢,那么您可以回到HSCAN (如option2中),或者使用新的哈希函数将对象重新分发到更多的桶中。

  • 快批负荷
  • 稍慢的单个对象存储/加载

我的建议,如果我把你的情况正确,是使用第三选项与顺序ids范围100。如果您针对大量的数据,计划从第一天开始集群。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41697688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档