在go或nodejs中处理大量的req / sec

时间:2013-12-27 13:24:58

标签: mysql go

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

在每台前端服务器上处理尽可能多的req / sec的最佳策略是什么,只是发送回复并将请求存储在内存中,以后稍后由DB编写工作者在后台处理?

目标是在突发期间尽可能少地做,并在突发后尽快将请求写入DB。

编辑:交易顺序不重要, 我们可以丢失一些交易,但99%需要记录 在收到最后一个请求之后几秒钟,获取所有请求到DB的延迟。可以说不超过15秒

2 个答案:

答案 0 :(得分:2)

缓冲区大小等于数据库写入程序在15秒内可以处理的通道怎么样?当请求进入时,它将在通道上发送。如果通道已满,请提供某种“系统重载”错误响应。

然后,DB编写器从通道读取并写入数据库。

答案 1 :(得分:2)

这个问题有点模糊。但是我会抓住它。

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

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

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

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

例如,如果每个HTTP请求都是1K的标头+数据,那么想要解析它并抛弃除了您实际需要的一两个数据(即数据库ID)之外的所有数据。如果您依赖语言协程作为“隐式”队列,则在解析它们时,每个协程将具有1K缓冲区。在某些情况下,拥有有限数量的工作人员并明确管理队列会更有效/更快。如果您有一百万件事要做,那么小额开销就会快速增加,并且语言运行时并不总是针对您的应用进行优化。

另外,Go会比Node.js更好地控制你的内存。 (结构比对象小得多。结构的键的'开销'对于Go来说是编译时的事情,但对于Node.js来说是运行时的事情)

3)你怎么知道它有效?你希望能够确切地知道你在做什么。当你依赖语言协同程序时,要问“我有多少执行线程以及最老的线程是什么?”并不容易。如果您创建一个显式队列,那么这些问题就容易多了。 (想象一下,一小撮工人把东西放进队列,还有一些工人把东西拉出来。边缘有一点不确定性,但中间的队列非常清楚地记录了你的积压。你可以很容易地计算出像“流失”这样的东西。速率“和”最大内存使用量“这对于了解你的重载程度非常重要。”

我的建议:跟Go一起去。从长远来看,Go将是很多更好的选择。 Go运行时现在有点不成熟,但每个版本都在变得越来越好。 Node.js可能在一些领域(成熟度,社区规模,图书馆等)略微领先