将实时聊天中的消息保存到 MySQL vs Dynamodb 的策略

Posted

技术标签:

【中文标题】将实时聊天中的消息保存到 MySQL vs Dynamodb 的策略【英文标题】:Strategy to Save messages from live chat into MySQL or Dynmodb 【发布时间】:2018-06-25 03:08:30 【问题描述】:

我正在编写一个实时聊天应用程序,它将被许多用户使用。我正在考虑使用 Amazon 的 ElasticCache Redis 来管理我们的 PUB/SUB 和最新消息缓存。

我看到的唯一问题是将这些实时消息保存到数据库以供将来使用。关于我可以使用什么策略将这些消息从弹性缓存保存到数据库中的任何建议。

首选 RDS 还是我应该使用 NoSQL,例如Dynmodb 来存储这些消息? 我应该创建一个队列来存储来自缓存的这些消息还是实时保存它们也可以工作。

谢谢

【问题讨论】:

【参考方案1】:

此处的适当策略在很大程度上取决于数量、预期的查询模式和消息保留率。假设您希望支持永久保留并从那里迁移:

大型 RDS 实例每秒可以轻松处理数千次写入,而读取从属服务器将有助于有效平衡读取负载。特别是Aurora 对此非常有用,我建议您研究一下并将其与传统 RDS 进行比较。此外,底层机制的 Postgres 将具有比 mysql 支持的实例更高的写入吞吐量,因为不同的锁定策略更有利于整体吞吐量。如果您的实时消息是通过 pubsub 系统中继的,那么 redis 中的额外“最近消息”缓存实际上可能不是必需的,并且可以由读取从属设备处理,如果音量足够低,则可以由主设备处理。这也取决于聊天系统的类型。一对一聊天与基于房间的聊天或全球聊天将具有显着不同的阅读特征。

SQL 解决方案的最大问题是消息随时间推移,并且如果您的消息数量达到十亿以上规模,则能够有效地随时显示任何消息。根据不同的聊天类型,这可能是可分片的,但是像 NoSQL 解决方案这样的解决方案可能更有意义。当然,他们并非没有警告。它们将更横向扩展,能够在顶端处理更高的每秒写入或消息数量增长,并且基于数据模型具有更自然的分片能力,但数据模型将更具限制性且更难查询以某种方式。

话虽如此,为简单起见,如果您不打算通过十亿消息标记或每秒 1000 条消息,那么从 SQL 开始可能会提供一些简单性和灵活性。从专业知识较少的 NoSQL 数据库开始,比遇到意外警告或开发问题更容易让您陷入困境。

就您实际使用的写入模式而言,我认为先写入数据库,然后再写入缓存,并在成功写入后发布到 pubsub 主题有助于确保历史一致性。这也取决于您想要做出的保证。如果实时交付比历史准确性更重要,则可能适用相反的顺序。但是,如果您选择 SQL 数据库,这将意味着您的吞吐量直接与单个 SQL 主机的写入吞吐量相关联。 Postgres 最近引入了双向复制的可能性,它为您提供多主机支持,但它有很多警告,我不相信 RDS 支持。

对于 pub-sub,redis 可能就足够了,但这又取决于规模。在高端,更分布式和容错的东西可能更合适。例如,AWS 有一个专用的pubsub service with SNS。这将具有减轻管理的好处,并且在消息吞吐量方面可能会有更多的增长空间。 Redis 很棒并且快得令人难以置信,但它也将成为单点故障,受内存限制,并且最终绑定到单个线程。但是,如果您从规模的低端开始并且不打算达到非常高的吞吐量,那么 Redis 就足够了。

重要提示:然而,将 redis 用于 pubsub 的一件事是 redis should not be exposed to outside connections。这是一个潜在的巨大安全问题,因此如果您的网络外部有客户端直接连接(就像我假设您希望使用聊天系统一样),Redis 将是一个糟糕的选择。应始终阻止外部连接。 总是


TL;DR: - 对于较低的规模,RDS 可能会在很长一段时间内通过传统的主从设置满足您的需求,但像 Dynamo 或 Cassandra 这样的 NoSQL 解决方案将更好地满足长期增长、难以置信的高吞吐量或大量数据量的需求。 - 出于安全方面的考虑,Redis 不太可能是 PUBSUB 的最佳选择,对于缓存层可能需要也可能不需要,但其他 pubsub 技术可能足以用于实时消息传递。

【讨论】:

以上是关于将实时聊天中的消息保存到 MySQL vs Dynamodb 的策略的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 和 websocket 创建实时聊天

Django 频道实时聊天保存发送的消息

使用 PHP 和 jQuery 进行实时聊天。在哪里存储信息? mysql还是文件?

实时聊天、消息处理 - Socket.io、PHP、MySQL、Apache

Firebase 网络将聊天存储为实时数据库中的数组

Ajax vs Comet(不是聊天应用程序)