이 글은 2006년 8월에 작성된 글로, 현재 상황과 매우 다릅니다. 결과 데이터와 이를 분석한 차트도 유실된 상황입니다. Rails Deployment의 다른 글을 참고하시기 바랍니다.

 

레일스 애플리케이션을 배포하는 방법은 다양하다. 그리고 시간이 지남에 따라 선호하는 방식도 계속 바뀌고 있다. 레일스가 처음 나왔을 때는 개발용 Webrick과 서비스용 아파치(FastCGI)로 단순하게 분류되었지만, 어느새 Lighttpd(속칭 Lighty)가 득세하기도 하고, Mongrel이라는 기린아가 등장하기도 하였다. 그렇다면 현 시점에서 레일스 애플리케이션을 서비스한다면 어떤 환경이 가장 적절할까?

 

적합한 배포 환경의 판단 조건은 여러 가지가 있겠지만 그 중 안정성, 성능, 확장성(Scalability)을 우선 생각해볼 수 있겠다. 이 글에서는 이 중 쉽게 측정할 수 있는 값인 성능을 중심으로 주로 사용되는 환경을 테스트해보기로 한다. 테스트를 진행한 환경은 아래와 같다.

 

  • Webrick
  • Mongrel
  • Apache + CGI
  • Apache + FCGI
  • Apache + ProxyBalancer + Mongrel
  • Lighttpd + FCGI
  • Lighttpd + Pound + Mongrel

 

테스트 환경

이 결과에 절대 의존해서는 안 된다. 매우 특수한 한가지의 경우만을 고려하고 있기 때문이다.

  • CPU : Dual Xeon 3.00GHz
  • RAM : 2G
  • OS : Red Hat Enterprise Linux ES release 3 (Taroon Update 7)
  • Kernel : 2.4.21-40.ELsmp
  • Testing S/W : Siege 2.64

 

DBMS

가장 보편적이라고 생각하는 Mysql의 최신 버전(5.0.24)을 사용한다.

  1. create table messages( id int primary key, body varchar(255) );
  2. insert into messages values( 1, 'Hello, Mysql!' );

 

DB의 성능 테스트가 아니므로 아주 간단한 SELECT 질의만을 사용할 것이다.

  1. select * from messages where id = 1;

 

Hello, Mysql! 레일스 애플리케이션

테스트에 사용한 애플리케이션은 Mysql의 messages 테이블의 id가 1인 message를 읽어서 화면에 출력하는 간단한 프로그램이다. 캐시는 사용하지 않는다. 실 세계의 프로그램이라고 할 수는 없지만 여기서는 일반적인 Hello, World! 보다는 약간 나은 수준에서 만족하기로 하자. 모든 테스트는 production 환경에서 이루어진다.

 

  1. # app/model/message.rb
  2. class Message < ActiveRecord::Base
  3. end
  4.  
  5. # app/controllers/messages_controller.rb
  6. class MessagesController < ApplicationController  
  7.   layout 'plain_html'  
  8.   def hello    
  9.     @message = Message.find(1)  
  10.   end
  11. end

 

  1. <!--app/views/messages/hello.rhtml-->
  2. <%=@message.body%>
  3.  
  4. # app/views/layouts/plain_html.rhtml
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  6. <html xmlns="http://www.w3.org/1999/xhtml">
  7. <head>
  8.   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  9.   <title>TEST<title>
  10. </head>
  11. <body leftmargin="0" topmargin="0" marginwidth="0" marginheight="0" bgcolor="#f0f0f0">
  12. <%= @content_for_layout %>
  13. </body>
  14. </html>

 

벤치마크

각 환경에 대해 동시 사용자 수를 50, 100, 150으로 하여 30초간 테스트했다. 너무 간단한 애플리케이션이어서인지 값이 눈에 보이게 차이가 나는 것은 아니지만, 몇 가지 주목할 만한 사실을 발견하기도 한다.

Webrick

루비 표준 라이브러리의 일부인 Webrick은 루비로 구현된 웹 서버이다. 레일스에서 script/server를 실행하면 Webrick이 실행된다. 레일스 애플리케이션을 구동할 수 있는 가장 간단한 방법으로 성능이 중요하지 않은 개발 환경으로는 최고라고 할 수 있다.

하지만, Webrick으로 성능을 논할 수는 없다. 일단 결과를 보자. 참담하다.

 

모든 요청을 처리하지 못했다. 서비스 환경으로 사용할 수 없다는 의미이다. 물론, 이 경우의 응답 시간도 믿을 것이 못 된다.

하지만 Webrick은 여전히 매력적이고 유용한 개발 환경이다. 순수한 루비 웹 서버라는 상징성도 여전하다.

Mongrel

Webrick의 단점을 보완하기 위해 일부 기능을 C 언어로 구현해 성능을 향상했다. 그래서 이름도 잡종(mongrel)이다. Webrick처럼 편하면서 속도까지 보장해준다니, 최근 Mongrel이 여기 저기서 사랑 받는 것은 어찌 보면 당연한 것일지도 모르겠다.

테스트 결과 소규모의 애플리케이션의 경우는 Mongrel 만으로 운영해도 무리가 없을 정도의 성능을 보여주었다. 그리고 Webrick과 달리 요청을 100% 처리했다.

 

다시 말하지만, 동시 사용자 50의 경우에는 뛰어난 성능을 보여주고 있다. 하지만 정적인 리소스도 함께 서빙해야하고, 대용량 서비스의 경우에는 확장성의 문제도 있으므로 아파치나 Lighttpd와 함께 쓰이는 것이 일반적이다.

Apache 2.2.3 + CGI

가장 많이 쓰이는 아파치 웹 서버와 CGI. 성능에 문제가 많을 것이라는 사실을 충분히 예상할 수 있지만, 그래도 실험을 해보았다.

결과는 생각보다 훨씬 심각했다. 테스트 도중 커널 패닉 상태가 되어버려 리부팅을 하는 사태까지 벌어졌고, 아래 결과만 봐도 요청을 전혀 처리를 못했다는 사실을 알 수 있다. 한마디로 레일스 애플리케이션 배포에서 CGI라는 단어는 지워버려야 한다. 결코 고려 대상이 될 수 없다.

 

이 결과에는 루비 인터프리터의 성능도 한몫 했을 것이다.

Apache 2.2.3 + FCGI

CGI의 성능을 보완하기 위한 방법이 FastCGI이다. 아파치 2.x에서는 mod_fcgid를 사용해야 한다.

이 조합은 아마도 가장 널리 쓰이고 있을 것이다. mod_fcgid를 설치하고 .htaccess 파일에서 dispatch.cgi 대신 dispatch.fcgi를 사용하도록 하면 된다. 처음 접하는 사람에게는 설정이 다소 복잡하기는 하지만, 그에 따른 보상은 확실하다. 성능과 확장성을 동시에 충족시켜주기 때문이다.

 

실험 결과에서 모든 요청을 소화하고, 매우 빠른 성능을 보여주고 있음을 볼 수 있다.

하지만, Apache + FastCGI와 레일스의 궁합이 맞지 않는다는 푸념은 어렵지 않게 찾아볼 수 있다. 아파치 fastcgi 모듈이 활발하게 개발되고 있지 않고, 몇 가지 버그도 있는 것으로 추정된다. 그 결과 500 에러가 자주 발생한다. 이는 Dreamhost(이 블로그를 호스팅하는 업체)에서 자주 볼 수 있는데, 아니나 다를까 이 조합을 사용 중이다.

위 수치만으로는 훌륭하지만 추천할만한 조합은 아니다. 결과에 이런 이슈가 담기지 못한 점이 아쉽다. 아무튼 Apache + FastCGI가 가진 문제점에 지친 루비스트들은 다른 조합을 찾아 헤매고 다녔다. 그 결과는 아래에 계속된다.

Lighttpd + FCGI

위에서 설명한 문제로 인해 많은 사람들이 비교적 FastCGI 지원이 훌륭한 Lighttpd로 옮겨갔다. 이름만 봐도 알 수 있듯 Lighttpd는 (아파치보다) 가벼운 웹 서버이다. 애칭으로 Lighty라고도 불리고 있다. 이 개발자가 RailsConf에서 발표를 했을 정도로 레일스와는 친한 모습을 보여주고 있다. 여러 벤치마크에서 Lighttpd는 아파치보다 나은 성능을 증명하고 있기도 하다.

무엇보다 Lighttpd에 열광하는 이유는 기본으로 제공되는 안정적인 fastcgi 모듈이다. 이 모듈이 아파치의 mod_fastcgi보다 빠르고 안정적이라는 사실은 모두가 인정하고 있다.

 

작은 차이기는 하지만, 위의 Apache+ FCGI보다 나은 성능을 보여주고 있음을 알 수 있다. 안정적면서 성능까지 빠르고 FastCGI의 확장성은 여전히 가지고 있다. 이만하면 레일스 애플리케이션을 구동하기에 충분하다.

개인적으로 아파치의 설정파일보다 Lighttpd의 그것을 좋아한다. 더 논리적이라고 할까? 다양한 상황을 표현하기가 훨씬 간단했다. Lighttpd의 단점은 아파치에 비해 널리 알려져 있지 않았다는 점이다. 팀원을 설득해야 하는 수고가 따른다.

Apache 2.2.3 + ProxyBalancer + Mongrel

최근 Lighttpd로 옮겨갔던 사람들이 다시 아파치로 돌아오고 있다는 소식이 들린다. 바로 Apache 2.2 버전에서 지원하는 modproxybalancer 때문이다. 왕의 귀환이다.

이 조합이 필요한 이유는 안정성 때문이다. 레일스를 FastCGI 환경에서 돌리는데 가장 큰 걸림돌은 바로 에러 처리이다. 여러 요청을 동시에 많이 받아 부하가 걸린 레일스 애플리케이션이 먹통이 되어버리기도 한다. 로드 밸런서가 필요한 이유이다.

일반적으로 정적인 요청(이미지, JS, CSS, 캐시 등)은 아파치에서 직접 처리하고, 동적인 요청은 Mongrel에게 위임한다. 이 때 modproxybalancer가 로드 밸런싱을 해준다. Mongrel의 뛰어난 성능과 아파치의 적절한 로드 밸런싱으로 안정적인 서비스가 가능하다. 물론 다양한 조합이 주는 유연함과 확장성은 더 말할 것도 없다. 일단 결과를 보자.

 

FastCGI 보다 성능면에서 낫다고는 할 수 없다. 하지만 그렇게 떨어지지도 않는다. FastCGI 환경이 문제가 생긴다면 로드 밸런서와 상의할 때이다.

Lighttpd + Pound + Mongrel

그래도 아파치보다는 Lighty가 좋다. 하지만 Lighty의 mod_proxy는 아파치의 그것만큼 영리하지 못하다. 물론 다음 버전에서는 개선될 것이라고 한다. 그 동안 손가락만 빨면서 기다릴까? 물론 아니다.

Pound를 사용하면 Lighty에서도 modproxybalancer와 같은 효과를 볼 수 있다. 난 죽어도 Lighty를 써야겠다 하는 사람에게는 가뭄의 단비라 하겠다.

 

성능은 아파치와 비슷하거나 약간 빠르다.

결론

지금까지 여러 가지 테스트의 결과를 보았다. 그 결과 실 서비스에 사용할만한 조합은 아래와 같다.

  • Apache + ProxyBalancer + Mongrel
  • Lighttpd + FCGI
  • Lighttpd + Pound + Mongrel

개인적인 의견은 가장 좋은 성능을 보인 Lighttpd + FCGI를 일단 사용해보고 혹시나 안정성의 문제가 발견된다거나, 더 유연한 조합이 필요하다면 Apache + ProxyBalancer + Mongrel 조합을 테스트해보는 것이 어떨까 싶다. 난 500 에러는 정말이지 다시 보고 싶지 않아~라고 생각하는 사람이라면 바로 Apache + ProxyBalancer + Mongrel을 사용하는 것도 좋겠다. 아파치보다 Lighty를 선택했다면 Lighttpd + Pound + Mongrel 도 시도해 볼만한 조합이다.

마지막으로 성능 테스트 결과를 하나의 표에 정리한 것이다.

 

다음에는 레일스와 다른 프레임워크간의 성능 차이는 어느 정도인지 테스트해볼 것이다. 비교할 프레임워크로는 Zend, Django, Webwork, Grails를 고려하고 있다.

(이어지는 글: 웹 프레임워크 성능 비교)

 

업데이트

이 벤치마크를 진행한 후, 시간이 많이 흘러서 더 나은 선택들도 나오고 있다. 몇가지 테스트를 해보았는데 그 결과도 함께 비교해보기 바란다. 이벤트 기반 몽그렐의 성능은 기대 이상이므로 이벤트 기반 몽그렐을 사용하기를 추천한다. 그리고 Apache2 vs. Nginx라는 테스트를 진행한 결과 Nginx도 고려할만한 대안임을 확인할 수 있었다.

 

Leave a Reply

Website

Email