我正在构建类似于Google Analytics的东西,目前我正在进行实时数据库更新。这是我的应用程序的工作流程:
1和2在SQL中非常快 - 它们是SELECT。 #3真的很慢,因为它是一个更新。在现实世界中,我的数据库(MySQL)没有扩展。根据New Relic的说法,#3占据了大部分时间 - 高达70%!
我的想法是我需要停止进行同步数据库操作。在短期内,我正在尝试减少数据库写入,所以我正在考虑一个全局哈希(比如在environment.rb中声明),可以从我的控制器和模型中访问,我可以写入,而不是写入D B。我经常可以让任务编写需要写入数据库的更新。
问题:
PS:这是违规查询 - 所有感兴趣的列都被编入索引:
更新statistics_api
设置count_request
= COALESCE(count_request
,?)+? WHERE(id
=?)
答案 0 :(得分:1)
你的哈希解决方案听起来有点过于复杂。这组幻灯片是一个富有洞察力的最新资源,可以解决您的问题:
他们说最简单的事情是:
Thread.new do
MyModel.do_long_thing
end
但Ruby mysql驱动程序是阻塞的,因此该线程中的mysql请求仍然可以阻止您的请求。您可以使用mysqlplus作为驱动程序并获取非阻塞请求,但现在我们正在获得一个非常复杂和专业的解决方案。
如果你真的只是想要这个你的请求周期,但可以为它保留服务器的锁定,你可以这样做:
MyController
after_filter :do_jobs
def index
@job = Proc.new{ MyModel.do_long_thing }
end
private
def do_jobs
return unleses @job
@job.call
end
end
我将它更多地抽象到ApplicationController中,但你明白了。 proc将更新推迟到请求之后。
如果您认真对待异步和后台进程,则需要查看各种选项,并根据需要做出决定。 Matt Grande推荐使用DelayedJob-这是一个非常受欢迎的选择,但如果您的整个服务器陷入数据库写入困境,我不会建议它。如果这只是一个特别慢的更新,但你的服务器没有过载,那么这可能是一个很好的解决方案。
我目前在最复杂的项目中使用与Starling配合。工作已经相当可扩展,但Starling有点不太理想。 Workling的优势之一是能够交换后端,因此如果Starling成为一个大问题,我们可以将其移除。
如果您的服务器陷入写入困境,则无论您的异步任务方法如何,都需要查看它的扩展。
祝你好运!听起来你的应用程序正在以令人兴奋的速度增长: - )答案 1 :(得分:0)
稍后使用DelayedJob执行此操作。
编辑:如果您的数据库受到如此大的打击,以至于一个UPDATE显着减慢了您的请求,那么您可能应该考虑设置主从数据库架构。
答案 2 :(得分:0)
我刚刚在EventMachine邮件列表上提出了类似的问题,我建议我尝试使用phat(http://www.mikeperham.com/2010/04/03/introducing-phat-an-asynchronous-rails-app/)来获取异步数据库。
也许你应该尝试一下。