본문 바로가기

소프트웨어 이야기/인프라

(Phusion Passenger) Rails + Nginx 최적화를 위한 설정값

지난주는 인프라에 이리치이고 저리치였던 주였다. ㅠㅠ 

서버의 메모리 사용량에 이리치이고 저리치이면서 패신저의 프로세스 상태를 확인하고, 설정값들을 변경해줘야하는 상황들이 발생했다. 

패신저란.. 레일즈애플리케이션과 웹서버를 연결해주는 중간다리쯤정도만 생각했었다. 그런데 이번주는 패신저에 대해서 더 잘 알아두면 좋을 것 같단 생각을 한 주였다. 

이래저래.. 큰불들은 꺼졌지만, 까먹기전에 패신저에 대한 내용들을 찾아서 정리해보고자 한다.


아 ㅎ ㅎ !


이 포스팅의 내용은 루비 + 엔진엑스로 패신저 조합의 이야기이다. 



A. 패신저 프로세스 수 조절하기

이번주는 적당한 프로세스 수를 찾기 위해 이렇게 저렇게 설정해보고, 메모리에 치이고, 리퀘스트 큐에 치이는 한주였다.


패신저에서는 프로세스 수를 동적으로 생성할 수 있다. 

요청이 늘어나면, 프로세스 수를 늘어나고, 요청이 줄어들면, 프로세스 수는 같이 줄어든다. 

알아서 스케일업 / 스케일다운을 해준다.


그런데 여기서 트레이드오프가 발생하게 된다. 프로세스 수를 늘리거나, 줄이는 작업은 성능에 영향을 미친다. 



항상 늘어나고, 줄어들게 하면 퍼포먼스에 영향을 미치기 때문에, 항상 떠있게할 최소 프로세스 수를 설정해줘야한다. 

그 값이 passenger_min_instances 설정값이다.

패신저를 설정해놓은 어플리케이션별로, 최소 프로세스 갯수를 이 값이 설정해두면 된다. 



그렇다고, 무조건 요청이 늘어나는 만큼 프로세스 수가 늘어나도 문제가 발생한다. ( 이번주에 겪었ㄷr...☆ )

예를 들어, 패신저 프로세스당 110MB를 잡아먹는데, 처리해야하는 작업이 많아져서 프로세스가 30개가 생성되었다고 생각해보자.
그런데 메모리는 3.75GB로 할당된 인스턴스라고 생각해보자.

그러면 3300MB (3.22GB, 전체 메모리 중 85% )만큼을 패신저가 메모리를 잡아먹게 된다.
서버에서는 패신저 뿐만 아니라 다른 프로그램들도 돌고있을거다.
그러면 이제... 서버의 메모리 사용량이 꽉차게 되면서 빨간불이 들어오게 되는거다. ㅎㅋ 

때문에 적당히 프로세스의 최대 갯수를 정해줘야한다.

보통 한 프로세스당 최대 150MB까지 사용될 수 있다는 가정하에 Max Size를 조정해야한다.
서버의 메모리 용량의 75% 정도를 패신저 메모리로 잡는게 적합하기 때문에

( 전체 서버 메모리 용량 * 0.75 ) / 150MB
라는 공식으로 프로세스 최대 갯수를 조정하는게 좋다. ( 적정한 수를 튜닝하는 방법은 Passenger 최적화 문서에 잘 정리되어 있다 )



B. 메모리릭이 발생했을때 최적화하면 좋은 설정값

위에서 이야기한 것처럼, 프로세스를 동적으로 생성하고 / 삭제하는 동작을 자주하게 되면 퍼포먼스에 영향을 미친다.
그래서 몇개의 프로세스를 몇개 미리 띄어놓는다. 

그런데 여기서 메모리릭이 발생하게 되면, 
실제로 이 프로세스에서 쓰는 메모리는 30MB인데, 이전에 누적된 메모리 100MB 때문에 
한 프로세스의 메모리 사용량이 130MB가 되는 상황이 발생할 수 있다.


이런 경우, 근본적인 문제 해결 방법은 메모리릭의 원인을 찾는거다. 
그런데 외부 Gem에서 메모리릭이 발생하고 있다면, 문제를 찾아서 해결하는게 어렵다.

그래서 우선, 패신저의 옵션을 사용하면, 임시적으로 메모리 이슈를 해결할 수 있다.
아래의 설정 값을 사용하면 된다. 

passenger_max_requests
프로세스가 처리할 수 있는 요청 갯수를 제한하는 설정값이다. 
이 옵션은 프로세스가 지정한 횟수만큼 요청을 처리하게 되면, 처리하고 있던 프로세스가 끝나는대로 프로세스를 죽여서 메모리를 해제시켜준다. 

passenger_memory_limit
프로세스 메모리의 크기를 제한하는 설정값이다.
이 옵션은 각 프로세스의 메모리가 지정한 크기보다 커지면, 처리하고 있던 프로세스가 끝나는대로 프로세스를 죽여서 메모리를 해제시켜준다.
메모리 크기를 제한하는 이 옵션은 엔터프라이즈 버전에서만 사용할 수 있다.


C. 기타 

설정값들을 조정하다보니, 의문점이 생겼다. 
왜 최소 갯수는 passenger_min_instances이고, 최대 갯수는 passenger_max_pool_size인가?
passenger_min_pool_size이 더 자연스럽다는 생각을 했다. 
그래서 찾아봤다.

passenger_min_instances는 이 애플리케이션에서 떠있어야하는 최소 프로세스 수를 의미한다.
그래서 passenger_max_instances라는 옵션도 있다. 이건 이 애플리케이션에서 떠있어야하는 최대 프로세스 수를 의미한다.

한 패신저에서는 여러개의 애플리케이션이 올라갈 수 있다. 블로그 웹 애플리케이션도 올라갈 수 있고, 쇼핑몰 웹 애플리케이션도 올라갈 수 있다. 만약에 이렇게 2개의 웹 애플리케이션이 떠져있다면, 각 애플리케이션별로 최소 / 최대 프로세스 수를 설정할 수 있다.

그리고 passenger_min_pool_size는 블로그 웹앱 / 쇼핑몰 웹앱 상관없이 한 패신저에서 처리될 수 있는 최소 프로세스 수를 의미한다고 보면 된다.