第10章用户关系服务——10.2 基于Redis中ZSET的设计

第10章用户关系服务——10.2 基于Redis中ZSET的设计
John Yaml基于Redis ZSET的设计
一开始我们很容易想到使用Redis的ZSET对象来实现用户关系服务,ZSET高效支持数据的插入与查询功能,且很容易实现按照关注时间排序。
对于每个用户来说,都使用两个ZSET对象分别维护其关注列表和粉丝列表。
- 关注列表的Key为
following_{用户ID}
,Member为被关注的用户ID,对应的Score为关注行为发生的时间。 - 粉丝列表的Key为
follower_{用户ID}
,Member为粉丝用户ID,对应的Score为用户被关注行为发生的时间。
查询某用户的关注列表 ,就是获取following_{用户ID}
集合的数据,使用ZREVRANGE命令即可实现按照关注时间从近到远排序的要求:
1 | ZREVRANGE following_{用户ID} 100 199 |
获取用户的粉丝列表也是同理,只不过读取的Key为follower_{用户ID}
。
获取用户的关注数和粉丝数即获取这两个ZSET的长度,对应的Redis命令为ZCARD。
当用户1关注用户2时,就是在用户1的关注列表ZSET和用户2的粉丝列表ZSET中新增一条记录,Score为当前时间戳:
1 | ZADD following_用户1 时间戳 用户2 |
取消关注亦是同理,只不过是在用户1的关注列表ZSET和用户2的粉丝列表ZSET中删除一条记录:
1 | ZREM following_用户1 用户2 |
当查询用户1是否关注用户2时,既可以查询在用户1的关注列表ZSET中是否包含用户2 ,也可以查询在用户2的粉丝列表ZSET中是否包含用户1:
1 | ZRANK following_用户1 用户2 |
当批量查询用户1与若干指定用户的关注关系时,可以先使用ZRANGE命令获取用户1的关注列表:
1 | ZRANGE following_用户1 0 -1 |
然后在结果中查找这些指定的用户是否存在即可。当批量查询若干指定用户是否是用户1的粉丝时,也是同理。
使用Redis ZSET实现用户关系服务比较简单,不过,它毕竟使用了昂贵稀缺的内存资源,此方案本身有一定的局限性。对于国民级社交应用来说,拥有几百万粉丝的网红、大V数不胜数,更不要说其中的大网红动辄粉丝数上亿了,这就意味着需要存储很多超长的 ZSET对象,而这对于Redis来说是一笔昂贵的开销。所以,Redis ZSET方案仅适合社交属性不强,或者用户量级不大的小型应用,并不适合拥有海量用户、社交属性强的应用。