部署 升级 Ruby 2.1 以及 GC 调整

quakewang · 2014年02月28日 · 最后由 douxiance 回复于 2015年08月20日 · 8830 次阅读
本帖已被管理员设置为精华贴

Ruby 从 1.8 => 1.9 => 2.0 => 2.1 一直在 GC 上不断地改进,最近 2.1.1 刚刚发布,抽空将我们的应用从 2.0 升级了一下,记录一下相关改动。

我们在服务器使用的是 rvm,首先更新一下 rvm:

rvm get head

淘宝提供了 ruby 相关的镜像,可以更新一下源,后续安装会快很多:

sed -i 's!cache.ruby-lang.org/pub/ruby!ruby.taobao.org/mirrors/ruby!' $rvm_path/config/db

安装 2.1.1:

rvm install 2.1.1

建议使用 railsexpress 的性能优化补丁(其中包括已经合并到 ruby 2.2 method cache 的改进):

rvm install 2.1.1 --patch railsexpress

设置 2.1.1 为默认版本:

rvm use 2.1.1 --default

OobGC 优化: 我们之前使用的 unicorn 自带的 OobGC,它会固定在每 N 次请求后,执行一次 GC。tmm1 写了另一个 OobGC: https://github.com/tmm1/gctools ,它利用 ruby 2.1 新的 gc 事件,使用 c 扩展来进行更智能的 OobGC,配置很简单,在 config.ru 里面加上:

require 'gctools/oobgc'
use GC::OOB::UnicornMiddleware

不过他不支持请求阶段的 GC.disable,实际用我们的应用测下来和 unicorn 自带的 OobGC+GC.disable 相比,在普通压力测试下,平均响应时间稍慢 2~3%,服务器的 cpu 消耗会少 2% 左右。

除了 OobGC 外,这个 gem 还提供了 GC 的日志输出,只要加上:

require 'gctools/logger'

可以在 stderr 看到具体的 GC 执行情况,用来判断 GC 参数调整是否合理十分有用。

GC 参数调整: 和 Ruby 2.0 相比,2.1 多了一些分代 GC 的参数,这篇文章 http://tmm1.net/ruby21-rgengc/ 非常详细地介绍了各个参数的意义,还提供了 github 用的参数配置。配合 gctools/logger,我们最终调整的 GC 参数如下:

export RUBY_GC_HEAP_INIT_SLOTS=500000
export RUBY_GC_HEAP_FREE_SLOTS=700000
export RUBY_GC_HEAP_GROWTH_FACTOR=1.25
export RUBY_GC_HEAP_GROWTH_MAX_SLOTS=300000
export RUBY_GC_MALLOC_LIMIT=80000000
export RUBY_GC_OLDMALLOC_LIMIT=80000000 
2 楼 已删除

干货!! 👍

Cool, tmm1 还写了一个 profile 输出分析工具,叫做 stackprof, 可以帮助找出性能瓶颈。

详解一下 gctools/logger 呗

👍,如果谁再能跑一下 benchmark ,给出性能比较结果就更好,更有说服力了。

tmm1 这人还不是 ruby core 的成员么。。

#7 楼 @vincent 没有太多空闲服务器资源,我用 ab 跑了一下普通压力的,和 2.0 相比没有什么差别。

#6 楼 @huacnlee tmm1 的文章里面已经介绍很详细了,主要就是看 major 和 minor GC 发生的频率,旧代和新代 GC 的统计,用来调整 GC 参数看效果用。

看過 1.9 / 2.0 / 2.1 NewRelic Pref Graphs, GC 其實已經很大進步,餘下來的就是 Ruby Execution Speed,仍然有很大進步空間。

请问为何升级后,盖上电脑睡眠,再激活,就发现回到 1.9.3 了?

需要 登录 后方可回复, 如果你还没有账号请 注册新账号