【问题标题】:Instant Messaging Schema design advice即时消息架构设计建议
【发布时间】:2020-01-29 17:10:11
【问题描述】:

我正在尝试在我的应用中构建即时消息功能,作为更大项目的一部分。

  • 聊天可以有超过 2 个参与者(群聊)
  • 如果参与者 A 删除了一条消息,参与者 B 仍然应该可以看到它(这就是我使用 Message Participants 表的原因)
  • 同样适用于对话。
  • 按照相同的逻辑,如果所有参与者都删除了对话/消息,则应将其从 DB 中删除。

问题:

  1. 恐怕这个架构太麻烦了,这意味着一旦应用获得一定的流量标记(1k 活跃用户?我猜),查询就会太慢

  2. 消息参与者将有每条消息的多条记录 - 聊天中的每个参与者都有一条记录。即时消息意味着它将涉及那些时间非常紧迫的写入。那不是问题吗?

  3. 是否应该添加一层 Redis DB 来管理聊天的活动会话的消息传递?它将存储最近的消息,并主动将 PostgreSQL 数据库与这些消息同步(也许与 postgresql 具有的异步事务功能?)

更新架构:

  • 我也很乐意听到有关“读取”状态功能的想法。我假设群组聊天要复杂得多,所以至少为 1:1 聊天提供这个功能会很好。

【问题讨论】:

  • 您使用什么工具制作这些图表?我真的很喜欢美学

标签: postgresql database-design schema chat instant-messaging


【解决方案1】:

我对你的图表有点困惑。对话参与者不应该链接到对话而不是消息吗? FK 看起来不错,只是线条看起来不对。

我还不会担心性能。 Premature Optimization Anti-Pattern 警告我们不要因为性能原因而放弃干净的设计,直到我们知道我们是否会遇到性能问题。您预计有 1000 个用户——这对于现代信息系统来说并不算多。即使它们同时处于活动状态,每 10 秒输入一条消息,这也仅意味着每秒 100 笔交易,这没什么好怕的。当然,我不知道你要在哪个平台上运行它。但是设置这些表并编写一个尽可能快地插入这些记录的简单测试程序应该是一件容易的事。

您的第二个问题让我想知道您希望消息传递的“即时”程度。消息的所有查看者都应该在一毫秒内收到文本的每个键击吗?还是他们只需要看到每条消息在发布后立即出现?无论如何,限制用户响应的因素可能是网络,而不是数据库。

也许这主要不是数据库设计问题。让我们假设您的发帖率和观看率都很高。但并非所有对话都会一直很忙。如果需要 - 但不是更早 - 可能有必要将当前繁忙的对话保存在内存中,并使用数据库作为未来不忙时的备份。

关于您的额外 cmets:

100k 用户:这不是本论坛的主题,而是关于创业公司的业务发展。许多初创公司的创始人都想象着大量的用户被他们的网站所吸引,而实际上大多数初创公司只是失败了,或者只接触到了极少数的用户。因此,请注意只有在极不可能的情况下,您的公司将成为下一个 Whatsapp 的情况下,投资(金钱,以及设计和实施工作)才会有所回报。

如果您并没有真正预料到会有这么多用户,而只是想把这想象成一个编程练习,那么您仍然面临着一项艰巨的任务。您将没有模拟流量的平台,因此无法对实际需要解决的性能问题进行测量。这就是过早优化警告的原因之一:除非您明确知道瓶颈在哪里,否则您和我们所有人都只是猜测,可能会做出错误的决定。

将消息标记为已读很容易:在消息参与者中引入布尔属性read,并在用户阅读消息后立即将其设置为true。在何种情况下以及向谁展示这取决于您的业务需求。

【讨论】:

  • 感谢您的帮助!是的,一个小小的疏忽,你是完全正确的。我已将更新的架构添加到帖子中。 (我还从附件添加了一个 FK 到用户)。现在,关于 1000 个用户——我只是用它来猜测我什么时候会遇到性能问题。我实际上的目标是为大约 10 万用户构建一些东西。这听起来有点雄心勃勃,但我也将此作为一个项目来学习如何构建质量数据库。我绝对明白 Facebook 规模之类的东西没有意义,但 100k 应该是合理的
  • 关于 IM - 您的第二个选项就是我所说的“即时”:他们只需要看到每条消息在发布后立即出现。从这个意义上说,它应该像 Whatsapp(“他们正在输入”选项可能很好,但不是必需的。除非你能提出一种实现它的方法?)。而且我还想添加将消息标记为“已读”到另一方的功能(仅在 1:1 聊天中,因为在群聊中我认为这会更有问题)。你能建议一个方法吗?
  • 另外,关于我对添加 Redis 的考虑,我在某处读到 Postgresql 使消息发送“滞后”到另一端,几秒钟......这对于 IM 来说是有问题的。这就是为什么我正在考虑添加一个 Redis 层,它会存储最新的 X 消息(可能是 100 条?),然后即使你刚刚登录到套接字,获取也会更快,而不仅仅是在你积极登录的时候它。但我可能是错的,所以我很乐意听取您的意见。顺便说一句,后端平台将是 nodejs。我的另一个担心是如果很多用户发送大量消息,消息表会变得很大。
猜你喜欢
  • 2011-12-28
  • 1970-01-01
  • 2012-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多