Redis中保存好友关系,用list还是用set?

2013-01-18 09:18:52 +08:00
 yibin001
现在维护一个项目,先说说数据库的情况:
生产环境的用户量(用户表)为:1700W。
用户的关注、好友在Friends表中,记录数为:3600W,现在每天的增长量为30W左右。
id --主键,自增长
userid --用户ID
username --用户名 (冗余)
targetuserid --对方用户id
targetusername --对方用户名
friendtype --是否为好友



现在考虑对friends表做拆分,我的方法是按二个维度做拆分,也是通用做法:分成关注表与粉丝表,再对关注与粉丝做水平拆分。
这意味着:二个人的相互关注,会产生4条记录,记录数会比单独的friends表要多,但这样拆分会换来效率上的提升,这还是值得的。


最终大家还是觉得只对friends表做水平拆分,按userid区间分表,这样可以最大力度保持原表结构及原有的业务逻辑。
但这样会带来新的问题:即无法按targetuserid查找粉丝。


现在想把关注与粉丝放到Redis中,但似乎list/set都无法完全满足需求:
set可以去重,但无法用原生命令取某一区间的值(体现在分页上)。
list无法去重,但可以取某一区间,但同时,list也无法删除指定的value(比如取消对某一用户的关注)


对于分表目前来说是对friends表水平拆分,这个基本确定了,但Redis这一块有什么好办法?新浪微博也是用的Redis维护关系,它们是怎么做到的?
23067 次点击
所在节点    Redis
12 条回复
wwwjfy
2013-01-18 10:14:52 +08:00
Sorted Sets?
yibin001
2013-01-18 10:31:42 +08:00
@wwwjfy
性能上,Sorted Sets与list/set差异大吗?像关注列表还好办,每个人的关注数是有限制的。
但粉丝列表就有点夸张了,这个地方还没有完全想好怎么存粉丝。初步的粉丝存法呢,只保存1000个,1000个之后的直接DB了,况且这样的需求并不常见。
linnchord
2013-01-18 10:50:35 +08:00
好友粉丝列表一般要按关系建立时间点排序吧?还是sorted好,粉丝一般排个5页就ok吧———数据分页大多数时候是个伪需求。
wwwjfy
2013-01-18 11:24:58 +08:00
@yibin001 搜了下,看到新浪也说了,大数据量,redis做存储已经不太合适。虽然没说原因,但是内存太贵了。

是不是可以数据库做存储,redis只做cache,去重在数据库完成,redis可以只用list,设置过期时间,只存储活跃用户的数据,内存就用不了太多
xcl3721
2013-01-18 11:56:47 +08:00
微博用的hset
yibin001
2013-01-18 12:04:52 +08:00
@linnchord
哈哈~看到高兄出没。分页呢有2种排序方式:关系建立时间点和最后登录时间。

@wwwjfy
这是一个方案,设想每一个list做一个过期时间,比如7天,每个list最多只放1000个用户(排好序的),设置一下list-max-ziplist-entries,压缩一下,估计内存上会节省不好。
当然,不可能一次性把1700W用户都加载到内存,这里只做被动加载,Redis最多也只是当一个cache用。


@xcl3721
hset?hash?
TerranC
2013-01-18 12:07:32 +08:00
其实可以在前端代码逻辑里去cache
用户时常产生交互的人也就那么多
list cache一份常用关系到redis
qiongqi
2013-01-18 12:50:44 +08:00
通常来说,zset会好些,各种操作的时间复杂度,占用cpu都好过list
miizoo
2013-01-18 17:37:42 +08:00
如果列表也从redis中取的话,sorted set.
仅仅关系的话,set。
因为这样就可以用交集来看共同的好友,或是快速看是否关注了,或是看有多少个粉丝之类。
yibin001
2013-01-18 18:01:24 +08:00
@miizoo
对于分页这样的伪命题只能无视了。。。。
单单从粉丝列表/关注列来说来,set是不是错的选择,遇到一种叫“排序”的需求,就麻烦了。
比如按被关注人的上次登录时间排序。。。。。。
darklowly
2013-01-19 02:16:36 +08:00
elasticsearch+cache瞬间搞定
xatest
2013-01-19 19:11:17 +08:00
Redis的sorted set 可以同时满足取区间值和删除指定值的需求,性能上与list, set相比主要是增删操作要慢一点,list增加一个元素是O(1)的,sorted set是O(log(n))级别,假如在每个用户的好友数据量不超过1000的情况下,也就是不超过O(10)的时间复杂度,可以接受。

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

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

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

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

© 2021 V2EX