【问题标题】:Handling hundreds of simultaneous requests in rails在 Rails 中处理数百个同时请求
【发布时间】:2011-09-26 08:23:25
【问题描述】:

我正在编写一个 ruby​​ on rails 应用程序,该网站最重要的功能之一是现场投票。我们完全期望我们将在短短 1 分钟内收到 1 万个投票请求。连同其他请求,这意味着我们可能会收到大量请求。

我最初的想法是设置服务器以使用 apache + phusion,但是,为了投票,我正在考虑编写一个 php 脚本并在 memcached 中写入/读取信息。数据只需要持久化15分钟左右,所以1分钟内向数据库写入10000次似乎毫无意义。我们还需要标记用户的 ip,这样他们就不会投票两次,因此在 memcached 中更加复杂。

如果有人有任何建议或想法以使这项工作尽可能好,请提供帮助。

【问题讨论】:

  • 查看 NoSQL 数据库,每分钟 10k 写入大约是每秒 165 次写入。不多。
  • 没想到,你推荐的最靠谱的是什么?
  • 用于 NoSQL 的 MongoDB。如果您使用的是 MySQL,请使用 MyISAM 表。
  • 如果你决定使用基于 Rack 的框架(Rails、Sinatra),请不要使用 Apache + Passenger,首先因为 Apache 是一个巨大的内存和 CPU 猪,其次是因为它是一个巨大的内存和 CPU hog :p,checkout Nginx,它可以很容易地用Passenger编译,或者代理到像Unicorn这样的东西。它的内存占用也非常小,不到 2MB。

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


【解决方案1】:

如果您正在为这种大规模涌入构建应用程序,您将需要将其基本组件精简到绝对最低限度。

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

您还应该确保正确调整数据库,并针对它运行许多负载测试,以确保它按预期运行,并为更高的负载留出健康的余量。

在一分钟内进行 10,000 次数据库调用并不是什么大问题,在经过适当调整的堆栈上,每次调用只需要几分之一毫秒。 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 层。

【讨论】:

  • 感谢您的好评。我可能会测试 eventmachine 并且 Sinatra + memcached 似乎真的很有效,而且不需要太多额外的工作编码。问题是,这是针对单个功能的,但是,它的要求如此之高,需要它自己的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 2019-08-17
  • 2021-12-21
相关资源
最近更新 更多