mysql - 在 go 或 nodejs 中处理大量请求/秒

标签 mysql go

我正在开发一个网络应用程序,需要处理突发的非常高的负载, 每分钟一次,我在几秒钟内收到大量请求(~1M-3M/秒),然后在剩下的一分钟内我什么也得不到,

在每个前端服务器上处理尽可能多的请求/秒的最佳策略是什么,只是发送回复并将请求以某种方式存储在内存中,以便稍后在后台由 DB writer worker 处理?

目的是在burst期间尽量少做,burst后尽快将请求写到DB。

编辑:交易顺序并不重要, 我们可能会丢失一些交易,但需要记录 99% 收到所有请求到数据库的延迟可能是在收到最后一个请求后的几秒钟。假设不超过 15 秒

最佳答案

这个问题有点含糊。但我会尝试一下。

1) 您需要限制。一个简单的实现将打开数百万个到数据库的连接,这显然会表现不佳。至少,每个连接都会占用数据库上 MB 的 RAM。即使使用连接池,每个“线程”也可能占用大量 RAM 来记录它的(传入)状态。

如果您的应用服务器的处理线程数量有限,您可以使用 HAProxy 来“拿起电话”并在队列中缓冲请求几秒钟,直到您的应用服务器上有空闲线程来处理请求。

事实上,您可以只使用像 nginx 这样的 Web 服务器来接收请求并说“200 OK”。然后,一个简单的应用程序读取网络日志并插入到数据库中。这将很好地扩展,尽管您可能希望一个线程读取日志并多个线程插入。

2) 如果您的语言有协程,您自己处理缓冲可能会更好。您应该衡量依赖我们的语言运行时进行调度的开销。

例如,如果每个 HTTP 请求都是 1K 的 header + 数据,想要解析它并丢弃除您实际需要的一两个数据(即 DB ID)之外的所有内容。如果您依赖语言协程作为“隐式”队列,则在解析每个协程时,它将为每个协程提供 1K 缓冲区。在某些情况下,拥有有限数量的工作人员并明确管理队列会更有效率/更快。当您有上百万件事情要做时,小开销会迅速累积起来,并且语言运行时不会始终针对您的应用程序进行优化。

此外,与 Node.js 相比,Go 可以更好地控制内存。 (结构比对象小得多。结构键的“开销”对于 Go 来说是编译时的事情,但对于 Node.js 来说是运行时的事情)

3) 你怎么知道它在工作? 你希望能够确切地知道你在做什么。当您依赖语言协同例程时,要问“我有多少个执行线程,最旧的是哪个?”并不容易。如果你做一个明确的队列,这些问题就更容易问了。 (想象一下几个 worker 把东西放进队列,然后几个 worker 把东西拉出来。边缘有一点不确定性,但中间的队列非常明确地捕获了你的积压。你可以很容易地计算出诸如“drain”之类的东西速率”和“最大内存使用量”,这对于了解您的重载程度非常重要。)

我的建议:使用 Go。从长远来看,Go 将是一个好得多的选择。 Go 运行时现在有点不成熟,但每个版本都在变得更好。 Node.js 可能在几个方面(成熟度、社区规模、库等)略微领先

关于mysql - 在 go 或 nodejs 中处理大量请求/秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20801537/

相关文章:

Go:如何找出 rune 的 Unicode 属性?

php - 如何通过 Laravel 统计独立访客并在图表中显示?

php - MySQL:验证费率范围内的日期范围(laravel 可选)

mysql - PDO/MYSQL 查询中的括号 ()

go - 附加两个数组的通用函数

go - 获取 bigInt 数 golang 的总和

html - 无法在Go中将图像添加到html模板

amazon-web-services - Go lang 中的 AWS API Gateway 客户端证书

MySQL - SELECT ...(子查询)AS 字段名

mysql - 仅获取匹配间隔的唯一时间戳行