PHP模塊中Memcached和Memcache的卻別

PHP搭配Memcached已是婦孺皆知的標配了。再提彷佛讓人以爲太「圡」了,不過有一些細節不見得人人都清楚,好比說PECL裏有兩個Memcached的模塊,MemcacheMemcached,目前大部分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

相關文章
相關標籤/搜索