Memcached::__construct

Descrierea

publicMemcached::__construct
([ string$persistent_id
] )

Creates a Memcached instance representing the connection to the memcache
servers.

Parametri

persistent_id

By default the Memcached instances are destroyed at the end of the
request. To create an instance that persists between requests, use
persistent_id to specify a unique ID for the
instance. All instances created with the same
persistent_id will share the same connection.

User Contributed Notes 7 notes

When using persistent connections, it is important to not re-add servers.

This is what you do not want to do:<?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),));?>Every time the page is loaded those servers will be appended to the list resulting in many simultaneous open connections to the same server. The addServer/addServers functions to not check for existing references to the specified servers.

If you're wanting to get started with Memcached on a relatively small project but need some scalability then it can make sense to allow $persistent_id to also denote both a key prefix and a server set which you define yourself. This keeps both key separation and allocation of data sets to certain server(s) incredibly simple throughout the project's life, without hampering any of your options.

<?php

// Here is the array which we will add to in the future$GLOBALS['memcached-sets'] = array ('_' => array ( array('localhost', 11211) ) );

// Add servers if no connections listed. Get server set by $persistent_id or use default set. // In a production environment with multiple server sets you may wish to prevent typos from silently adding data // to the default pool, in which case return an error on no match instead of defaultingif( !count($instance->getServerList()) ) {$servers = array_key_exists($persistent_id, $GLOBALS['memcached-sets']) ? $GLOBALS['memcached-sets'][$persistent_id] : $GLOBALS['memcached-sets'][DEFAULT_MEMCACHED_SET];$instance->addServers($servers); }

This is why you do not want to call ->addServers() every time your script runs, because ->addServers() does not check for dups and will add hundreds or thousands of connections to the memcached daemon proc from the Apache proc(s).

One side effect is that any other scripts (even across different website domains) can also add to your server "pool" (if they know the server pool name, or if they can get it from the memcached daemon itself (not sure if/how this is possible), or if you or your team has coded several sites using the same server pool (i.e., new Memcached( 'same-server-pool-name' ) ). This may present a security hole.

Note that with this Memcached interface, if one or more underlying memcached daemons are down, suffering high network latency (over 1 second by default), or have crashed, then there still will be no warning, no error, no notice. Everything will appear to work correctly, you just won't get proper results back.

This was causing me to tear my hair out since I listened to the comments posted here.

If you enable persistence, the options you set will persist as well AND certain options if you set them with persistence enabled WILL CLOSE ALL YOUR PERSISTED CONNECTIONS. This is a part of libmemcached that the memcached extensions is built against. You can verify this by running strace.

So this is what you should do:

<?php

$mem = new Memcached($myPoolId);

if(empty($mem->getServerList())) {//This code block will only execute if we are setting up a new EG(persistent_list) entry$mem->setOption(Memcached::OPT_RECV_TIMEOUT, 1000);$mem->setOption(Memcached::OPT_SEND_TIMEOUT, 3000);$mem->setOption(Memcached::OPT_TCP_NODELAY, true);$mem->setOption(Memcached::OPT_PREFIX_KEY, "md_");$mem->addServer($myMemcahceIp, $myMemcachePort);}