首頁  >  文章  >  後端開發  >  PHP記憶體快取memcached模組安裝與用法

PHP記憶體快取memcached模組安裝與用法

WBOY
WBOY原創
2016-07-25 08:52:43815瀏覽
  1. # tar -xzf libevent-1.1a.tar.gz
  2. # cd libevent-1.1a
  3. # ./configure --prefix=/usr
  4. # make
  5. # make install
  6. # cd ..
  7. # tar -xzf memcached-1.1.12.tar.gz
  8. # cd memcached-1.1.12 # make
  9. # make install
複製程式碼

安裝完成之後,memcached 應該在 /usr/bin/memcached。三、執行memcached 守護程式執行memcached 守護程式很簡單,只需一個命令列即可,不需要修改任何設定檔(也沒有設定檔給你修改):/usr/bin/memcached -d -m 128 -l 192.168.1.1 -p 11211 -u httpd參數解釋:-d 以守護程序(daemon)方式運行memcached; -m 設定 memcached 可以使用的記憶體大小,單位為 M; -l 設定監聽的 IP 位址,如果是本機的話,通常可以不設定此參數; -p 設定監聽的端口,預設為 11211,所以也可以不設定此參數; -u 指定用戶,如果目前為 root 的話,需要使用此參數指定用戶。當然,還有其它參數可以用,man memcached 一下就可以看到了。

三、memcached 的工作原理首先memcached 是以守護程序方式運行於一個或多個伺服器中,隨時接受客戶端的連接操作,客戶端可以由各種語言編寫,目前已知的客戶端API 包括Perl /PHP/Python/Ruby/Java/C#/C 等等。 PHP 等客戶端在與memcached 服務建立連線之後,接下來的事情就是存取物件了,每個被存取的物件都有一個唯一的識別碼key,存取操作都透過這個key 進行,保存到memcached中的物件實際上是放置記憶體中的,並不是保存在cache 檔案中的,這也是為什麼memcached 能夠如此高效快速的原因。

注意,這些物件並不是持久的,服務停止之後,裡邊的資料就會遺失。

四、PHP 如何作為 memcached 用戶端有兩種方法

可以使 PHP 作為 memcached 用戶端,呼叫 memcached 的服務進行物件存取操作。

第一種,PHP 有一個叫做memcache 的擴展,Linux 下編譯時需要帶上–enable-memcache[=DIR] 選項,Window 下則在php.ini 中去掉php_memcache.dll 前邊的註釋符,使其可用。 除此之外,還有一種方法,可以避開擴充、重新編譯所帶來的麻煩,那就是直接使用 php-memcached-client。

本文選用第二種方式,雖然效率會比擴充函式庫稍差一些,但問題不大。四、PHP memcached 應用範例首先 下載 memcached-client.php,在下載了 memcached-client.php 之後,就可以透過這個檔案中的類別「memcached」對 memcached 服務進行操作了。其實程式碼呼叫非常簡單,主要會用到的方法有 add()、get()、replace() 和 delete(),方法說明如下:add ($key, $val, $exp = 0) 往 memcached 中寫入對象,$key 是對象的唯一標識符,$val 是寫入的對象數據,$exp 為過期時間,單位為秒,預設為不限時間;get ($key) 從 memcached 取得物件數據,透過物件的唯一識別碼 $key 取得;replace ($key, $value, $exp=0) 使用 $value 取代 memcached 中標識符為 $key 的物件內容,參數與 add() 方法一樣,只有 $key 物件存在的情況下才會起作用;delete ($key, $time = 0) 刪除 memcached 中標識符為 $key 的對象,$time 為可選參數,表示刪除之前需要等待多長時間。

以下是一段簡單的測試程式碼,程式碼中對標識符為 'mykey' 的物件資料進行存取操作:

  1. // 包含memcached 類別檔案
  2. require_once('memcached-client.php');
  3. // 選項設定
  4. 'debug' => true , //是否開啟debug
  5. 'compress_threshold' => 10240, //超過多少位元組的資料時進行壓縮
  6. 'persistant' => false //是否使用持久連線
  7. );
  8. // 建立memcached 物件實例
  9. $mc = new memcached($options);
  10. // 設定此腳本使用的唯一識別碼
  11. $key = 'mykey';
  12. // 往memcached 中寫入物件
  13. $mc->add($key, 'some random strings');
  14. $val = $mc->get($key);
  15. echo "n".str_pad('$ mc->add() ', 60, '_')."n";
  16. var_dump($val);
  17. // 取代已寫入的物件資料值
  18. $mc->replace( $key, array('some'=>'haha', 'array'=>'xxx'));
  19. $val = $mc->get($key);
  20. echo "n".str_pad ('$mc->replace() ', 60, '_')."n";
  21. var_dump($val);
  22. // 刪除memcached 中的物件
  23. $mc->delete( $key);
  24. $val = $mc->get($key);
  25. echo "n".str_pad('$mc->delete() ', 60, '_')."n" ;
  26. var_dump($val);
  27. ?>
複製程式碼

在實際應用中,通常會把資料庫查詢的結果集保存到memcached 中,下次訪問時直接從memcached 中獲取,而不再做資料庫查詢操作,這樣可以在很大程度上減輕資料庫的負擔。通常會將 SQL 語句 md5() 之後的值當作唯一識別碼 key。

以下是利用 memcached 來快取資料庫查詢結果集的範例(此程式碼片段緊接上邊的範例程式碼):

  1. $sql = 'SELECT * FROM users';
  2. $key = md5($sql); //memcached 物件識別碼
  3. $key = md5($sql); //memcached 物件識別碼
  4. {
  5. // 在memcached 中未取得到快取數據,則使用資料庫查詢取得記錄集。
  6. echo "n".str_pad('Read datas from MySQL.', 60, '_')."n";
  7. $conn = mysql_connect('localhost', 'test', 'test');
  8. mysql_select_db('test');
  9. $result = mysql_query($sql);
  10. while ($row = mysql_fetch_object($result))
  11. $datas[] = $row;fetch_object($result))
  12. $datas[] = $row; // 將資料庫中取得的結果集資料儲存到memcached 中,以供下次造訪時使用。
  13. $mc->add($key, $datas);
  14. {
  15. echo "n".str_pad('Read datas from memcached.', 60, '_')."n";
  16. }
  17. var_dump($datas);
?>
複製程式碼

可以看出,使用memcached 之後,可以減少資料庫連線、查詢操作,資料庫負載下來了,腳本的運作速度也提高了。之前我曾經寫過一篇名為《PHP 實作多伺服器共享SESSION 資料》文章,文中的SESSION 是使用資料庫保存的,在並發存取量大的時候,伺服器的負載會很大,經常會超出MySQL 最大連接數,利用memcached,我們可以很好地解決這個問題,工作原理如下: 當使用者造訪網頁時,查看memcached 中是否有當前使用者的SESSION 數據,使用session_id() 作為唯一標識符;如果數據存在,則直接返回,如果不存在,再進行資料庫連接,獲取SESSION 數據,並將此數據儲存到memcached 中,供下次使用; 目前的PHP 運行結束(或使用了session_write_close())時,會呼叫My_Sess::write() 方法,將資料寫入資料庫,這樣的話,每次仍會有資料庫操作,對於這個方法,也需要進行最佳化。使用全域變量,記錄使用者進入頁面時的SESSION 數據,然後在write() 方法內比較此數據與想要寫入的SESSION 數據是否相同,不同才進行資料庫連接、寫入資料庫,同時將memcached 中對應的物件刪除,如果相同的話,則表示SESSION 資料未改變,那麼就可以不做任何操作,直接回傳了;

那麼用戶 SESSION 過期時間怎麼解決呢?記得 memcached 的 add() 方法有過期時間參數 $exp 嗎?把這個參數值設定成小於 SESSION 最大存活時間即可。另外別忘了給那些一直在線的用戶延續 SESSION 時長,這個可以在 write() 方法中解決,透過判斷時間,符合條件則更新資料庫資料。

php的memcached客戶端memcached

之前在安裝memcache時有提到memcached客戶端是叫memcache,其實還有一個基於libmemcached的客戶端叫memcached,據說性能更好,功能也更多。

memcache的官方首頁:http://pecl.php.net/package/memcache memcached的官方首頁:http://pecl.php.net/package/memcached

以下是安裝Memcached版本的PHP模組的過程記錄:
  1. $mem = new Memcache;

  2. $mem->addServer($memcachehost, '11211');
  3. $mem->addServer($memcachehost, '11212');
  4. $mem->set('hx','9enjoy');
  5. echo $mem->get('hx');
  6. $md = new Memcached;

  7. $servers = array(
  8. array($memcachehost, '11211'),
  9. array($memcachehost, '11212')
  10. ) ;
  11. $md->addServers($servers);
  12. $md->set('hx','9enjoy');
  13. echo $md->get('hx');
複製程式碼

memcached的方法比memcache多不少,例如getMulti,getByKey,addServers等。 memcached沒有memcache的connect方法,目前也還不支援長連線。 memcached 支援 Binary Protocol,而 memcache 不支持,意味著 memcached 會有更高的效能。 Memcache是​​原生實作的,支援OO和非OO兩組介面並存,memcached是使用libmemcached,只支援OO介面。 更詳細的差異:http://code.google.com/p/memcached/wiki/PHPClientComparison

memcached服務端是集中式的快取系統,分散式實作方法是由客戶端決定的。 memcached的分佈演算法一般有兩種選擇: 1.根據hash(key)的結果,模連結數的餘數決定儲存到哪個節點,也就是hash(key)% sessions.size(),這個演算法簡單快速,表現良好。然而這個演算法有個缺點,就是在memcached節點增加或刪除的時候,原有的快取資料將大規模失效,命中率大受影響,如果節點數多,快取資料多,重建快取的代價太高,因此有了第二個演算法。 2、Consistent Hashing,一致性雜湊演算法,他的查找節點過程如下:

先求出memcached伺服器(節點)的雜湊值,並將其配置到0~232的圓(continuum)上。然後用同樣的方法求儲存資料的鍵的雜湊值,並映射到圓上。然後從資料映射到的位置開始順時針查找,將資料保存到找到的第一個伺服器上。如果超過2的32次方後仍然找不到伺服器,就會保存到第一台memcached伺服器上。

memcache在沒有任何配置的情況下,是使用第一種方法。 memcached要實作第一種方法,似乎是使用(未確認): $md->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC);

第二種一致性雜湊演算法: memcache在php.ini加

Memcache.hash_strategy =consistent Memcache.hash_function =crc32

memcached在程序中加(未確認)

$md->setOption(Memcached::OPT_DISTRIBUTION, Memcached::DISTRIBUTION_CONSISTENT); $md->setOption(Memcached::OPT_HASH, Memcached::HASH_CRC); 或 $mem->setOption(Memcached::OPT_DISTRIBUTION,Memcached::DISTRIBUTION_CONSISTENT); $mem->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE,true);


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn