redis 如何存储大型 set - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhy
V2EX    Redis

redis 如何存储大型 set

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

    以新浪微博的点赞功能为例, 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     Solana     3999 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 61ms UTC 05:28 PVG 13:28 LAX 21:28 JFK 00:28
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86