본문 바로가기

기술자료/기술운영자료

apache 2.4 (event-mpm), nginx 1.4 비교 테스트

apache 2.4 event-mpm

             nginx-1.4 비교 테스트

 

 

Event-driven programming

프로그래밍 방법론 중에 하나로써, 프로그램의 흐름이 이벤트에 의해 결정이 되는 방식

다른 프로그램 혹은 쓰레드의 메시지나 사용자 행동, 센서의 출력과 같은 이벤트 들이 있음.

어플리케이션이 이벤트를 선택 또는 이벤트를 감지하고, 이벤트를 처리하는

분명한 두 섹션을 가지는 어플리케이션 아키텍쳐 기술로 정의가 되기도 한다.

event-driven 방식은 일반적으로 윈도우즈 프로그래밍에 널리 사용되는 방식으로 알려져 있지만

네트워크 통신 등 다양한 분야에서 사용되고 있으며 이 방식을 사용하게 되면

framework에서 좀 더 빨리 return 할 수 있게 되어 더 많은 처리를 할 수 있도록

어플리케이션 단에서 대응을 할 수 있다.

 

 

Event-driven

해당 방식은 기존의 아파치 웹서버에서 사용되던 방식 -하나의 쓰레드에서 하나의 클라이언트를 처리하는 방식- 보다 적은 쓰레드 수로 많은 클라이언트를 처리할 수 있다.

기존 아파치 웹서버 처럼 하나의 쓰레드에서 하나의 클라이언트를 처리하게 되면

'accept' 와 persistence layer에서 정보를 읽거나 쓴 후 가공하여 클라이언트에 전달될 때까지

I/O 문제로 쓰레드가 대기해야 할 때가 잦은 데다 클라이언트 갯수 만큼 쓰레드가 생성되야해서

메모리의 점유도 그만큼 크다.

하지만 비동기식 이벤트 기반 방식에서는 각 상태(state)를 정하고, 여기서 event가 발생할 때 마다 이event를 처리하도록 하여 더 적은 쓰레드로(혹은 쓰레드 없이) CPU를 효율적으로 사용할 수 있게 된다.

최근 nginx, Lighttpd, Tornado, Magnum, Aleph 등 최근 개발된 웹 서버들과

서버 사이드 자바스크립트인 Node.js가 event-driven 방식을 채택하고 있다.

 

 

nginx (http://nginx.org)

러시아인 igor sysoev가 2004년 처음 릴리즈한 웹서버.

nginx는 C10K problem을 해결하기 위하여 기존 아파치 방식 처럼 하나의 쓰레드에서 하나의 클라이언트 요청을 처리하는 것이 아닌 event-driven 구조를 사용한다.

최근 점유율이 빠르게 상승하고 있는 웹 서버.

 

 

 

 

 

apache event-mpm

keep-alive에 대한 고민에서 출발한 새로운 mpm 방식

요청과 keep-alive한 아파치의 요청을 그대로 맺어주는 것이 아니라, 요청을 처리하는

쓰레드를 따로 두어 분산된 처리를 하는데 그 목적을 하고 있음

 

 

http://httpd.apache.org/docs/2.2/mod/event.html

This MPM tries to fix the 'keep alive problem' in HTTP. After a client completes the first request, the client can keep the connection open, and send further requests using the same socket. This can save signifigant overhead in creating TCP connections. However, Apache traditionally keeps an entire child process/thread waiting for data from the client, which brings its own disadvantages. To solve this problem, this MPM uses a dedicated thread to handle both the Listening sockets, and all sockets that are in a Keep Alive state.

The MPM assumes that the underlying apr_pollset implementation is reasonably threadsafe. This enables the MPM to avoid excessive high level locking, or having to wake up the listener thread in order to send it a keep-alive socket. This is currently only compatible with KQueue and EPoll.

 

 

http://httpd.apache.org/docs/current/mod/event.html

The event Multi-Processing Module (MPM) is designed to allow more requests to be served simultaneously by passing off some processing work to supporting threads, freeing up the main threads to work on new requests. It is based on the worker MPM, which implements a hybrid multi-process multi-threaded server. Run-time configuration directives are identical to those provided by worker.


 

 

 

 

KeepAlive

HTTP프로토콜상 한번 접속 후 자료를 모두 전송하면 접속을 끊어 버리지만

KeepAlive On 상태에서는 KeepAliveTimeOut시간 동안 접속을 끊지 않고 다음 접속을 기다린다.

 순수 html파일, 이미지파일 등으로만 구성된 서버(동적파일이 없는서버)에 KeepAlive On으로

설정할 경우 50%정도의 성능 향상을 보인다고 한다. 단 이와 같은 성능향상을 보이려면

서버가 바쁘지 않아야 한다. 아주 바쁜 서버 환경에서 KeepAlive On을 설정해 놓을 경우

모든 접속자 마다 연결 유지를 해 놓아야 하기 때문에 아파치 프로세스수가 기하 급수적으로 
늘어나 MaxClient값을 초과하게 된다. 또한 On상태일때 접속유지 하는 프로세스들 때문에

메모리를 그 만큼 많이 사용하게 된다. 따라서 KeepAlive값은 단순히 On/Off 시킬것이 아니라

접속자, 메모리용량과 연관해서 값을 설정하여야한다.

 

접속자가 많지만 메모리가 충분하다 : On

접속자가 많지만 메모리 여유가 없다 : Off

접속자가 적고 메모리가 충분하다 : On

접속자가 적고 메모리 여유가 없다 : Off

 

- 메모리가 충분하다는 의미는 접속자가 MaxClient값에 도달했을 경우라도 swap메모리를

  사용하지 않는상태를 뜻한다.

 

 

 

 

 

apache 2.4.4 설치

#wget http://mirror.apache-kr.org/httpd/httpd-2.4.4.tar.gz

#wget http://mirror.apache-kr.org//apr/apr-1.4.6.tar.bz2

#wget http://mirror.apache-kr.org//apr/apr-util-1.4.1.tar.bz2

 

#tar zxvf httpd-2.2.4.tar.gz

#tar jxvf apr-1.4.6.tar.bz2

#tar jxvf apr-util-1.4.1.tar.bz2

 

*apache 2.4.x는 pcre 설치 필요

#wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.33.tar.gz

 

*apache 2.4.x 버전에서는 apr과 apr-util을 별도로 포함하여 컴파일 해야함

 

#mv apr-1.4.6 /tmp/httpd-2.4.4/srclib/apr

#mv apr-util-1.4.1 /tmp/httpd-2.4.4/srclib/apr-util

 

#./buildconf

 

*2.4.x에서의 default mpm은 event-mpm으로 설정 되므로 mpm설정 생략

 

# ./configure --prefix=/usr/local/apache --enable-modules=all --with-included-apr --enable-suexec --enable-rewrite

 

#make &&make install

 

 

 

php-5.4.16 설치

 

./configure --prefix=/usr/local/php --with-apxs2=/usr/local/apache/bin/apxs --with-mysql=/usr/local/mysql --with-config-file-path=/usr/local/apache/conf --with-libdir --with-freetype-dir --with-gd --with-jpeg-dir --with-png-dir --with-zlib --enable-mbstring --enable-exif

 

* --with-mysql은 삭제 한 상태로 컨피그 진행

* mpm이 다른 방식인 관계로 mysql 컨피그시 --enable-thread-safe-client 옵션 필요.

 현재 해당 부분 이슈가 있어서 확인 진행 중

 php 컴파일시 옵션 추가 --disable-maintainer-zts --disable-safe-mode

 

 

 

 

nginx-1.4.1

 

php 설치

./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php --with-libdir --with-zlib --enable-mbstring --enable-exif --enable-fpm

 

#make &&make install

 

 

 

 

 

php-fpm 설정

*php-5.3.x부터 php-fpm이 내장되어 간단한 설정 후 사용이 가능함

 

#cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf

#vi /usr/local/php/etc/php-fpm.conf

 

하기 내용의 주석을 제거 후 적절히 설정

 

pid = run/php-fpm.pid

error_log = log/php-fpm.log

pm.max_children = 35

pm.start_servers = 20

pm.min_spare_servers = 5

pm.max_spare_servers = 30

listen = 127.0.0.1:9000

 

 

#chmod 755 /etc/init.d/php-fpm &&chkconfig --add php-fpm &&chkconfig php-fpm on

 

#service php-fpm start

 

 

 

 

nginx 설치

#wget http://nginx.org/download/nginx-1.4.1.tar.gz

#tar zxvf nginx-1.4.1.tar.gz

#./configure --prefix=/usr/local/nginx --add-module=../nginx_mod_h264_streaming-2.2.7 --with-http_flv_module --with-http_secure_link_module

#make &&make install

 

# wget -O /etc/init.d/nginx "http://wiki.nginx.org/index.php?title=RedHatNginxInitScript&action=raw&anchor=nginx"

 

#vi /etc/init.d/nginx

아래와 같이 경로 수정

그림입니다.
원본 그림의 이름: mem00002274014c.tmp
원본 그림의 크기: 가로 550pixel, 세로 404pixel
 

 

 

# chmod 755 /etc/init.d/nginx &&chkconfig --add nginx &&chkconfig nginx on

#service nginx start

 

웹브라우저에서 아래 페이지 정상출력 되는지 확인

그림입니다.
원본 그림의 이름: mem00002274014d.tmp
원본 그림의 크기: 가로 550pixel, 세로 199pixel
 

 

 

php와 연동 설정

#vi /usr/local/nginx/conf/nginx.conf

아래 내용을 수정, 작성

그림입니다.
원본 그림의 이름: mem00002274014e.tmp
원본 그림의 크기: 가로 550pixel, 세로 112pixel
 

 

#service nginx restart

 

phpinfo가 뜨는지 확인

 

 

 


 

 


 

벤치마킹 결과

 

1. apache-2.2.x(prefork) vs apache-2.4.4(event-mpm) vs nginx-1.4.1

 

default 설정

index.html

request : 100,000

client : 100

그림입니다.
원본 그림의 이름: mem00002274014f.tmp
원본 그림의 크기: 가로 550pixel, 세로 299pixel
 

 


 

2. apache-2.4.4(event-mpm) vs nginx-1.4.1

 

default 설정

index.html

request : 100,000

client : 100

 

그림입니다.
원본 그림의 이름: mem000022740150.tmp
원본 그림의 크기: 가로 550pixel, 세로 290pixel
 

 

 


 

3. apache-2.4.4(event-mpm) vs nginx-1.4.1

 

default 설정

phpinfo()

request : 50

client : 50

 

그림입니다.
원본 그림의 이름: mem000022740151.tmp
원본 그림의 크기: 가로 550pixel, 세로 335pixel
 


 

4. apache-2.4.4(event-mpm) vs nginx-1.4.1

 

mpm 및 keepalive 설정 변경

아마존 AWS에서 진행한 테스트를 참고하여 설정 값을 변경 하였습니다.

http://blog.celingest.com/en/2013/02/25/nginx-vs-apache-in-aws/

 

httpd-mpm.conf

그림입니다.
원본 그림의 이름: mem000022740152.tmp
원본 그림의 크기: 가로 457pixel, 세로 124pixel
 

 

 

nginx.conf

그림입니다.
원본 그림의 이름: mem000022740153.tmp
원본 그림의 크기: 가로 550pixel, 세로 438pixel
 

 

 

 

phpinfo()

request : 100

client : 50

그림입니다.
원본 그림의 이름: mem000022740154.tmp
원본 그림의 크기: 가로 550pixel, 세로 325pixel
 

 

 

테스트는 단순 페이지 출력으로 진행한 점,

정확히 동일한 웹서버 튜닝에 한계가 있는 점 등을 고려했을때

 

nginx의 강점은 빠른 속도, 상황에 따라 크게 편차가 크지 않다는 점 등이 있겠음.

 

다만 nginx의 php 연동 방식이 fastcgi에 의존하고 있는 부분 때문에

(php-fpm의 성능이 아직 만족스럽지 않은 문제로)

단순한 구조의 가벼운 웹사이트 운용에 보다 적합하다고 보여짐.

 

테스트 상에서는 nginx가 나은 성능을 보이지만 php 모듈을 직접 적재하여 운용할 수 있는 apache가 구조상 잇점이 있기에 복잡한 구성의 웹사이트 운영에서는 보다 적합할 수 있음.

 

apache의 경우, AWS에서 테스트한 대상이 event-mpm이 아닌 worker방식이기 때문에

(event-mpm이 worker방식을 기반으로 개발된 것이므로 아주 타당성이 없다고 할 수는 없음.)

 

정확한 테스트 비교환경 구성에 무리가 있을 수도 있다는 점,

 

실제로 해외 테스트 결과 event-mpm과 nginx 테스트 결과 가 큰 편차를 보이지 않고 있다는 점

등을 미루어보아 전적으로 nginx가 좋다라고 단정할 수는 없기에 이 부분은 지속적으로 확인해볼 필요가 있겠습니다.