什么是CAS協議
Memcached於1.2.4版本新增CAS(Check and Set)協議類同於Java並發的CAS(Compare and Swap)原子操作,處理同一item被多個線程更改過程的並發問題。
在Memcached中,每個key關聯有一個64-bit長度的long型惟一數值,表示該key對應value的版本號。這個數值由Memcached server產生,從1開始,且同一Memcached server不會重復。在兩種情況下這個版本數值會加1:1、新增一個key-value對;2、對某已有key對應的value值更新成功。刪除item版本值不會減小。
php使用
Memcached::cas()執行一個“檢查並設置”的操作,因此,它僅在當前客戶端最后一次取值后,該key 對應的值沒有被其他客戶端修改的情況下, 才能夠將值寫入。檢查是通過cas_token
參數進行的, 這個參數是Memcach指定給已經存在的元素的一個唯一的64位值, 怎樣獲取這個值請查看Memcached::get*() 系列方法的文檔。注意:這個值作為double類型是因為PHP的整型空間限制。
譯注:這是Memcached擴展比Memcache擴展一個非常重要的優勢, 在這樣一個系統級(Memcache自身提供)的沖突檢測機制(樂觀鎖)下, 我們才能保證高並發下的數據安全。
<?php $m = new Memcached(); $m->addServer('localhost', 11211); do { /* 獲取ip列表以及它的標記 */ $ips = $m->get('ip_block', null, $cas); /* 如果列表不存在, 創建並進行一個原子添加(如果其他客戶端已經添加, 這里就返回false)*/ if ($m->getResultCode() == Memcached::RES_NOTFOUND) { $ips = array($_SERVER['REMOTE_ADDR']); $m->add('ip_block', $ips); /* 其他情況下,添加ip到列表中, 並以cas方式去存儲, 這樣當其他客戶端修改過, 則返回false */ } else { $ips[] = $_SERVER['REMOTE_ADDR']; $m->cas($cas, 'ip_block', $ips); } } while ($m->getResultCode() != Memcached::RES_SUCCESS); ?>