Redis Twitter般的Follow / Unfollow设计模式

时间:2012-06-05 10:50:10

标签: algorithm architecture nosql redis twitter-follow

假设我们正在复制Twitter的跟随功能。据我所知,现在每个人都同意使用Redis进行以下设计。

所有跟随joe的推文都存储在一个有序的集合“ss:joe”中,其中key = tweet_id,score = tweet_timestamp

所以,当joe跟随ladygaga时,ladygaga的推文被添加到“ss:joe”,到目前为止一直很好。

问题是:当joe取消关注ladygaga时,如何从“ss:joe”删除ladygaga的推文?

迭代每一首“ss:joe”推文并删除那些属于ladygaga的内容。

我能想到的最好的方法是为每个存储她自己的推文的用户维护另一个排序集,所以ladygaga将使用key = tweet_id,score = tweet_timestamp将她的排序集“tweets:ladygaga”,然后我们可以选择ladygaga的ZINTERSTORE的推文“ss:joe”和“推文:ladygaga”。

有更好的解决方案吗?

1 个答案:

答案 0 :(得分:3)

这个设计存在更大的问题。将tweet_id存储在ss:joe中意味着系统无法考虑gaga创建新推文(或删除一个,如果支持的话)而不修改ss:joe。现在想象一下有几百名明星,每人有50,000名粉丝,每人每天写十几条推文。这是很多插入很多集合,你也不能轻易分发。而且,这是一个很多重复的数据(记住redis是一个只有RAM的数据库,虽然RAM变得更便宜,但它仍然没有“无限”)。 编辑:为了更新关注者记录,您还需要了解关注者(因为在每个新写的推文上迭代每个用户几乎都不是一个选项)。因此,您还需要维护一个反向链接列表。

另一种设计方法是将所关注人员的用户ID存储在一个集合中(如果愿意,可以存储已排序的集合,因此用户可以对该顺序进行随机播放)。每个人还有一个排序集,其中包含所有推文ID(按日期排序)。

这将需要一个额外的查询每个被跟踪的人来获取推文ID,但它会减少取消关注从一个集合中删除一个值,并且它会在创建新推文时自动更新所有人

查找比插入/删除(可能需要重新平衡或重新散列)成本更低,所以即使你跟随十几个人,这些额外的查询可能不会像更频繁的更新一样多。
此外,查找实际上可能发生在复制从属网络上(在每个人都可以看到新推文之前,可能会有一两个查询,但是谁在乎 - 它会无限扩展)。