이 질문에 대한 답은 스크린샷 한 장으로 대신하겠습니다.
{% img img-responsive /images/posts/ruby-2-1-improvement.png 645 259 이건 확실한 '예스'라고 불러야겠죠 %}
약 일주일 전 프로덕션 환경에서 Ruby 1.9를 2.1로 업그레이드했고, 그 결과가 바로 위 그래프입니다. 하단의 회색 영역은 가비지 컬렉션(GC) 시간이 거의 0에 수렴한 모습을 보여줍니다. 전체적으로 업그레이드만으로 서버 응답 시간이 15~20% 개선되었습니다. 별도의 GC 튜닝 없이도 말이죠!
업그레이드를 배포한 후 Google과 Bing의 크롤링 빈도도 눈에 띄게 증가했습니다. 검색 엔진 트래픽에 크게 의존하는 사이트에게는 특히 반가운 변화입니다.
좋네요, 그럼 업그레이드는 얼마나 어려웠나요?
약 150개에 달하는 gem 의존성을 가진 대형 Rails 애플리케이션에서조차, 업그레이드는 단 하나의 작은 커밋과 며칠간의 테스트면 충분했습니다. 모든 서버에서 rvm을 사용하고 chef로 프로비저닝하고 있기 때문에, 서버들을 2.1로 올리는 작업은 chef role 파일의 버전 숫자 하나만 바꾸는 수준의 간단한 일이었습니다.
어떤 문제가 발생했나요?
저희는 여전히 음역(transliteration) 용도로 iconv를 사용하고 있어서, 2.x에서 제거된 내장 기능을 대체해 주는 iconv gem을 추가해야 했습니다. 또한 ruby-debug와 debugger gem은 2.x 환경에서 동작하게 만들지 못해 pry와 pry-byebug로 전환했습니다. 여전히 debugger gem이 pry-byebug보다 낫다고 생각하지만, pry는 irb보다 월등히 좋아서 결국 상쇄된 셈입니다. byebug의 저자 Deivid Rodriguez가 제가 겪은 pry-byebug 문제는 byebug 자체의 문제가 아닐 것이라고 지적했는데, 정곡을 찌른 지적이었습니다! 실제 원인은 byebug와 pry의 상호작용 때문이었습니다.
1.9와 2.1이 혼재된 환경에서는 bundler도 1.5.1로 업그레이드해야 합니다. 새 버전의 bundler에서는 Gemfile에 플랫폼 요구사항으로 2.1을 지정할 수 있습니다:
gem 'iconv', '~> 1.0.2', :platform => [:mri_20, :mri_21]
GitHub 역시 2.1에서 몇 가지 다른 문제를 겪은 것으로 보입니다. Aman Gupta가 이 gist(https://gist.github.com/tmm1/8393897)에서 관련 내용을 언급했지만, 저희 환경에서는 아직 어떠한 문제도 발견하지 못했습니다.
배포 후 GC를 추가로 튜닝하면 더욱 큰 속도 향상을 얻을 수 있습니다. Aman이 그 방법을 자세히 설명한 좋은 글(https://tmm1.net/ruby21-rgengc/)을 남겼으니 참고하세요. 저렴하고 간단한 Ruby 업그레이드에서 최대한의 성능을 끌어내고 싶다면, 그의 블로그에 있는 2.1 시리즈 전체를 읽어볼 가치가 충분합니다.