Facebook 或 Twitter 如何实现他们的订阅系统

Posted

技术标签:

【中文标题】Facebook 或 Twitter 如何实现他们的订阅系统【英文标题】:How did Facebook or Twitter implement their subscribe system 【发布时间】:2015-05-20 04:38:24 【问题描述】:

我正在开发一个类似 SNS 的移动应用项目,用户可以在其中上传他们的内容,并可以在他们的主页上看到他们订阅的主题或朋友的更新。

我将用户内容存储在 mysql 中,并通过简单地首先查询用户订阅的人员和内容,然后使用 'where userid IN (....) 或主题查询过滤掉的内容表来查询用户特定的主页数据IN (....)' 子句。

我怀疑当内容表堆积或用户订阅大量用户或主题时,这会变得非常慢。我们新发布的应用程序已经开始每周有成千上万的新用户,并且随着时间的推移越来越多。可扩展性现在必须是我们关心的问题。

所以我想知道 Facebook 或 Twitter 如何处理数量惊人的订阅问题。他们是否为每个用户处理一个列表?我试图搜索,但我得到的只是如何与 Facebook 或 Twitter 交互,而不是他们如何实际实现此功能。

我注意到,您在使用 Facebook 时,只会在您的提要中看到更新而不是历史记录。这意味着订阅新用户不会像使用我当前的方法那样将大量过时的内容转储到您的提要中。

Facebook 如何设计他们的数据库以及他们如何向订阅用户发送新内容?

我的后端目前是 php+MySQL,如果应该这样做的话,我不介意引入其他后端技术,例如 Redis 或 JMS 之类的东西。

【问题讨论】:

【参考方案1】:

听起来你们还处于早期阶段。有 N 多种方法可以解决这个问题,这取决于你认为你会在短期内达到 DAU 的哪个阶段、你必须在硬件上花多少钱、你手中的时间来构建它等等。

您可以尝试一个临时表,该表将新引入的项目、其包含的元数据(哪个主题、朋友 user_id 列表等)排队。然后使用像 RabbitMQ/GearMan 这样的队列消费者系统来管理这个不断增长的列表的消费,并确定谁应该处理这个。在 Scala 或 J2EE 系统(如 Maven/Tomcat)中构建队列消费者程序,这些程序可以持续存在。如果你真的想坚持使用 PHP,构建一个 PHP REST API,它可以存在于 php5-fpm 的内存中,并由 FastCGI 进程管理器管理,并通过像 nginx 这样的代理调用,由 curl 调用以适当的时间间隔从执行的 cron 启动脚本。

[编辑] - 最好不要将数据库用于排队系统,使用像 Redis 这样的缓存服务器,它在许多方面都优于数据库,并且可以持久保存到磁盘(查找 RDB 和 AOF)。万一作业突然失败,它的容错性不是很好,您可能会丢失作业记录。您很可能不会关心这些崩溃边缘情况。还要查找php-resque!

为了让 SNS 有效地退出,我假设您已经对表格进行了非规范化。我想象一个“user_topic”表,其主题映射到订阅它们的用户。创建另一个表“notification_metadata”,描述用户喜欢在哪里接收通知(短信/推送/电子邮件/应用内通知),以及推送到这些渠道所需的元数据(APNS/GCM 的移动客户端批准密钥、电子邮件地址、用户身份验证令牌)。对 notification_metadata 中的两个字段使用 JSON blob,因此每个用户将只有一行。这可以节省数据库上的 I/O 命中。

使用 user_id 作为“notification_meta”的主键,使用 user_id + topic_id 作为“user_topic”的主键。不要为任何一个添加自动增量“id”字段,在这个用例中它非常没用(占用空间、CPU、索引内存等)。如果两个字段都在 PK 中,则 user_topic 上的查询将全部来自内存,并且唯一的磁盘命中是在 JOIN 期间的“notification_meta”上。

所以如果一个用户订阅了 2 个主题,“user_topic”中会有两个条目,每个用户在“notification_meta”中总是会有一行

还有更多的扩展方式,比如为每个新主题动态创建一个新表、根据 user_id 分片到不同的 MySQL 实例、分区等。有 N 种扩展方式,尤其是在 MySQL 中。祝你好运!

【讨论】:

以上是关于Facebook 或 Twitter 如何实现他们的订阅系统的主要内容,如果未能解决你的问题,请参考以下文章

如何从 MSN、Twitter、Facebook、GMail 等中检索联系人/电子邮件?

Javascript - WinRT - 如何与 twitter 或 Facebook 分享分数?

如何在iOS中为twitter和Facebook实现通用深层链接?

如何在没有 Facebook、Twitter 等的情况下将社交功能集成到 iOS 和/或 Android 应用程序中?

如何在 iPhone 应用中实现 Facebook 和 Twitter 通知表

Oauth - Facebook/Twitter/Foursquare