redis 如何存储大型 set

2015-08-17 10:05:01 +08:00
 zhy

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

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

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

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

求大侠给点指导~

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

因为没有什么需求需要找出赞过某个微博的全部人。。
celon
2015-08-17 12:31:29 +08:00
@9hills 的确这个 trick 好用
watzds
2015-08-17 12:39:38 +08:00
是呀,这个点赞全记录下来干嘛
21grams
2015-08-17 13:17:14 +08:00
同意上面的说法,而且我专门去网页上试了一下,只能看到考赞数,看不到点赞人的列表的。
zhy
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
2015-08-17 15:00:34 +08:00
可以做到获取列表的, 如我之前提到的 " 查询 set 改为执行 lua 获得有统一前缀的所有 key "
yourmoonlight
2015-08-18 09:01:33 +08:00
@9hills 赞!你怎么这么机智。
neolf
2016-03-24 00:05:09 +08:00
@celon 线上 redis 中取 keys 是不可行的
qize
2017-10-15 20:26:53 +08:00
keyskeys 性能很差

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/213681

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX