V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhy
V2EX  ›  Redis

redis 如何存储大型 set

  •  
  •   zhy · 2015-08-17 10:05:01 +08:00 · 6650 次点击
    这是一个创建于 3368 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以新浪微博的点赞功能为例, key 为 topic id , value 为 set 类型,里面存储点赞用户的 uid (考虑按点赞时间倒序排列)。

    当点赞用户较少时(比如 10W ),性能应该还 OK ;
    但是对于某些热门微博,点赞数上到几百万,这时候所有的 uid 放到一个 set 里明显就不是很明智了。

    看了下 redis 集群分片的功能,好像主要适用于海量 key 的情形,而这里的问题不是针对 key 的数量,而是对于 value 的值太多了。

    我想到修改 key ( topic id + something )的方式来达到变相的分片,但是要满足插入、删除、分页去 ID 的功能貌似有点难。

    求大侠给点指导~

    第 1 条附言  ·  2015-08-17 10:50:27 +08:00
    错字更正:列表取 ID

    比如微博的这个功能: http://weibo.com/1537790411/CuIbfpsJI?type=like#_rnd1439779817776
    12 条回复    2017-10-15 20:26:53 +08:00
    celon
        1
    celon  
       2015-08-17 10:22:27 +08:00 via iPhone
    key -> set 变为 key+attr -> value
    插入删除 set 变为加减 key
    查询 set 改为使用 lua 获得有统一前缀的所有 key
    zhy
        2
    zhy  
    OP
       2015-08-17 10:52:36 +08:00
    @celon 你的意思是直接不使用 set 吗?这样的 key 也会用到,但是对于取 list 的功能会比较麻烦。
    又加了个微博的链接,分页是根据排序结果做的,微博这里应该不是这样做的,否则会很慢吧
    slixurd
        3
    slixurd  
       2015-08-17 11:04:07 +08:00
    如果不放进 HashMap/SET 里,你就要考虑内存空间消耗了
    在大量数据的情况下还是放在 HashMap 里吧,能节省不少空间,虽然说 CPU 时间也相对会增加一些
    9hills
        4
    9hills  
       2015-08-17 11:17:23 +08:00
    有个很简单的做法,一个微博只保留最近 N 个赞(如 N=20 )
    然后为每个人记录赞过的微博即可。

    因为没有什么需求需要找出赞过某个微博的全部人。。
    celon
        5
    celon  
       2015-08-17 12:31:29 +08:00
    @9hills 的确这个 trick 好用
    watzds
        6
    watzds  
       2015-08-17 12:39:38 +08:00 via Android
    是呀,这个点赞全记录下来干嘛
    21grams
        7
    21grams  
       2015-08-17 13:17:14 +08:00
    同意上面的说法,而且我专门去网页上试了一下,只能看到考赞数,看不到点赞人的列表的。
    zhy
        8
    zhy  
    OP
       2015-08-17 14:17:53 +08:00
    @21grams 我补充的链接是鹿晗的一条微博,可以列出全部人员的,不过估计这样点的人不多

    @celon @9hills 我也考虑过为每一个用户创建一个包含 topic id 的 set ,而且每个用户点赞数不可能到很高。这个在某些需求下可能有用,但是获取列表就做不了了。

    @watzds 记录全部人的一个需求可能是,给这些点赞的人发系统通知什么的

    @slixurd 对的。今天又看了一下微博点赞用户的列表,第一页用户是不断往后移动的,所以我觉得可能就是 redis 的 zset 做的。

    问了一下高手, 100W 个 value 对 set 来说可能问题不大,要考虑的是整个 set 的大小。另外 zset 的效率是 O (log (N ))的,条数太多,性能会有一定的下降,但可以接受。
    celon
        9
    celon  
       2015-08-17 15:00:34 +08:00
    可以做到获取列表的, 如我之前提到的 " 查询 set 改为执行 lua 获得有统一前缀的所有 key "
    yourmoonlight
        10
    yourmoonlight  
       2015-08-18 09:01:33 +08:00
    @9hills 赞!你怎么这么机智。
    neolf
        11
    neolf  
       2016-03-24 00:05:09 +08:00
    @celon 线上 redis 中取 keys 是不可行的
    qize
        12
    qize  
       2017-10-15 20:26:53 +08:00 via iPhone
    keyskeys 性能很差
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5642 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 08:00 · PVG 16:00 · LAX 00:00 · JFK 03:00
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.