个性化Feed的缓存策略

时间:2017-01-08 12:56:50

标签: database caching redis memcached

假设用户可以订阅其他用户的帖子,标签或他可能想要的任何其他类似标准。

在他的Feed中,应用会返回用户之间相同的“主要Feed”,并根据其“订阅”条件提供Feed项(Feed通过API提供)。

Feed数据是一种实体(帖子)。而且这个Feed是无限滚动的(分页),这增加了额外的复杂性。

如果用户之间的Feed相同,则缓存很简单,但在个性化Feed的情况下,我无法想到最好的方法。

每个“页面”都按日期范围(某一天)进行偏移。

我能想到的一种方法是:

'相同的Feed'部分由日期键缓存(某些键代表日期范围)。

个性化帖子Feed项目将单独缓存。然后我根据标准保留帖子ID的数组,例如创作用户,或标记它被分配给喜欢(用户#1:[10,15,23,64 ...],标记#FOO:[1,2,5,10 ...]),还有分隔符它们按日期范围(根据它们适合的分页部分),然后通过Redis或Memcahed中的ID通过mget / getMulti获取这些帖子并返回合并结果。

但是这种方法对我来说有点'不合适',因为它太复杂了。 要么, 使用微调数据库(假设在RAM中运行,或者在其中完全缓冲)而不进行缓存 - 在这种情况下可行(渲染/序列化时间不重要,因为我将它几乎原始传递给客户端)?

我寻求平台/缓存层不可知的一般策略建议。

2 个答案:

答案 0 :(得分:1)

以下设计可能是更好的方法。

查询处理器层: 通常,这将是一个REST API,它接受查询并返回post feed(按日期或后期计数等分页)。这将搜索帖子存储(数据库,索引存储,如solr等),并获取帖子ID列表[注意:不要加载所有帖子,只加载他们的ID。

帖子服务图层 查询处理器层将使用此服务层获取给定其ID的所有帖子。首先,它联系缓存服务层,要求发送带有ID的帖子。如果找不到它们,则获取它将从存储加载帖子并将其返回到查询处理器。此外,它会将加载的帖子发送到缓存服务层,以便将其缓存以备将来使用。

缓存服务层 给定一个帖子ID,只有当它出现在缓存中时才会返回帖子。

现在,帖子的缓存键可以帮助您加快帖子检索时间。

EG: Redis为您提供键的模式匹配。因此,使用格式为 postId:date:userId:tag1,tag2 的密钥,您可以非常轻松地使用标记或userId等发布或获取日期范围内的所有帖子。

答案 1 :(得分:1)

您所描述的内容基本上与Facebook可扩展性挑战相似,评论为here。基本上它是通过提前创建个性化的源并将它们放入memcached来解决的。

为了进一步优化,您可以记录用户阅读Feed的频率,并调整缓存对象的生命周期,以便为重度用户提供更短的时间。

同样,您需要更少地刷新那些由很少更新的源Feed组成的个性化Feed。 最后,据我所知,Facebook没有完全解决由超过5.000个来源组成的Feed的问题,这可能就是为什么他们首先将5.000个朋友限制,然后选择忽略来自不那么亲密的朋友的更新个性化饲料。因此,如果您能够承担丢失一些条目的费用,那么最后一步就是忽略一些来源。