在rails中处理数百个并发请求

时间:2011-06-30 21:35:00

标签: php ruby-on-rails ruby apache phusion

我在rails应用程序上写了一篇ruby,网站最重要的特色之一就是实时投票。我们完全希望在短短1分钟内收到10k的投票请求。与其他请求一起意味着我们可能会收到大量请求。

我最初的想法是将服务器设置为使用apache + phusion,但是,对于投票而言,我正在考虑在侧面编写php脚本并在memcached中写入/读取信息。数据只需要持续大约15分钟,因此在1分钟内写入数据库10,000次似乎毫无意义。我们还需要标记用户的ip,这样他们就不会投票两次,因此在memcached中更加复杂。

如果有人有任何建议或想法让这项工作尽可能最好,请帮忙。

1 个答案:

答案 0 :(得分:7)

如果您正在为这种大规模的涌入构建一个应用程序,那么您将需要将其基本组件删除到最低限度。

对于那种强度使用完整的Rails堆栈并不实际,也不必要。通过直接调用DB,甚至跳过ORM来构建一个非常薄的Rack层来处理投票会好得多,它基本上是INSERT语句的包装器。这就是Sinatra和Sequel,它可以作为一个有效的查询生成器,可能会有所帮助。

您还应该确保正确调整数据库,并对其运行许多负载测试,以确保它按预期执行,并提供更高负载的良好余量。

一分钟内进行10,000次DB调用并不是什么大问题,每次调用在适当调整的堆栈上只需要几分之一毫秒。 Memcached可以提供更高的性能,特别是如果结果不是永久性的。 Memcached有一个原子增量运算符,这正是你在简单列表投票时所寻找的。 Redis也是一家非常有能力的临时商店。

另一个想法是完全废弃数据库并编写一个持久的服务器进程,它说一个简单的基于JSON的协议。如果你致力于Ruby,Eventmachine非常适合将这些东西放在一起,如果你愿意用JavaScript构建一个专门的计数服务器,那么NodeJS也是如此。

即使在使用专用服务器进程的适度硬件上,也可以轻松实现一分钟10,000次操作,而无需完整数据库堆栈的开销。

您必须确保您的范围定义得非常好,以便在部署之前测试并严重滥用您的实现。

因为你所描述的是,在核心,等同于哈希查找的东西,基本代码就是:

contest = @contest[contest_id]

unless (contest[:voted][ip])
  contest[:voted][ip] = true
  contest[:votes][entry_id] += 1
end

在一秒钟内运行这几十次是完全可行的,所以唯一的开销就是在它周围包裹一个JSON层。