2

假设我们正在复制 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 将拥有她的排序集“tweets:ladygaga”,key=tweet_id, score=tweet_timestamp,然后我们可以通过 ZINTERSTORE 挑选出ladygaga 的推文“ss:joe”和“tweets:ladygaga”。

有更好的解决方案吗?

4

1 回答 1

3

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

另一种设计是将关注的人的用户 ID 存储在一个集合中(或排序集合,如果你愿意,这样用户就可以打乱顺序)。每个人还有一个带有所有推文 ID 的排序集(按日期排序)。

这将需要每个被关注的人额外查询来获取推文 ID,但它将减少不关注从一组中删除一个值,并且它将在创建新推文时自动更新每个人。

查找比插入/删除(可能需要重新平衡或重新散列)成本更低,因此即使您关注十几个人,这些额外的查询也可能不像更频繁的更新那样严重。
另外,查找实际上可以在复制的从属网络上发生(在每个人都可以看到新推文之前可能会经过一两秒,但谁在乎——它可以无限扩展)。

于 2012-06-05T11:20:38.223 回答