16.6.3.6 PHP와 MySQL과 memcached 사용
PHP는 PECL 확장에 의해 Memcache 함수를 지원합니다. PHP의 memcache
확장을 사용하려면 PHP를 소스에서 빌드 할 때 configure에 --enable-memcache
옵션을 지정하여 빌드합니다.
Red Hat 기반 서버를 설치하는 경우는 php-pecl-memcache
RPM을 설치할 수 있습니다.
root-shell> yum --install php-pecl-memcache
Debian 기반 배포는 php-memcache
패키지를 사용합니다.
글로벌 런타임 구성 옵션을 설정하려면 php.ini
파일에 구성 옵션의 값을 지정합니다. 다음 표는 각각의 전역 런타임 구성 옵션의 이름, 기본값 및 설명을 보여줍니다.
구성 옵션 | 기본 | 설명 |
---|---|---|
memcache.allow_failover | 1 | 처음에 선택한 서버에 오류가 발생한 경우 목록에서 다른 서버를 쿼리 할 것인지 지정합니다. |
memcache.max_failover_attempts | 20 | 실패를 반환하기 전에 시도하는 서버의 수를 지정합니다. |
memcache.chunk_size | 8192 | memcached 서버와의 데이터 교환에 사용하는 네트워크 청크 크기를 정의합니다. |
memcache.default_port | 11211 | memcached 서버와 통신 할 때 사용하는 기본 포트를 정의합니다. |
memcache.hash_strategy | standard | 사용하는 해시 방식을 지정합니다. consistent 로 설정하면 키를 다른 서버로 재 할당하지 않고 풀에 서버를 추가하거나 풀에서 제거 할 수 있습니다. standard 로 설정하면 저장시 다른 서버를 사용할 수있는 오래된 (모듈러) 방식이 사용됩니다. |
memcache.hash_function | crc32 | 키를 서버에 매핑 할 때 사용하는 함수를 지정합니다. crc32 하면 표준 CRC32 해시가 사용됩니다. fnv 하면 FNV-1a 해시 알고리즘이 사용됩니다. |
memcached 서버에 대한 연결을 만들려면 새로운 Memcache
오브젝트를 작성하고 연결 옵션을 지정합니다. 예 :
<?php $cache = new Memcache; $cache->connect('localhost',11211); ?>
그러면 지정한 서버에 연결이 즉시 엽니 다.
여러 memcached 서버를 사용하려면 addServer()
를 사용하여 memcache 개체에 서버를 추가해야합니다.
bool Memcache::addServer ( string $host [, int $port [, bool $persistent [, int $weight [, int $timeout [, int $retry_interval [, bool $status [, callback $failure_callback ]]]]]]] )
php-memcache
모듈의 서버 관리 메커니즘이 인터페이스의 중요한 부분이며, memcached 인스턴스에 대한 기본 인터페이스와 해시 메커니즘에 의한 인스턴스를 선택하는 방법을 제어합니다.
두 memcached 인스턴스에 대한 간단한 연결을 만들려면 :
<?php $cache = new Memcache; $cache->addServer('192.168.0.100',11211); $cache->addServer('192.168.0.101',11211); ?>
이 시나리오에서는 인스턴스 연결은 명시 적으로 열리지 않고 값을 저장하거나 검색하려고 한 경우에만 열립니다. memcached 인스턴스에 영구 연결을 활성화하려면 $persistent
인수를 true로 설정합니다. 이것은 기본 설정이며, 이에 따라 연결이 열려 있습니다.
다른 인스턴스에 열쇠 분포를 제어하려면 memcache.hash_strategy
전역 설정을 사용합니다. 이것은 선택에 사용되는 해시 메커니즘을 설정합니다. 각 서버에 다른 가중치를 추가 할 수 있습니다. 이 가중치는 인스턴스 항목이 인스턴스 목록에 나타나는 횟수를 효과적으로 증가시켜 다른 인스턴스보다 그 인스턴스가 선택 될 가능성을 늘립니다. 이 가중치를 설정하려면 $weight
인수를 1보다 큰 값으로 설정합니다.
정보를 설정하고 검색하는 기능이 테이블에 같이 memcached
에 사용할 수있는 범용 함수 인터페이스와 동일합니다.
PECL의 memcache 함수 | 일반 함수 |
---|---|
get() | 일반 get() . |
set() | 일반 set() . |
add() | 일반 add() . |
replace() | 일반 replace() . |
delete() | 일반 delete() . |
increment() | 일반 incr() . |
decrement() | 일반 decr() . |
PECL의 memcache
인터페이스의 완벽한 예를 보여줍니다. 이 코드는 사용자가 영화 이름을 지정한 때 Sakila 데이터베이스에서 영화 데이터를로드합니다. memcached
인스턴스에 저장되어있는 데이터는 mysqli
결과 행으로 기록되고이 정보는 API에 의해 자동으로 직렬화됩니다.
<?php $memc = new Memcache; $memc->addServer('localhost','11211'); if(empty($_POST['film'])) { ?> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Simple Memcache Lookup</title> </head> <body> <form method="post"> <p><b>Film</b>: <input type="text" size="20" name="film"></p> <input type="submit"> </form> <hr/> <?php } else { echo "Loading data...\n"; $film = htmlspecialchars($_POST['film'], ENT_QUOTES, 'UTF-8'); $mfilms = $memc->get($film); if ($mfilms) { printf("<p>Film data for %s loaded from memcache</p>", $mfilms['title']); foreach (array_keys($mfilms) as $key) { printf("<p><b>%s</b>: %s</p>", $key, $mfilms[$key]); } } else { $mysqli = mysqli('localhost','sakila','password','sakila'); if (mysqli_connect_error()) { sprintf("Database error: (%d) %s", mysqli_connect_errno(), mysqli_connect_error()); exit; } $sql = sprintf('SELECT * FROM film WHERE title="%s"', $mysqli->real_escape_string($film)); $result = $mysqli->query($sql); if (!$result) { sprintf("Database error: (%d) %s", $mysqli->errno, $mysqli->error); exit; } $row = $result->fetch_assoc(); $memc->set($row['title'], $row); printf("<p>Loaded (%s) from MySQL</p>", htmlspecialchars($row['title'], ENT_QUOTES, 'UTF-8'); } } ?> </body> </html>
PHP는 PHP와 관련된 Apache 인스턴스의 실행을 계속하는 한, memcached 인스턴스에 대한 연결이 열린 상태로 유지됩니다. 실행중인 인스턴스에서 서버를 목록에 추가하거나 목록에서 제거 할 때 (예를 들어, 추가 서버가 지정된 다른 스크립트를 시작할 때 등) 연결은 공유되지만 스크립트에서 명시 으로 구성된 인스턴스 만 선택됩니다.
스크립트에서 서버 목록을 변경하여 문제가 발생하지 않도록하려면 반드시 일치 해시 메커니즘을 사용하십시오.