5

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

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

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

4

1 回答 1

7

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

为这种强度使用完整的 Rails 堆栈并不实际,也没有必要。最好构建一个非常薄的 Rack 层,通过直接调用 DB 来处理投票,甚至跳过 ORM,基本上是一个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 层。

于 2011-06-30T21:54:56.880 回答