PHP의 두 확장 모듈인 memcache와 memcached의 차이점에 대해 인터넷에 널리 유포된 기사가 있습니다. 특히 memcached와 memcached의 큰 차이점은 memcached 모듈이 긴 연결을 지원하지 않는다는 점을 강조합니다. 그래서 수년 동안 저는 memcached가 긴 연결을 지원하지 않는다고 생각했습니다. 사실 memcached 확장 모듈은 아주 초기 버전부터 긴 연결을 지원해 왔습니다. 확장 모듈의 소스 코드에서 확인할 수 있습니다:
/* {{{ Memcached::__construct([string persist_id[, callback on_new[, string Connection_str]]]))
선택적으로 영구 Memcache 연결을 사용하여 Memcached 객체를 생성합니다. */
정적 PHP_METHOD(Memcached, __construct)
{
PHP 매뉴얼에서 memcached 확장 모듈이 제공하는 생성자가 매뉴얼에 소개된 선택적 매개변수 persistent_id
를 제공하는 것을 볼 수 있습니다:
기본적으로 Memcached 인스턴스는 요청이 종료된 후 삭제됩니다. 하지만 인스턴스를 생성할 때 persistent_id
으로 각 인스턴스에 고유 ID를 지정하면 요청 간에 인스턴스를 공유할 수 있습니다. 동일한 persistent_id
값으로 생성된 모든 인스턴스는 동일한 연결을 공유합니다.
이 매개변수의 의미는 명명된 ID를 생성자에 전달하면 긴 연결이 설정된다는 것입니다. 일반적으로 우리는 PHP-FPM 모드를 사용하므로 PHP-FPM 프로세스는 memcached 서비스를 다시 시작합니다. 연결 채널. 또한 persist_id는 연결 풀 이름이고 모든 php-fpm 프로세스는 이 연결 풀의 구성원이라는 것을 이해할 수 있습니다.
그러나 우리가 주의해야 할 점은 PHP가 해석된 언어라는 것입니다. PHP가 처음으로 memached 모듈을 통해 긴 연결을 설정할 때 후속 PHP 실행에서는 동일한 persist_id를 사용하여 긴 연결을 구축해서는 안 된다는 점을 기억하세요. memcached의 생성자.다른 persist_id 이름을 가진 긴 연결이 설정될 수 있습니다. php에서 동일한 이름을 반복적으로 실행하면 php-fpm 프로세스가 비정상적으로 발생하고 memcached와의 통신이 점점 느려지게 됩니다. 동시에 libmemcached 버전에 따라 PHP가 coredump를 생성하게 됩니다.
그러면 persist_id라는 이름의 긴 연결을 설정한 후 단일 php-fpm이 반복적으로 긴 연결을 설정하는 것을 방지하려면 어떻게 해야 할까요? 실제로 PHP 매뉴얼에 주석으로 설명되어 있는데, 내용은 다음과 같습니다.
영구 연결을 사용하는 경우 서버를 다시 추가하지 않는 것이 중요합니다.
이것은 당신이 하고 싶지 않은 일입니다:
$mc = new Memcached('mc'); $mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); $mc->addServers(array( array('mc1.example.com',11211), array('mc2.example.com',11211), ));
페이지가 로드될 때마다 해당 서버가 목록에 추가되어 동일한 서버에 대한 동시 연결이 많이 발생합니다. addServer/addServers 기능은 지정된 서버에 대한 기존 참조를 확인하지 않습니다.
더 나은 접근 방식은 다음과 같습니다.
$mc = new Memcached('mc'); $mc->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); if (!count($mc->getServerList())) { $mc->addServers(array( array('mc1.example.com',11211), array('mc2.example.com',11211), )); }<br />
getServerList() 메소드를 사용하여 현재 실행에 사용되는 php-fpm 프로세스 컨테이너에 동일한 이름을 가진 긴 연결 리소스가 이미 존재하는지 확인합니다. 존재하는 경우 addServers() 메소드를 반복적으로 사용하지 마십시오. 새로운 연결 구성을 추가합니다.