'cache'에 해당되는 글 4건

  1. 2009.10.29 PhpExpress - PHP loader and accelerator
  2. 2009.07.03 Memcache 데몬을 사용하여 메모리에 데이터 저장(cache)하기
  3. 2009.06.11 PEAR 활용 imagick 설치 및 PHP 캐싱 (1)
2009. 10. 29. 18:33

PhpExpress - PHP loader and accelerator

Overview of NuSphere PhpExpress

PhpExpress is NuSphere Free PHP loader and accelerator that provides support for encoded files and also speeds up the execution of regular PHP files.

Please note that if you are using PHP files encoded with NuSphere NuCoder PhpExpress is required to be installed on the server.

This is how PhpExpress works:
  • When PHP interpreter executes any PHP script it first compiles the script into bytecodes. However NuCoder produces PHP files that have been already compiled into bytecodes.
  • PhpExpress loads encoded PHP scripts directly into PHP engine saving time and boosting performance of PHP interpreter
  • PhpExpress also implements caching for PHP engine and accelerates execution process even if PHP Script is not encoded

Obtaining PhpExpress

PhpExpress can be downloaded from NuSphere website and distributed Free Of Charge without limitations. Every NuCoder installation also comes with PhpExpress.

How to download PhpExpress from NuSphere Website

You can download the archive containing PhpExpress from Free Downloads area of your NuSphere Account. To do that:
  • Create NuSphere Account and login
  • Click on Free Downloads
  • Follow the link to NuSphere PhpExpress for the Operating System of your server to start the download process
  • Save NuSphere-PhpExpress-2.0.zip file for Windows or NuSphere-PhpExpress-2.0.tag.gz for Linux/Unix to the disk
  • For windows - using WinZip or similar program unzip NuSphere-PhpExpress-2.0.zip in the directory of your choice
  • For Linux/Unix - use the following command to unfold NuSphere-PhpExpress-2.0.tag.gz tar -xvfz Nusphere-PhpExpress-2.0.tag.gz
  • The uncompressed archive will create a directory "NuSphere-PhpExpress" with phpexpress-php-x.x.dll files for Windows or phpexpress-php-x.x.so for Linux/Unix (where x.x is the version of PHP compatible with the module)
How to obtain PhpExpress from NuCoder installation

PhpExress extensions for all operating systems can be found in the folder "loader" of your NuCoder installation

How to install NuSphere PhpExpress

NuSphere PhpExpress is a regular PHP extension, which makes it easy to install and deploy. To install PhpExpress:
  • Open php.ini file for editing
  • Add line extension=phpexpress-php-x.x.dll if you are deploying on Windows, extension=phpexpress-php-x.x.so if you are deploying on Unix, Linux or Mac OS operating systems (where x.x is the version of PHP compatible with the module)
  • Copy phpexpress-php-x.x.dll or phpexpress-php-x.x.so in the PHP extensions directory specified in php.ini file
  • Stop and Start Apache if you are running PHP as Apache module
  • Execute call to phpinfo() function and make sure that PhpExpress is properly installed
Once PhpExpress is installed on the server, you can execute PHP Scripts encoded with NuCoder as well as regular, not encoded PHP scripts. In both cases you will gain an improved performance in the execution of the scripts.

How to monitor PHP Cache implemented by NuSphere PhpExpress

PhpExpress accelerates execution of PHP scripts by caching them and avoiding unnecessary compilation. You can view and control PHP Cache created by PhpExpress with a single function call to the PHP function phpexpress() provided by PhpExpress PHP extension. phpexpress() produces the output similar to phpinfo() with the user Interface to administer PhpExpress cache. The output of phpexpress() is illustrated below:


Please note that PHP caching is only enabled when PHP is running as an extension of the Web Server - dll on windows or shared object on Linux/Unix/Mac Operating Systems. Caching of PHP scripts when PHP is running in CGI mode is not useful and therefore disabled.

원문 : http://www.nusphere.com/

Trackback 1 Comment 0
2009. 7. 3. 20:10

Memcache 데몬을 사용하여 메모리에 데이터 저장(cache)하기

XCache와 XDebug, Memcache 데몬을 연구하고 있습니다. Memcache 데몬(memcached)은 고성능 분산 객체 캐시입니다. 애플리케이션과 데이터 스토어 중간에 설치되는 memcached는 RAM에 객체들을 저장합니다. 각각의 캐시 히트는 데이터베이스 서버의 라운드트립(roundtrip)을 대체하면서 애플리케이션의 속도를 높여줍니다.

XCache를 사용하면 같은 PHP 코드를 페이지에 나타내기 위해 재 컴파일 해야 하는 불필요하고 값비싼 노력을 들이지 않아도 된다. XCache는 프리 오픈 소스 소프트웨어이며 설치도 오래 걸리지 않는다. XDebug는 소프트웨어 엑스레이와 비슷하다. 애플리케이션을 들여다 보고, 내부 작동을 노출하며 코드가 사이클을 어떻게 소비하는지를 가려낸다. XDebug를 사용하면 알고리즘을 조정하여 코드를 최적화 하고, 병목 현상을 줄이며, 과도한 메모리 사용을 줄일 수 있다.

주: XCache는 실행 환경에 쓰일 수 있다. XDebug는 실행 머신에서 오버헤드가 많기 때문에 개발 환경에 적합하다.

이번 시간에는 효과적인 성능 강화 장치를 소개하도록 하겠다. memcached라고 하는 Memcache 데몬은 고성능 분산 객체 캐시이다. 애플리케이션과 데이터 스토어 중간에 설치되는 memcached는 RAM에 객체들을 저장한다.

Memcached PHP 확장은 간단한 애플리케이션 프로그램 인터페이스(API)로 캐시에 액세스 한다. 이 캐시를 사용하려면 API를 호출하여 객체가 이전에 저장되었는지 여부를 파악한다. 저장되었다면, 객체를 가져와서 프로세스를 계속 진행한다. 그렇지 않을 경우, 데이터베이스로 가서 필수 데이터를 가져와서, 이를 객체에 매핑하고, 캐시에 추가한다. 바로 이 부분에서 memcached는 이전에 처리했던 정보에 대한 데이터베이스 쿼리를 최소화 하거나 줄여준다.

XCache와 XDebug가 터보차저(turbocharger)라면 memcached는 제트 엔진이다. 애프터버너에 불을 붙일 준비를 하라.

빠른 속도에 대한 필요성

일반적으로, PHP 애플리케이션에서 가장 시간을 많이 소비하는 작업은 데이터 검색이다. 실제로, 저장소에서 정보를 가져오는데 걸리는 시간은 그것이 파일이든, 데이터베이스 서버이든, 컴파일이나 심지어 PHP 프로그램을 실행하는데 필요한 시간을 훨씬 초과한다. 데이터베이스 서버로 연결하는데 필요한 시간은 한 가지 지연 요소이고, 쿼리가 완료되기를 기다리는 데에도 시간이 추가되고, 결과 전송에는 더 많은 레이턴시가 발생한다. 더욱이, 코드가 객체를 사용하고 있다면, 행들을 객체들로 매핑하는 데에도 시간이 걸린다.

MySQL은 쿼리 캐시를 사용하여 쿼리 단계의 속도를 높인다. 또한 데이터베이스(한 개의 마스터와 많은 카피들)를 복제하여 많은 CPU들 간 쿼리 프로세싱의 부담을 나눌 수 있다. 하지만 MySQL 쿼리 캐시의 콘텐트는 기본 테이블이 변하자마자 퇴색된다. 더욱이, 쿼리 캐시는 쿼리가 이전 쿼리와 동일할 경우에만 히트된다. 복제 역시 한계가 있다. 예를 들어, 데이터베이스 쓰기는 분산될 수 없다.

쿼리 캐시와 데이터베이스 복제는 의미가 있고 전체적인 워크로드 관리 전략에도 쓸모가 있지만(쿼리 캐시는 일부 메모리를 사용하지만 비교적 저렴하다. 복제는 치명적인 다운타임의 위험 부담을 줄인다.), 연결과 전송 시간이라는 것이 남아있다.

Memcache PHP 확장은 RAM에 객체들을 저장한다. 각 캐시 히트는 데이터베이스 서버로의 라운드트립을 대체하면서 애플리케이션을 더욱 빠르게 실행한다. memcached 역시 (간접적으로) 데이터베이스 서버의 성능을 높인다. memcached는 지속 저장소로써 작동하기 때문에 더 적은 요청들이 데이터베이스 서버로 가게 되면서, 쿼리에 대한 응답성은 더 높아진다.

한 개 이상의 서버에서 memcached를 실행할 수 있고, 캐시의 콘텐트는 모든 노드들 간 중복된다. 서버가 중지하면, 클라이언트 API 소프트웨어는 다른 서버로 캐시 읽기 및 쓰기를 다시 라우팅 한다.

XCache와는 달리, 코드를 수정하여 memcached를 통합해야 한다. 하지만, 객체 메소드 내에 데이터베이스 액세스 코드를 고립시키면, 수정 작업은 간단하고 중앙화 된다.

Danga Interactive에 의해 작성된 Memcache 데몬은 프리 오픈 소스 소프트웨어로서 Berkeley Software Distribution (BSD) License 하에 배포된다. 이 데몬은 유닉스®와 리눅스® 시스템에서 쉽게 구현되며, Mac OS X와 Microsoft® Windows®에서도 구현될 수 있다. 많은 리눅스 배포판들은 memcached 패키지를 제공한다. 여러분의 패키지 저장소를 검사해 보라. Mac OS X나 Windows를 사용하고 있거나 사전 구현된 바이너리를 선호한다면 Google 검색을 통해 웹에서 소프트웨어를 찾을 수 있다






PHP (재)구현

Debian 리눅스에서 memcached를 구현, 설치, 전개해 보자. 프로세스의 속도를 높이고 기존 웹 서버 인프라스트럭처와는 별개로 memcached를 테스트 하려면 XAMPP Apache를 베이스로 사용하라. XAMPP는 설치하기 쉬우며, Apache V2, MySQL, PHP V4 and V5, Perl, 많은 라이브러리, 많은 웹 애플리케이션(phpMyAdmin)을 포함하고 있다. 처음부터 Linux, Apache, MySQL, PHP (LAMP) 스택을 구현하지 않았거나, 이 같은 일로 어려움을 겪고 싶지 않다면 XAMPP로 시작하는 것이 이상적이다.

주: 소스에서 PHP를 구현해 보았거나 파일을 갖고 있다면, --enables-memcache 옵션을 설정 스위치의 리스트에 추가하고 memcached와 PHP Memcache 확장을 구현하는 전 단계를 건너뛰어도 된다.

Memcached를 구현 및 전개하려면, XAMPP 개발 파일, XAMPP에 포함된 PHP 버전용 소스 코드, memcached 소스 코드, Memcache용 PHP 확장이 필요하다. XAMPP 바이너리와 XAMPP 전개 파일(추가 컴포넌트 구현에 필요함)을 XAMPP에서 다운로드 하라. 또한 wget을 사용하여 소프트웨어를 쉽게 얻을 수 있다.

$ wget 'http://www.apachefriends.org/download.php?xampp-linux-1.6.tar.gz'      
$ wget 'http://www.apachefriends.org/download.php?xampp-linux-devel-1.6.tar.gz'

앞에 있는 tarball(tarball은 압축된 .tar 파일이고 확장자는 .tar.gz이다.)에는 바이너리가 포함되어 있다. 뒤에 있는 tarball에는 XAMPP 시스템에 코드를 구현하는데 필요한 헤더 파일이 포함되어 있다.

파일 시스템 어디에나 XAMPP를 둘 수 있지만, /opt에 저장하도록 한다. 또한 개발 파일도 /opt에 둔다. /opt를 사용하면 나머지 빌드 프로세스가 훨씬 쉬워진다. -C 옵션을 사용하여 파일을 직접 /opt에 추출한다.


Listing 1. /opt로 파일을 직접 추출하기
                
$ sudo mkdir /opt
$ tar xzf xampp-linux-1.6.tar.gz -C /opt
$ tar xzf  xampp-linux-devel-1.6.tar.gz -C /opt
$ ls -CF /opt/lampp
RELEASENOTES	error/		info/		logs/		phpsqliteadmin/
backup/		etc/		lampp*		man/		sbin/
bin/		htdocs/		lib/		manual/		share/
build/		icons/		libexec/	modules/	tmp/
cgi-bin/	include/	licenses/	phpmyadmin/	var/

그런 다음, XAMPP(PHP V4.4.6에 번들된 XAMPP V1.6)에 포함된 PHP 버전용 소스를 다운로드 및 추출한다. PHP.net에서 PHP V4.4.6용 코드를 다운로드 하라. wget을 사용하면 간단하다.

$ wget http://us2.php.net/get/php-4.4.6.tar.bz2/from/www.php.net/mirror
$ tar xjf php-4.4.6.tar.bz2
$ cd php-4.4.6

XAMPP의 PHP 빌드 스크립트를 수정하여 Memcache를 실행하도록 PHP를 재구현 한다. /opt/lampp/share/lampp/configures.tar.gz에 원래 빌드 스크립트(기타 빌드 스크립트)가 있다. PHP V4 빌드 스크립트를 추출한다.

$ tar xzfv /opt/lampp/share/lampp/configures.tar.gz \
  php/configure-php4-oswald

configure-php4-oswald를 열고 --enable-memcache를 추가하라. (시스템이 Oracle과 PostgreSQL 데이터베이스를 갖고 있지 않다면 이와 관련한 옵션들을 제거해야 한다.) Listing 2는 PHP를 재구현 하기 위해 테스트 시스템 상에서 수정된 스크립트 모습이다. (PHP 빌드 프로세스는 Flex, Bison, libxml, PCRE 같은 유틸리티와 개발 라이브러리에 의존한다. 추가 패키지를 설치하여 리눅스 배포판과 PHP 설정의 콘텐트에 기반하여 빌드를 준비하도록 하라.)


Listing 2. PHP를 재구현 하기 위해 수정된 XAMPP 스크립트
                
(
    cd /opt/lampp/bin
    rm phpize phpextdist php-config php
    rm -rf /opt/lampp/include/php
)

make distclean

export PATH="/opt/lampp/bin:$PATH" 
export CFLAGS="-O6 -I/opt/lampp/include/libpng \
    -I/opt/lampp/include/ncurses \
    -I/opt/lampp/include -L/opt/lampp/lib" 

./configure \
    --prefix=/opt/lampp \
    --with-apxs2=/opt/lampp/bin/apxs \
    --with-config-file-path=/opt/lampp/etc \
    --with-mysql=/opt/lampp \
    --enable-inline-optimation \
    --disable-debug \
    --enable-memcache \
    --enable-bcmath \
    --enable-calendar \
    --enable-ctype \
    --enable-dbase \
    --enable-discard-path \
    --enable-exif \
    --enable-filepro \
    --enable-force-cgi-redirect \
    --enable-ftp \
    --enable-gd-imgstrttf \
    --enable-gd-native-ttf \
    --with-ttf \
    --enable-magic-quotes \
    --enable-memory-limit \
    --enable-shmop \
    --enable-sigchild \
    --enable-sysvsem \
    --enable-sysvshm \
    --enable-track-vars \
    --enable-trans-sid \
    --enable-wddx \
    --enable-yp \
    --with-ftp \
    --with-gdbm=/opt/lampp \
    --with-jpeg-dir=/opt/lampp \
    --with-png-dir=/opt/lampp \
    --with-tiff-dir=/opt/lampp \
    --with-freetype-dir=/opt/lampp \
    --without-xpm \
    --with-zlib=yes \
    --with-zlib-dir=/opt/lampp \
    --with-openssl=/opt/lampp \
    --with-expat-dir=/opt/lampp \
    --enable-xslt \
    --with-xslt-sablot=/opt/lampp \
    --with-dom=/opt/lampp \
    --with-ldap=/opt/lampp \
    --with-ncurses=/opt/lampp \
    --with-gd \
    --with-imap-dir=/opt/lampp \
    --with-imap-ssl \
    --with-imap=/opt/lampp \
    --with-gettext=/opt/lampp \
    --with-mssql=/opt/lampp \
    --with-mysql-sock=/opt/lampp/var/mysql/mysql.sock \
    --with-mcrypt=/opt/lampp \
    --with-mhash=/opt/lampp \
    --enable-sockets \
    --enable-mbstring=all \
    --with-curl=/opt/lampp \
    --enable-mbregex \
    --enable-zend-multibyte \
    --enable-exif \
    --enable-pcntl \
    --with-mime-magic \
    --with-iconv 

make 

sudo make install 

exit 1

이 스크립트의 끝으로 가면 XAMPP는 새롭고 독립적인 memcache 실행 PHP V4를 갖게 된다. 빌드를 테스트하고 싶다면, XAMPP 밖에 있는 것을 포함하여 Apache와 MySQL의 모든 실행 카피들을 중지하고 다음 명령을 실행한다.

$ sudo /opt/lampp/lampp start

새로운 PHP V4 모듈을 포함하여 XAMPP 버전의 Apache와 MySQL이 시작될 것이다. (실행 Apache 서버가 분산되지 않은 채로 실행되도록 하려면, /opt/lampp/etc/httpd.conf 파일을 편집하고 Listen 포트 매개변수를 8080(또는 다른 포트)로 변경한다. 그런 다음, 다음 명령어를 사용하여 XAMPP의 Apache 서버를 개별적으로 실행할 수 있다.

sudo /opt/lampp/bin/apachectl start

브라우저에 http://localhost를 입력하면 그림 1과 같은 모습을 볼 수 있다.


그림 1. 리눅스 페이지용 XAMPP: XAMPP와 PHP 설치가 성공했음을 나타내고 있다.
 

PHP 빌드가 설치되었는지 확인하려면, 왼쪽에 있는 phpinfo() 링크를 클릭하라. 그림 2와 같은 통계를 볼 수 있다. 이 PHP 버전은 4.4.6이고, 빌드 옵션에는 --enable-memcache가 포함되며, php.ini의 실행 버전은 /opt/lampp/lib에 위치하고 있다.


그림 2. PHP의 커스텀 빌드가 XAMPP 빌드로 대체되었음을 나타내고 있다. 
 





PHP Memcache 확장 구현하기

새로운 PHP가 생기면, 다음 단계는 PHP Memcache 확장을 구현 및 설치하는 차례이다. 이 확장은 Memcache 데몬 서비스에 액세스 하는데 필요한 API를 제공한다.

Memcache 확장의 소스 코드를 검색하는 것으로 시작한다. wget과 다음 명령어를 사용하여 소스를 얻을 수 있다.

$ wget http://pecl.php.net/get/memcache-2.1.0.tgz

Memcache 확장을 구현하는 과정은 PHP 확장을 구현하는 과정과 동일하다.

  1. 소스 디렉토리를 변경한다.
  2. phpize, ./configure, make, make install 순으로 실행한다.
  3. 새로운 버전의 phpize를 사용하고 있는지를 확인하라.
  4. 또 다른 버전의 phpize를 포함하고 있는 디렉토리 앞에 쉘의 PATH에 /opt/lampp/bin를 둔다.
    $ cd memcache-2.1.0
    $ export PATH=/opt/lampp/bin:$PATH
    $ phpize
    $ ./configure
    $ make
    ...
    $ sudo make install
    Installing shared extensions:    
    /opt/lampp/lib/php/extensions/no-debug-non-zts-20020429/
    

확장 디렉토리에 memcache.so라고 하는 새로운 파일이 생긴다. 이 확장을 로딩 및 적용하려면, php.ini를 편집해야 한다. XAMPP PHP 설정 파일, /opt/lampp/etc/php.ini를 열고 Listing 3의 라인들을 추가한다.


Listing 3. php.ini 편집하기
                
extension=memcache.so
memcache.allow_failover = 1 
memcache.max_failover_attempts=20 
memcache.chunk_size =8192 
memcache.default_port = 11211 

첫 번째 라인은 Memcache 확장을 로딩한다. 다른 네 개의 라인들은 확장을 제어하는 매개변수들이다. 위부터 아래까지 순서대로 보면 다음과 같다.

memcache.allow_failover
연결 에러가 발생할 경우 Memcache 확장이 다른 서버로 넘어갔는지 여부를 제어하는 Boolean이다. 기본값은 1이다. (true).
memcache.max_failover_attempts
데이터를 저장 또는 검색하기 위해 연결할 서버들의 수를 제한하는 정수. memcache.allow_failover가 실패하면, 이 매개변수는 무시된다. 기본은 20이다.
memcache.chunk_size
데이터 전송 크기가 어느 정도인지를 제어하는 정수이다. 기본은 8192 bytes (8 KB)이지만, 32768 (32 KB)로 설정하여 더 나은 성능을 볼 수 있다.
memcache.default_port
Memcache로 연결할 때 사용하는 TCP 포트용 정수이다. 이를 수정하지 않는다면, 기본은 권한이 없는 11211이다.

빌드가 완전한 기능을 하는지 여부를 파악하려면, 다음 명령을 사용하여 XAMPP Apache 웹 서버를 재시작 한다.

$ sudo /opt/lampp/bin/apachectl restart

XAMPP phpinfo() 페이지를 다시 방문하면 그림 3과 같은 Memcache 섹션을 볼 수 있다.


그림 3. phpinfo()를 통한 Memcache 설정 보기 
 





Memcache 데몬 구현하기

(다소 길어 보이는)한 가지 프로세스가 더 남아있다. 데이터용 RAM 캐시를 관리하는 Memcache 데몬을 구현 및 전개하는 것이다. 이 데몬은 libevent에 의존하고 있기 때문에 memcached를 컴파일 하기 전에 라이브러리를 구현 및 전개해야 한다.

$ wget http://www.monkey.org/~provos/libevent-1.3b.tar.gz
$ wget http://www.danga.com/memcached/dist/memcached-1.2.1.tar.gz

tarball을 추출하여 각 번들용 디렉토리를 만들어 낸다.

$ tar xzf memcached-1.2.1.tar.gz 
$ tar xzf libevent-1.3b.tar.gz

라이브러리로 시작하여, 각 패키지를 구현한다. /opt에 모든 파일들을 저장시키려면 설정할 때 --prefix 옵션을 사용하라. 아래 명령어는 libevent를 구현 및 설치하는 명령어이다.


Listing 4. php.ini 편집하기
                
$ cd ../libevent-1.3b
$ ./configure --prefix=/opt/lampp
...
$ make
$ sudo make install
...
/usr/bin/install -c .libs/libevent.lai /opt/lampp/lib/libevent.la
/usr/bin/install -c .libs/libevent.a /opt/lampp/lib/libevent.a
chmod 644 /opt/lampp/lib/libevent.a
ranlib /opt/lampp/lib/libevent.a
PATH="$PATH:/sbin" ldconfig -n /opt/lampp/lib
----------------------------------------------------------------------
Libraries have been installed in:
   /opt/lampp/lib

다음 명령어로는 memcached 바이너리를 구현 및 설치한다.


Listing 5. php.ini 편집하기
                
$ cd ../memcached-1.2.1
$ ./configure --prefix=/opt/lampp
...
$ make
$ sudo make install
...
/usr/bin/install -c memcached /opt/lampp/bin/memcached
/usr/bin/install -c memcached-debug /opt/lampp/bin/memcached-debug

memcached 시작은 간단하다.

./memcached -d -m 2048 -l ip-address -p 11211

-d 옵션은 전면이 아닌 데몬으로서 memcached를 실행한다. -m number number 메가바이트를 프로세스 인스턴스로 할당한다. (일부 시스템의 경우, 캐싱에 사용할 모든 메모리에 액세스 하기 위해 여러 memcached 인스턴스를 실행해야 한다. 자세한 내용은 Memcache 문서를 참조하라.) -l ip-address -p 11211은 데몬이 IP 주소 ip-address 와 port 11211을 리스닝 하게끔 한다. 여러분의 IP 주소로 대체하라. memcached에 다른 포트를 선택하면 php.ini가 이 포트를 반영하도록 해야 한다.






데이터 저장하기

이제 설치가 끝났으니, Memcache를 실행 할 차례이다.

Memcache는 객체를 저장하는데 사용되지만 스트링처럼 직렬화 될 수 있는 어떤 PHP 변수라도 저장할 수 있다. Memcache는 절차적이며 객체 지향적인 API이다. 여러분이 어떤 것을 사용하더라도 캐시에 변수를 저장할 때 다음 네 개의 인자가 필요하다.

유일 키
캐시에서 데이터를 검색하는데 사용된다. 각각의 레코드가 고유 아이디를 갖고 있다면 그것 자체로 캐시 키로서 충분하지만 다른 스킴을 조합하여 필요에 맞출 수 있다.
저장할 변수
직렬화 되어 저장되고 비 직렬화 되어 검색될 수 있다면 어떤 유형이라도 가능하다.
즐비를 통한 압축을 실행하는 Boolean
압축은 메모리를 캐시에 저장한다. 데이터의 저장과 복원이라는 비용이 든다.
초로 지정된 종료 시간
저장된 데이터가 종료되면 자동으로 제거된다. 이 값을 0으로 설정하면 캐시에서 아이템이 절대 종료되지 않는다. Memcache API delete() 함수를 사용하여 이 같은 영구 객체를 제거한다.

아래 코드는 객체 지향의 Memcache 확장 API를 사용하여 간단한 객체를 생성, 저장, 검색한다.


Listing 6. PHP 객체의 생성, 캐시, 저장
                
<?php

class myCache extends Memcache  {   
	function getInstance() {
    static $instance;     

    if ( ! isset( $instance )) {
    $instance = new Memcache;
    $instance->connect(  '198.168.0.1'  );
    }       

    return $instance;      
    }  
    
    function close( ) {
        if ( isset( $instance ) ) {
            $instance->close();
            $instance = null; 
        }
    }
}

class myDatum {
    var $values = array(
        'description' => null,
        'price'       => null,
        'weight'      => null
    );
	
	function myDatum( $settings ) {
	    foreach ( $settings as $key => $value ) {
            if ( ! array_key_exists( $key, $this->values ) ) {
                die( "Unknown attribute: $key" );
            }
            
            $this->values{ $key } = $value;
        }
	}
	
	function set( $key=null, $value=null ) {
	    if ( is_null( $key ) ) {
            die( "Key cannot be null" );
        }
        
        if ( ! array_key_exists( $key, $this->values ) ) {
            die( "Unknown attribute: $key" );
        }
        
        if ( ! is_null( $value ) ) {
            $this->values{ $key } = $value;
        }
        
        return( $this->values{ $key } );
	}
	
	function get( $key=null ) {
	    return( $this->set( $key, null ) );
	}
}


$datum = new myDatum( 
    array(
        'description' => 'ball',
        'price'       => 1.50,
        'weight'      => 10
    ) 
);

print $datum->get( 'description' ) . "\n";

$cache = myCache::getInstance( );

if ( $cache->set( $datum->get( 'description' ), $datum, false, 600 ) ) {
    print( 'Object added to cache' . "\n"); 
}

$cache->close();


$new_cache = myCache::getInstance( );

$new_datum = $new_cache->get( $datum->get( 'description' ) );

if ( $new_datum !== false ) {
    print( 'Object retrieved from cache' . "\n"); 
    print $new_datum->get( 'description' ) . "\n";
}

print_r( $new_cache->getExtendedStats() );

$new_cache->close();
?>

myCache 클래스는 싱글톤(singleton)이고 캐시에 독립된 개방 연결을 제공한다. myDatum 클래스는 모든 객체들을 대표한다. 연속된 애트리뷰트(해시(hash)로 구현됨)를 갖고 있으며, 한 개의 getter와 setter 메소드를 갖고 있다. myDatum 객체를 만들려면, 값 해시를 컨스트럭터로 전달한다. 애트리뷰트를 설정하려면 스트링과 값 같은 애트리뷰트 이름으로 set()을 호출한다. 애트리뷰트를 가져오려면 애트리뷰트 이름으로 get()을 호출한다.

위 코드에서 마지막 여러 라인들에서는 객체를 생성하여 이를 캐시에 저장하고 검색한다. 두 번째 라인, Memcache API 부분은 캐시의 통계를 보여준다. 새로운 PHP 명령행 인터프리터를 사용하여 Listing 6을 실행하면 Listing 7 같은 모습을 볼 수 있다.


Listing 7. PHP 객체의 생성, 저장, 검색
                
ball
Object added to cache
Object retrieved from cache
ball
Array
(
    [72.51.41.164:11211] => Array
        (
            [pid] => 865
            [uptime] => 3812845
            [time] => 1173817644
            [version] => 1.1.12
            [rusage_user] => 0.043993
            [rusage_system] => 0.038994
            [curr_items] => 1
            [total_items] => 5
            [bytes] => 145
            [curr_connections] => 1
            [total_connections] => 8
            [connection_structures] => 3
            [cmd_get] => 5
            [cmd_set] => 5
            [get_hits] => 5
            [get_misses] => 0
            [bytes_read] => 683
            [bytes_written] => 1098
            [limit_maxbytes] => 67108864
        )
)

간단하다. myDatum용 컨스트럭터가 일반적인 것이었다면 아이디가 주어지고 데이터베이스를 쿼리하여 특정 행(예를 들어, 123-45-6789에 해당하는 학생을 찾기)이 검색된다. 이 컨스트럭터를 확장하여 아이디용 캐시를 먼저 쿼리할 수 있다. 찾게 되면 그 객체를 리턴한다. 그렇지 않으면, 객체를 만들고, 이를 저장하여 리턴하도록 한다.

Debian 리눅스 시스템을 갖고 있다면 복사하거나 (NFS를 통해) /opt/lampp를 반출하고 여러 시스템에서 memcached를 실행할 수 있다. 두 개 이상의 머신에서 memcached를 동시에 실행하면, 오류가 없어지고 캐시 용량을 확장할 수 있다. addServer() API 함수를 사용하여 사용 가능한 memcached 서버 리스트를 구현한다.






결론

Memcache PHP API는 사용이 간단하고 memcached는 전개가 쉽다. 대부분의 작업은 PHP를 재구현 하여 적절한 확장을 포함하게끔 하는 것이다. 객체를 구현하는 메소드가 고립되면, 코드를 수정하여 Memcache를 활용하는 것은 간단하다.

간단한 기술과 노력으로 PHP 애플리케이션 성능을 높일 수 있다. 더 많은 RAM이나 서버를 구입하기 전에 기존 서버를 튜닝해 보기 바란다. 훨씬 저렴하다.



참고자료

교육


제품 및 기술 얻기

토론


필자소개

Martin Streicher는 Linux Magazine의 편집장이며, Hesketh.com에서는 웹 개발자로, developerWorks의 기고자로 활동하고 있다. 퍼듀대학교에서 컴퓨터 공학 석사 학위를 받았으며, 1996년부터 유닉스 계열 시스템을 프로그래밍 하고 있다.



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

Trackback 0 Comment 0
2009. 6. 11. 10:04

PEAR 활용 imagick 설치 및 PHP 캐싱

http://pecl.php.net/package/imagick

이 사이트에 방문하시어 최종 업데이트 된 제품을 다운로드 합니다. 

wget http://pecl.php.net/get/imagick-2.2.1.tgz

# tar zxf imagick-2.2.1.tgz
# cd imagick-2.2.1.tgz

# phpize

# ./configure  --with-php-config=/usr/local/php/bin/php-config

 에러가 발생할 수 있습니다. 

checking ImageMagick MagickWand API configuration program... configure: error: not found. Please provide a path to MagickWand-config or Wand-config program.

# yum -y install ImageMagick-devel

Transaction Check Error:
  file /etc/fonts/conf.d/30-aliases-fedora.conf from install of fontconfig-2.4.1-7.el5 conflicts with file from package fontconfig-2.4.1-6.el5
  file /usr/share/hal/fdi/information/10freedesktop/20-video-quirk-pm-el5-lenovo.fdi from install of hal-0.5.8.1-35.el5 conflicts with file from package hal-0.5.8.1-25.el5
  file /usr/share/hal/fdi/policy/10osvendor/10-power-mgmt-policy.fdi from install of hal-0.5.8.1-35.el5 conflicts with file from package hal-0.5.8.1-25.el5

사실 전에 설치할 때는 이런 에러가 없었는데, 에러가 나서 다음 두 가지 프로그램을 더 설치하도록 하겠습니다.

# yum -y install fontconfig

# yum -y install hal

그리고 다시 한번 반복해줍니다.

# yum -y install ImageMagick-devel

# make
# make install

Installing shared extensions:     /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/

이렇게 해주면 정상적으로 처리가 됩니다.

 

그런 다음 확장자를 php.ini에 등록시켜 줘야 합니다.
다음 사항을 수정시켜줍니다. 또는 추가해줍니다.  

; Directory in which the loadable extensions (modules) reside.
;extension_dir = "./"
extension_dir = "/usr/local/php/lib/php/extensions"
enable_dl = On
extension="no-debug-non-zts-20060613/imagick.so" 

아파치 재시작해줘야 합니다.

그리고 한가지 더 phpinfo를 보게 되면 다음과 같은 옵션이 보여야 합니다.

 



PEAR로 PHP 프로그램 캐싱하기


캐싱(caching)은
PHP 세계에서 현재 가장 빈번하게 언급되는 주제이다. PHP는 동적 웹 페이지를 생성하므로 웹 페이지가 요청 되어지면 매번 스크립트가 실행되어야 하며 실행 결과가 같다고 하더라도 그 결과는 매번 연산되어야 한다. 게다가 PHP는 스크립트가 요청될 때마다 컴파일한다. 이러한 오버헤드는 과중한 트래픽과 함께 사이트의 속도를 느리게 만들기도 한다. 다행히도 웹 요청 결과는 저장되거나 캐시될 수 있으며 스크립트를 재실행 하거나 컴파일 할 필요 없이 매칭 요청으로 제시될 수 있다. ZendCache같은 상품이나 Alternate PHP Cache같은 오픈 소스 솔루션은 바이트 코드인 PHP 스크립트의 컴파일된 버전을 캐시해준다. 'PHP land' 솔루션이 PHP디자인에 타격을 가하는 동안 'Userland'솔루션은 웹 애플리케이션 디자인과 프로그램에서 발생하는 일반적인 병목현상을 해결함으로써 한 단계 더 발전할 수 있다.(여기 사용된 'PHP land'는 PHP 4를 구동시키는 Zend Engine과 같은 PHP 언어 수준을 말하며 'Userland'는 PHP사용자에 의해 저작된 것을 말한다.) 데이터베이스 안에 저장된 거대한 카탈로그와 같은 상업적 응용 프로그램을 생각해 보자. 현실적으로 그 카탈로그의 정보는 하루 한 두 번 특정 시간대에 바뀔 것이다. 그리고 여전히 제품 페이지에 요청이 들어올 때마다 데이터베이스 쿼리는 수행된다. 이러한 오버로드는 쿼리 결과나 요청 페이지의 완벽한 HTML 출력을 캐싱함으로써 피할 수 있다. PEAR의 캐시 패키지는 동적인 내용, 데이터베이스 쿼리와 PHP 함수 호출을 캐싱하기 위한 프레임워크를 제공한다. 어디에서 PEAR 캐시를 얻을 수 있는가? 펄이 CPAN, TeX가 CTAN을 가지고 있듯이 PHP또한 클래스와 라이브러리 모듈을 위한 중앙 저장소를 가지고 있다. 이 중앙 저장소를 PEAR라고 부르며 이는 PHP Extension and Add-On Repository의 약자이다. 이 기사는 여러분이 PEAR 환경 설정을 이미 마쳤다는 가정 하에 기술된 것이다. 보기로 든 예제는 CVS에서 사용하는 PEAR Cache 개발 버전으로 만들어지고 테스트한 것이다. PEAR 캐시는 어떻게 작동하는가? PEAR 캐시 패키지는 일반 Cache 클래스, 함수 호출을 캐시하기위한 클래스, 스크립트 출력과 같은 몇 개의 특화된 하위 클래스로 구성된다. Cache 클래스는 실질적으로 캐시된 데이터를 저장하고 운영하는 Container 클래스라 불리는 다양한 종류의 클래스를 이용할 수 있다. 다음은 개개의 매개변수와 함께 PEAR 캐시의 현재 컨테이너 구현 목록을 정리해 놓은 것이다.

  • file - file 컨테이너는 캐시된 데이터를 파일 시스템 내에 저장한다. 이것은 가장 빠른 컨테이너이다.
  • Cache_dir - 이것은 컨테이너가 파일을 저장하는 디렉토리이다.
  • Filename_prefix - 캐시 파일을 위한 파일명 접두사, 예를 들어 "cache_"
  • shm - shm 컨테이너는 공유 메모리 내로 캐시된 데이터를 저장한다. 벤치마크는 이 컨테이너의 현재 구현이 file 컨테이너보다 훨씬 느리다는 것을 암시한다.
  • shm_key - 사용되는 공유 메모리 키
  • shm_perm - 공유 메모리 조각을 위한 퍼미션
  • shm_size - 할당된 공유 메모리의 크기
  • sem_key - 사용되는 새마포어 키
  • sem_perm - 세마포어를 위한 퍼미션
  • db - PEAR의 데이터베이스 분리 계층
  • dsn - DSN 사용된 데이터베이스 연결의 DSN. 세부 사항을 위해 PEAR DB 서류라고 명기해야 함.
  • Cache_table - 사용되는 테이블의 이름
  • phplib - phplib 컨테이너는 캐시된 데이터를 저장하기 위한 데이터베이스 분리 계층을 사용한다.
  • db_class
  • db_file
  • db_path
  • local_file
  • local_path
  • ext/dbx - PHP 데이터베이스 분리 계층 확장자. 이것은 여러분이 캐시된 데이터를 데이터베이스 내로 저장하고자 할 때 일반적으로 선택하는 컨테이너이다.
  • module
  • host
  • db
  • username
  • password
  • cache_table
  • persistent
PEAR 캐시를 사용함으로써 얻을 수 있는 수행상 이점은 여러분이 어떤 캐시 컨테이너를 사용하느냐에 크게 좌우된다. 예를 들어, 데이터베이스의 쿼리 결과를 다시 데이터베이스로 저장시키는 것은 아무 의미가 없다는 뜻이다. 함수 호출 캐싱 PEAR Cache의 Function Cache 모듈은 어떤 함수나 메소드의 결과와 출력이 내장 PHP함수나 사용자 정의 함수라 하더라도 캐시한다. 초기 설정값은 File 컨테이너를 사용하고 캐시 데이터를 function_cache 라 이름 붙여진 디렉토리로 갖다 놓는다. Cache_Function 클래스 생성자는 선택 가능한 모든 매개변수를 3개까지 받아들일 수 있다.
  • $container 사용할 캐시 컨테이너의 이름
  • $container_options 캐시 컨테이너를 위한 매개변수의 배열
  • $expires 캐시 개체가 만기된 후 시간을 나타내는 숫자

Cache_Function 클래스의 call()메소드를 사용하는 일반 함수 호출을 래핑함으로써 캐시된 함수 호출은 유발된다. Call()을 사용하는 것은 매우 쉽다. 첫번째 매개변수는 호출할 함수나 메소드의 이름을 지정하고 호출된 함수나 메소드의 매개변수가 그 뒤에 제시된다. Call()의 두 번째 매개변수는 호출된 함수나 메소드의 첫번째 매개변수이다. 이와 같은 방법으로 프로그램은 계속 작성된다. 그러면 이제 예제를 한 번 살펴보자.

 

예제 1: 캐싱 함수와 메소드 호출

<.;?php // Load PEAR Cache's Function Cache < 'Cache/Function.php'; // Define some classes and functions / methods // for demonstration class foo { function bar($test) { echo "foo::bar($test)<br>"; } } class bar { function foobar($object) { echo '$'.$object.'->foobar('.$object.')<br>'; } } $bar = new bar; function foobar() { echo 'foobar()'; } // Get Cache_Function object $cache = new Cache_Function(); // Cached call to static method bar() of class foo // (foo::bar()) $cache->call('foo::bar', 'test'); // Cached call to method foobar() of object bar // ($bar->foobar()) $cache->call('bar->foobar', 'bar'); // Cached call to function foobar() $cache->call('foobar'); ?>

함수 호출의 캐싱은 일일 기준으로 변하는 XML 소스의 XSL 변형과 같이 시간을 많이 소비하는 상황에서 편리하게 사용된다. 출력 캐싱 상업 응용 프로그램의 도입 예제를 돌이켜 볼 때, 이제 여러분은 요구할 때마다 데이터베이스에서 꺼내 사용할 수 있는 카탈로그 정보나 파싱된 템플릿 요소를 캐시할 수 있다. 우리는 이제 Cache_Output 클래스와 함께 스크립트의 완벽한 출력을 캐시함으로서 한 단계 더 발전하는 것이다.

 

예제 2: 캐싱 스크립트의 출력

<?php // Load PEAR Cache's Output Cache require_once 'Cache/Output.php'; $cache = new Cache_Output('file', array('cache_dir' => '.') ); // Compute unique cache identifier for the page we're about // to cache. We'll assume that the page's output depends on // the URL, HTTP GET and POST variables and cookies. $cache_id = $cache->generateID(array('url' => $REQUEST_URI, 'post' => $HTTP_POST_VARS, 'cookies' => $HTTP_COOKIE_VARS) ); // Query the cache if ($content = $cache->start($cache_id)) { // Cache Hit echo $content; die(); } // Cache Miss // -- content producing code here -- // Store page into cache echo $cache->end(); ?>
Cache_Output 클래스를 사용하면 쉽게 동적 데이터베이스 구동 웹 애플리케이션을 정적 애플리케이션으로 변화시킬 수 있다. 이것은 사이트의 수행 능력을 현저하게 개선시킬 수 있다. 점점 더 많은 웹 사이트가 HTML 컨텐트를 위해 GZIP를 사용한다. 이것은 서버의 대역폭을 감소시키며 트래픽 발생으로 인한 비용도 줄여준다. 게다가, 그것은 이러한 모뎀 연결을 이용하는 사용자의 경험을 증가시킨다. 내용을 압축하는데 필요한 CPU시간을 절약하기 위해 생성된 HTML의 GZIP 압축 버전을 캐시함에 따라 Cache_OutputCompressionCache_Output 클래스의 상관성을 확장시킨다. 맞춤식 솔루션 이전에 나는 PEAR Cache 프래임워크가 어떻게 맞춤식 캐싱 솔루션을 개발하기 위해 사용될 수 있는지에 대해 설명하였다. 그때 나는 SELECT 쿼리 결과를 캐시하는 MySQL_Query_Cache클래스를 선택하여 설명했다. 그렇다면 이제 클래스 변수인 생성자와 소멸자부터 시작해 보자. 생성자는 Cache_FunctionCache_Output클래스 앞에서 캐시 컨테이너 옵션을 옮기기 위해 사용된다. 소멸자는 MySQL 연결을 종료하고 필요하다면 캐시의 가비지 컬렉션을 작동시킨다.

<?php require_once 'Cache.php'; class MySQL_Query_Cache extends Cache { var $connection = null; var $expires = 3600; var $cursor = 0; var $result = array(); function MySQL_Query_Cache($container = 'file', $container_options = array('cache_dir'=> '.', 'filename_prefix' => 'cache_'), $expires = 3600) { $this->Cache($container, $container_options); $this->expires = $expires; } function _MySQL_Query_Cache() { if (is_resource($this->connection)) { mysql_close($this->connection); } $this->_Cache(); } } ?>
 
실제적으로 쿼리를 수행하고 캐시하는 핵심적인 부분을 살펴보기 이전에 좀더 도움을 주는 함수에 대해 살펴보자.

<?php function connect($hostname, $username, $password, $database) { $this->connection = mysql_connect($hostname, $username, $password) or trigger_error('Could not connect to database.', E_USER_ERROR); mysql_select_db($database, $this->connection) or trigger_error('Could not select database.', E_USER_ERROR); } function fetch_row() { if ($this->cursor < sizeof($this->result)) { return $this->result[$this->cursor++]; } else { return false; } } function num_rows() { return sizeof($this->result); } ?>
우리는 MySQL 데이터베이스에 연결하거나 캐시된 결과로부터 열을 불러오고 세트 안에 있는 열의 숫자를 가져오는데 필요한 함수를 이미 알고 있다. 그렇다면 데이터베이스 쿼리가 어떻게 수행하고 캐시하는지 살펴보도록 하자.

<?php function query($query) { if (stristr($query, 'SELECT')) { // Compute unique cache identifier for this query $cache_id = md5($query); // Query the cache $this->result = $this->get($cache_id, 'mysql_query_cache'); if ($this->result == NULL) { // Cache Miss $this->cursor = 0; $this->result = array(); if (is_resource($this->connection)) { // Use mysql_unbuffered_query(), if available if (function_exists('mysql_unbuffered_query')) {$result = mysql_unbuffered_query($query, $this->connection); } else {$result = mysql_query($query, $this->connection); } // Fetch all result rows while ($row = mysql_fetch_assoc($result)) {$this->result[] = $row; } // Free MySQL Result Resource mysql_free_result($result); // Store result set in cache $this->save($cache_id, $this->result, $this->expires, 'mysql_query_cache'); } } } else { // No SELECT query, don't cache it return mysql_query($query, $this->connection); } } ?>

 
예제 3: 활성중인 MySQL 쿼리 캐시

<?php require_once 'MySQL_Query_Cache.php'; $cache = new MySQL_Query_Cache(); $cache->connect('hostname', 'username', 'password', 'database'); $cache->query('select * from table'); while ($row = $cache->fetch_row()) { echo '<p>'; print_r($row); echo '</p>'; } ?>
이상 주어진 정보만으로도 여러분은 대부분의 응용 프로그램에서 PHP웹 페이지를 캐싱할 수 있을 것이다. 세바스찬 베르그만(Sebastian Bergmann)은 23세의 독일출신 컴퓨터 공학도이며 PHP 프로젝트에 참여하고 있다. 이외에도 온라인 및 오프라인의 자유기고가로 활동하고 있으며 독일 PHP 연합 고문단(www.php-ev.de)의 일원으로 phpOpenTracker 소프트웨어(www.phpOpenTracker.de)를 개발하고 있다. 
 


출처 : 한빛 네트워크


Trackback 1 Comment 1
  1. Favicon of http://blog.naver.com/jjusik2 프시쵸 2012.04.26 18:54 address edit & del reply

    좋은 정보 감사합니다~. imagick을 설치해서 문서 이미지(tiff)에 원하는 폰트 불러와서 문서에 체크, 글자를 넣으려 하는데 첫 길목부터 저를 힘들게 하더군요. =ㅅ= 그래도 이렇게 좋으신 분들이 있어서 제가 덜 고생을 하는 것 같습니다.