2010.09.01 16:26

PHP 애플리케이션 워크로드 분배

웹 애플리케이션의 대부분이 표시되기는 하지만 그 가치와 경쟁력은 고유 서비스나 알고리즘에 의해 결정된다. 그러한 작업이 복잡하거나 오래 걸릴 경우에는 웹 서버가 수신 요청에 응답하지 못하는 상황이 발생하지 않도록 하기 위해 비동기적으로 처리하는 것이 효과적이다. 실제로 특히, 계산 작업이 많거나 전문화된 기능은 하나 이상의 전용 서버에서 최적의 성능을 발휘한다.

자주 사용하는 약어

  • API: Application programming interface
  • HTTP: Hypertext Transfer Protocol
  • LAMP: Linux, Apache, MySQL, and PHP

PHP용 Gearman 라이브러리는 여러 시스템에 작업을 분배한다. Gearman은 작업을 큐에 저장하고 할당하는 역할을 수행하며 까다로운 작업의 경우 이러한 유형의 작업을 위해 따로 마련해 둔 시스템에 분배한다. 이 라이브러리는 Perl, Ruby, C, Python 및 PHP용으로 제공되며 Mac OS X, Linux® 및 Sun Solaris를 포함한 모든 UNIX® 계열 플랫폼에서 실행된다.

Gearman은 PHP 애플리케이션에 쉽게 추가할 수 있다. 일반적인 LAMP 구성에서 PHP 애플리케이션을 호스트하는 경우 Gearman을 사용하려면 추가 디먼과 PHP 확장이 필요하다. 2009년 11월을 기준으로 Gearman 디먼의 최신 버전은 0.10이며 두 가지 PHP 확장을 사용할 수 있다. 그 중 하나는 Gearman C 라이브러리를 PHP로 랩핑한 것이고 다른 하나는 순수하게 PHP로만 작성된 확장이다. 이 기사에서는 먼저 설명한 확장을 사용하며 이 확장의 최신 버전은 0.6.0이고 PECL 또는 Github에서 소스 코드를 다운로드할 수 있다.

참고: 이 기사에서 사용되는 공급자는 작업 요청을 생성한 시스템이고, 소비자는 작업을 수행하는 시스템이며, 에이전트는 공급자와 적합한 소비자를 연결하는 매개 시스템이다.

Gearman 설치하기

Gearman을 시스템에 추가하려면 디먼을 빌드하고 시작하는 단계와 사용 중인 PHP 버전에 일치하는 PHP 확장을 빌드하는 단계를 수행해야 한다. 확장을 빌드하는 데 필요한 모든 라이브러리는 디먼 패키지에 있다.

먼저 Gearman 디먼인 gearmand에 대한 최신 소스 코드를 다운로드하고 tar 파일의 압축을 푼 후 코드를 빌드하고 설치한다. (설치 단계를 진행하려면 수퍼 사용자인 root 권한이 필요하다.)

$ wget http://launchpad.net/gearmand/trunk/\
  0.10/+download/gearmand-0.10.tar.gz
$ tar xvzf gearmand-0.10.tar.gz
$ cd gearmand-0.10
$ ./configure
$ make
$ sudo make install

gearmand를 설치한 후에는 PHP 확장을 빌드한다. PECL에서 tar 파일을 가져오거나 Github의 저장소를 복제할 수 있다.

$ wget http://pecl.php.net/get/gearman-0.6.0.tgz
$ cd pecl-gearman
#
# or
#
$ git clone git://github.com/php/pecl-gearman.git
$ cd pecl-gearman

이제 코드가 준비되었으므로 다음 작업을 수행하여 확장을 빌드한다.

$ phpize
$ ./configure
$ make
$ sudo make install

Gearman 디먼은 일반적으로 /usr/sbin에 설치된다. 명령행에서 직접 디먼을 실행하거나 시스템이 다시 부팅될 때마다 디먼이 실행되도록 시작 구성에 디먼을 추가할 수 있다.

그런 다음에는 Gearman 확장을 사용하도록 설정해야 한다. 다음과 같이 php.ini 파일(php --ini 명령으로 빠르게 찾을 수 있음)을 열고 extension = gearman.so라는 행을 추가한다.

$ php --ini
Loaded Configuration File:         /etc/php/php.ini
$ vi /etc/php/php.ini 
...
extension = gearman.so

파일을 저장한다. 확장이 사용 가능하도록 설정되었는지 확인하기 위해 다음과 같이 php --info를 실행하고 Gearman을 검색한다.

$ php --info | grep "gearman support"
gearman
gearman support => enabled
libgearman version => 0.10

PHP 코드로도 적합한 빌드 및 설치를 확인할 수 있다. 이 간단한 애플리케이션을 verify_gearman.php에 저장한다.

<?php
  print gearman_version() . "\n";
?>

그런 다음 명령행에서 프로그램을 실행한다.

$ php verify_gearman.php
0.10

버전 번호가 앞에서 빌드하고 설치한 Gearman 라이브러리의 버전과 일치하면 시스템 준비가 완료된 것이다.

Gearman 실행하기

앞에서 언급한 대로 Gearman 구성에는 세 가지 유형의 행위자가 있다.

  • 하나 이상의 공급자가 작업 요청을 생성한다. 각 작업 요청은 email_all 또는 analyze와 같이 원하는 기능으로 이름을 지정한다.
  • 하나 이상의 소비자가 요청을 수행한다. 각 소비자는 해당 기능에 이름을 지정한 후 기능을 에이전트에 등록한다. 소비자는 작업자라고도 한다.
  • 에이전트는 자신에게 연락해 온 소비자가 제공하는 모든 서비스를 취합해서 분류하고 공급자와 서비스를 제공할 수 있는 소비자를 연결한다.

다음과 같이 명령행에서 빠르게 Gearman을 실행할 수 있다.

  1. 다음과 같이 에이전트인 Gearman 디먼을 실행한다.
    $ sudo /usr/sbin/gearmand --daemon
    

  2. 명령행 유틸리티 gearman을 사용하여 작업자를 실행한다. 작업자는 이름이 있어야 하며 모든 명령행 유틸리티를 실행할 수 있다. 예를 들어, 다음과 같이 디렉토리의 컨텐츠를 나열하는 작업자를 작성할 수 있으며 여기서, -f 인수는 작업자가 제공하는 함수에 이름을 지정한다.
    $ gearman -w -f ls -- ls -lh
    

  3. 마지막으로 살펴볼 행위자는 조회 요청을 생성하는 공급자 또는 작업이다. 요청도 gearman을 사용하여 생성할 수 있다. 이 경우에도 -f 옵션을 사용하여 원하는 서비스의 이름을 지정한다.
    $ gearman -f ls < /dev/null
    drwxr-xr-x@ 43 supergiantrobot  staff   1.4K Nov 15 15:07 gearman-0.6.0
    -rw-r--r--@  1 supergiantrobot  staff    29K Oct  1 04:44 gearman-0.6.0.tgz
    -rw-r--r--@  1 supergiantrobot  staff   5.8K Nov 15 15:32 gearman.html
    drwxr-xr-x@ 32 supergiantrobot  staff   1.1K Nov 15 14:04 gearmand-0.10
    -rw-r--r--@  1 supergiantrobot  staff   5.3K Jan  1  1970 package.xml
    drwxr-xr-x  47 supergiantrobot  staff   1.6K Nov 15 14:45 pecl-gearman
    

PHP에서 Gearman 사용하기

PHP에서 Gearman을 사용하는 방법도 앞의 예제와 비슷하지만 공급자와 소비자를 PHP로 작성한다는 점만 다르다. 각 소비자의 작업은 하나 이상의 PHP 함수로 캡슐화된다.

Listing 1에서는 PHP로 작성된 Gearman 작업자를 보여 준다. 이 코드를 worker.php라는 이름의 파일로 저장한다.


Listing 1. Worker.php
	
<?php
  $worker= new GearmanWorker();
  $worker->addServer();
  $worker->addFunction("title", "title_function");
  while ($worker->work());

  function title_function($job)
  {
    return ucwords(strtolower($job->workload()));
  }
?>

Listing 2에서는 PHP로 작성된 공급자 또는 클라이언트를 보여 준다. 이 코드를 client.php라는 이름의 파일로 저장한다.


Listing 2. Client.php
	
<?php
  $client= new GearmanClient();
  $client->addServer();
  print $client->do("title", "AlL THE World's a sTagE");
  print "\n";
?>

이제 다음과 같이 명령행에서 클라이언트를 작업자에 연결할 수 있다.

$ php worker.php &
$ php client.php
All The World's A Stage
$ jobs
[3]+  Running                 php worker.php &

작업자 애플리케이션은 계속 실행되면서 다른 클라이언트에게도 서비스를 제공할 수 있다.

Gearman의 고급 기능

Gearman은 웹 애플리케이션에서 다양한 용도로 사용할 수 있다. 대용량의 데이터를 가져오고, 다수의 이메일을 보내고, 비디오 파일을 인코딩하고, 데이터를 마이닝하고, 중앙 로그 파일을 작성하는 등의 작업을 사이트의 성능이나 응답성에 영향을 주지 않고 수행할 수 있다. 데이터를 병렬로 처리할 수 있다. 게다가 Gearman 프로토콜은 언어 및 플랫폼에 독립적이기 때문에 솔루션에서 여러 프로그래밍 언어를 함께 사용할 수도 있다. 다시 말해서, 공급자는 PHP로 작성하고 작업자는 C, Ruby 또는 Gearman 라이브러리에 사용할 수 있는 다른 언어로 작성할 수 있다.

클라이언트를 작업자에 연결하는 Gearman 네트워크는 사용자가 원하는 모습으로 얼마든지 구성할 수 있다. 다수의 구성을 이용해서 여러 에이전트를 실행하고 수많은 시스템에 작업자를 분산시킬 수 있다. 이러한 구성에는 로드 밸런싱이 내재되어 있다. 즉, 작동 가능하고 사용할 수 있는 각 작업자(작업자 호스트당 다수의 작업자가 있을 수 있음)가 큐에서 작업을 가져온다. 작업은 동기적 또는 비동기적으로 우선 순위에 따라 실행될 수 있다.

최신 릴리스의 Gearman에서는 시스템의 기능이 확장되어 지속적 작업 큐가 포함되었으며 HTTP를 통해 작업 요청을 제출할 수 있는 새 프로토콜도 지원된다. 이전 릴리스의 경우에는 Gearman 작업 큐가 메모리에 유지되었지만 관계형 데이터베이스의 지원을 받았다. 따라서 Gearman 디먼이 실패할 경우 다시 시작할 때 작업 큐를 다시 작성할 수 있다. 최근에 향상된 또 하나의 기능으로 memcached 클러스터를 통한 큐 지속성이 있다. memcached 저장소도 메모리를 이용하기는 하지만 여러 시스템에 분산되어 있기 때문에 SPOF(Single Point Of Failure)로 인한 문제점을 해결할 수 있다.

Gearman은 아직 초기 단계에 불과하면서도 뛰어난 기능을 갖춘 작업 분배 시스템이다. Gearman의 창시자인 Eric Day에 따르면 Yahoo!에서는 Gearman을 사용하여 60개 이상의 서버에서 하루에 6백만 개 이상의 작업을 처리하고 있다. 뉴스 집계 사이트 Digg는 하루에 40만 개의 작업을 처리하는 비슷한 규모의 Gearman 네트워크를 구축했다. 오픈 소스 검색 엔진인 Narada에서도 Gearman을 효과적으로 사용하고 있는 사례를 찾아볼 수 있다.

후속 릴리스의 Gearman에서는 통계 수집 및 보고, 고급 모니터링, 작업 결과 캐시 등의 다양한 기능을 제공할 것이다. 해당 Google 그룹에 가입하거나 Freenode에서 해당 IRC 채널인 #gearman을 방문하면 Gearman 프로젝트의 진행 상황을 확인할 수 있다.


출처 : http://www.ibm.com/developerworks/


Trackback 2 Comment 0