PHP搭配Memcached已是妇孺皆知的标配了。再提彷佛让人以为太“圡”了,不过有一些细节不见得人人都清楚,好比说PECL里有两个Memcached的模块,Memcache和Memcached,目前大部分PHP环境里使用的是名字里不带d的Memcache版本,这个版本释出的比较早,是一个原生版本,与之对应的带d的Memcached版本则是创建在libmemcached的基础上,因此说Memcached版本的功能更全一些。
安装Memcached版本的PHP模块
wget http://download.tangent.org/libmemcached-0.35.tar.gz
tar zxf libmemcached-0.35.tar.gz
cd libmemcached-0.35
./configure
make
make install
wget http://pecl.php.net/get/memcached-1.0.0.tgz
tar zxf memcached-1.0.0.tgz
cd memcached-1.0.0
phpize
./configure
make
make install
打开php.ini加上:
extension = "memcached.so"
这样安装就结束了,你能够经过下列命令来确认:
php -m | grep mem
演示Memcached版本的新功能
先虚构一个问题,假设counter初始值是一个整数,不使用increment方法,经过get/set完成每次加一。
在Memcache版本里,咱们只能按照大体以下的方式来进行:
$m = new Memcache();
$m->addServer('localhost', 11211);
$v = $m->get('counter');
$m->set('counter', $v + 1);
因为get/set这两个动做没法做为一个原子来操做,因此当多个进程同时处理时,会出现丢失的可能,更让人恼火的是,你根本就不知道何时出现丢失。
再看看Memcached版本里,咱们是如何作的:
$md = new Memcached();
$md->addServer('localhost', 11211);
$v = $md->get('counter', null, $token)
$md->cas($token, 'counter', $v + 1);
cas是Memcached版本里提供的功能,说白了就是一个乐观锁的功能,若是你把$token的值var_dump出来,就会发现$token其实就是一个版本号,若是经过get获得的$token版本号在cas的时候不对应,就说明已经有别的操做更新了,此时cas操做会失败,至于如何继续操做,就看你本身了。
注:若是你想手动重现一下冲突的状况,可在get和cas之间sleep若干秒,并拷贝两份脚本,前后执行。
顺便说一句,推荐的Memcached版本模块的哈希设置以下:
$md->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT);
$md->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);
总结
Memcached版本还有不少Memcache没有的功能,好比经过getByKey, setByKey等自动支持多个服务器,就不赘述了,该用哪一个扩展已经不言自明了。
补充:http://code.google.com/p/memcached/wiki/PHPClientComparisonphp