社交网络通知系统


10

背景

我正在为包含一些社交网络功能的客户端开发应用程序。我原本是在开发移动前端,但当时的情况也让我负责开发后端。

作为一般背景,我们的系统允许用户关注其他用户,并收到有关他们关注的人的通知,这是您期望从社交网络获得的。需要注意的是,只有一小部分用户(最多几百个)是可追踪的,并期望大多数用户群将关注这些个人中的至少一个。

在用户界面侧,我们将有一个带有数字的通知按钮,单击该按钮将带您进入通知屏幕。

问题

我一直在研究实现通知的策略,发现的大多数资源都指向在数据库中创建一个或多个通知表。(我喜欢的一个示例是此处接受的答案:https : //stackoverflow.com/questions/9735578/building-a-notification-system)。

让我烦恼的是,大多数数据库驱动的通知策略都要求为每个关注者的每个通知插入一行。因此,如果有一千人在关注​​Sally,我们将在相应表中插入一千行。那可扩展吗?如果我们到了成千上万的用户关注Sally并且她每天发表数十条帖子的情况,会发生什么?

我最初的想法是处理查询的所有问题:通知按钮上的数字将通过请求比上次访问通知屏幕最近发布的内容的行计数来获得,而单个通知将通过更详细的查询生成当您访问通知屏幕时。这种方法不需要写入或额外的存储空间,但是不灵活,可能会严重影响服务器。

设定

后端(由先前的开发人员建立)使用CodeIgniterMySQL数据库。它目前在糟糕的GoDaddy共享托管帐户上运行,但我认为(希望吗?)在我们投入生产之前,将对其进行升级,并且托管软件包将随着用户的增长而扩展。

目前,我们唯一的前端是移动应用程序,但我们计划稍后再建立一个网站。我现在不关心从服务器获取有关通知的实时推送更新。

附录

我不专门研究后端,而我在那个部门负责。客户知道这一点,并且我已尽力解释这种性质的项目的范围,但是他们已经明确表示,在这一点上,他们将不信任任何其他人来从事该项目。在开始添加测试人员之前,我们可能还要再做一个月的工作,我才能获得任何类型的性能指标。我真的无法估计未来5年我们将拥有多少用户,或者我们将使用什么硬件,但是我认为客户希望有成千上万的用户或更多。

我希望这个问题足够具体,可以在此处发布。如果需要,我可以对其进行优化。请询问您是否有任何疑问,或者我省略了重要的详细信息。

tl; dr

  • 当所有用户都只跟随数百人时,数据库驱动的通知系统是否会对长期可扩展性产生负面影响?
  • 有没有一种方法可以使通知由数据库驱动,而无需为每个关注者的每个通知单独的通知行?
  • 完全由查询驱动的通知系统是否具有可伸缩性,或者除了不向数据库写入任何数据以外,还具有其他优点?
  • 我想得太早了吗?我是否应该仅构建一个目前可以使用的产品,并且由于客户预算有限并且我们不知道最终产品是否会流行,如果问题出现,我们可以担心对其进行优化吗?

您可以使通知过期吗?例如,删除2周以上的内容。随着站点的成熟,这应该或多或少地平衡表的大小。
GrandmasterB

那不会有问题,我更关心的是锁定性能对数据库的性能影响,每当一个受欢迎的用户发布帖子时,该数据库就将50,000个条目写入通知表中。
user45623

我在一个具有类似(但较小)通知系统的项目中工作。我有一个后台进程,它查看新帖子队列并处理通知(在这种情况下,实际上是将电子邮件插入第二个队列中以进行发送)。这不是实时的,但通常可以在几分钟内处理完所有内容。
GrandmasterB,2015年

Answers:


10

因此,如果有一千人在关注​​Sally,我们将在相应表中插入一千行。那可扩展吗?

是的,只要数据库表已正确索引。

如果我们到了成千上万的用户关注Sally并且她每天发表数十条帖子的情况,会发生什么?

假设您想永久跟踪每个通知,那么您每天将为Sally生成数十万或数十万条通知记录。像Sally这样的流量的用户比例始终很小。

我最初的想法是处理查询的所有问题:通知按钮上的数字将通过请求比上次访问通知屏幕最近发布的内容的行计数来获得,而单个通知将通过更详细的查询生成当您访问通知屏幕时。

这似乎不必要地复杂。如果您需要有关通知的详细统计信息,只需存储通知即可。

当所有用户都只跟随数百人时,数据库驱动的通知系统是否会对长期可扩展性产生负面影响?

这就是它起作用的原因...少数人总是产生绝大多数流量。

有没有一种方法可以使通知由数据库驱动,而无需为每个关注者的每个通知单独的通知行?

是的...不存储通知;只需以即发即弃的方式发送通知电子邮件即可。或者,将通知存储一段时间,然后将其丢弃。或者,在读取每个通知后将其丢弃。

完全由查询驱动的通知系统是否具有可伸缩性,或者除了不向数据库写入任何数据以外,还具有其他优点?

我不确定您的意思。如果要查询通知,则必须将其存储在数据库中。 否则,没有任何查询。

我想得太早了吗?

与可以帮助您设计带有正确表的正确归一化索引数据库的人员联系。我看不出为什么这样的数据库无法有效处理您描述的方案。

一个真实的例子

据我所知,Stack Exchange 永久存储所有内容,包括所有通知。他们使用类似于MySql的数据库技术和某些缓存技术。尽管它们的硬件和存储空间很大,但获得的流量却是一个好问题。


哇,您解决了一切!谢谢,罗伯特!数据库已规范化,但我尚未查看索引。不幸的是,我不能“与可以帮助我的人交谈”,因为条款严格,我不能与任何人讨论该项目的具体细节,并且客户已经意识到他们将不信任任何人但是我在这个项目上……嗯,我应该能够对索引进行一些研究。谢谢!
user45623

1
索引的一般经验法则:每个外键都应使用可能重复的索引。每个主键都应该已经被索引。您需要在其上搜索或应用WHERE子句的字段应被索引;那些应该很少。
罗伯特·哈维

1
这是不正确的。这是不可扩展的。对于每个“ Sally”,您都将生成N行,其中N是您的用户数。如果您有任意数量的用户,这将很快成为一个问题。100个“莎莉”向10,000个用户发布10次是每天1000万行-听起来不是很好吗?您实际上想要做的是将其反转,并在每个“ Sally”帖子中创建一行,并让所有关注Sally的用户抓住这些内容,而不是自己的个人副本。当然,如果您需要特定于用户的逻辑(例如聚合),这会引起问题...
Ben

1
……这里的“避免每篇文章排成一行”的解释显然是个稻草人,因为大多数系统都要求这些文章必须坚持下去。另外,您不会避免查询“因为它们很复杂”,因此会避免它们,因为随着系统扩展,它们会导致不可持续的开销。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.