如果您正在为这种大规模涌入构建应用程序,您将需要将其基本组件剥离到绝对最低限度。
为这种强度使用完整的 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 层。