Ruby-on-rails 4 性能下降

问题描述:

升级到 Rails 后,我发现了严重的性能问题.

I've seen significant performance problems after upgrading to Rails.

我最近将我的项目从 Rails 2 和 Ruby 1.8 升级到 Rails 4 和 Ruby 2.0.在互联网上阅读,我明白升级应该提供开箱即用的出色性能改进(高达 30%).不幸的是,我发现在某些情况下性能要差很多,例如一些以前需要大约 20 秒的报告,现在需要 40 秒.

I've recently upgraded my project from Rails 2 and Ruby 1.8 to Rails 4 and Ruby 2.0. Reading around on the internet, I understand that upgrading should provide excellent performance improvement (up to 30%) out of the box. Unfortunately, I've found that the performance is a lot worse in some cases e.g. some reports that were previously taking around 20 seconds, now take 40 seconds.

我看到一些帖子表明垃圾收集可能是问题所在.在使用了一些推荐的设置后,我发现一些较长的报告实际上更短,但较短的报告仍然差很多.

I've seen some posts that suggest Garbage Collection may be the issue. After using some recommended settings, I've found that some of the longer reports are actually shorter, but the short reports are still much worse.

作为升级的一部分,我已经转而使用不显眼的 javascript 进行视图渲染,但这似乎不会导致性能问题 - 大部分时间都花在模型上.

As part of the upgrade, I've moved over to unobtrusive javascript for the view rendering, but this doesn't seem to contribute to performance issues - most of the time is being spent in the model.

有人知道我是否遗漏了一些配置陷阱"?是否有其他人因升级而出现性能问题?

Does anybody know if I'm missing some configuration 'gotchas'? Did anybody else have performance problems as a result of the upgrade?

提前致谢.

在升级过程中可能总会出现边缘情况,其中某些类型的操作运行速度较慢,而另一些则较快.最好只遵循常规的性能调优技术并使用 Oink gem 和 NewRelic 等工具来分析最慢的问题.

There are probably always going to be edge cases in upgrades, where certain types of operation run slower and other faster. It would probably be best to just follow regular performance tuning techniques and use tools such as the Oink gem and NewRelic to look analyse the slowest issues.

严格来说,通常最好在升级前收集尽可能多的性能分析数据,这样您就可以判断特定操作是否正在遭受更高的内存消耗、更多/更慢的垃圾收集、不同生成的 SQL(来自activerecord upgrade),正在创建更多对象.例如,使用升级后分析可能很难将数据置于上下文中,因此您可以判断 30 个 Post 对象的创建对于给定的操作是否正常.

To be rigorous it's usually best to gather as much performance profiling data prior to the upgrade as possible so you can then tell whether a particular operation is suffering from higher memory consumption, more/slower garbage collection, different generated SQL (from an activerecord upgrade), more objects being created. With post-upgrade profiling it can be difficult to put the data in context so you can tell if the creation of 30 Post objects is normal for a given action, for example.

关于急切加载,我们发现子弹是获得正确级别的非常有用的宝石.当然,这不一定是 Rails 3/4 问题,这是对的.

With respect to eager loading, we found bullet to be a very useful gem for getting the right level. You're right that it's not necessarily a Rails 3/4 issue, of course.

我们的另一个痛点是不仅要减少查询次数,还要小心我们是否真的需要创建一个对象.有时您可以只检索数据进行显示而不创建对象.此外,我们现在非常小心(例如)隐式运行:

Another pain point for us has also been to not only reduce the number of queries but to be careful about whether we really need to create an object. You can sometimes get away with just retrieving the data for display without creating the object. Furthermore, we are now very careful about (for example) implicitly running:

select * from books where client_id = 1 order by name

... 为了创建书名下拉列表,我们可以:

... in order to create a dropdown of book names, when we could:

select id, name from books where client_id = 1 order by name

它在 Rails 端的效率要高得多,即使有时在数据库端的差异很小(数据库端为 100 毫秒与 20 毫秒,但在 Rails 端为 2000 毫秒与 500 毫秒).

It is hugely more efficient on the Rails side, even if the difference in sometimes marginal on the database side (100ms vs 20ms on the database, but 2000ms vs 500ms on the Rails side).

再说一次,可能与 Rails 3/4 无关,除非 Rails 4 中存在一个使其效率更低的怪癖.

Again, possibly not Rails 3/4 relevant unless there is a quirk in Rails 4 that makes it even less efficient, perhaps.