PHP Memcached應用實現代碼_php技巧

來源:互聯網
上載者:User

肖理達 (KrazyNio AT hotmail.com), 2006.04. 06, 轉載請註明出處

一、memcached 簡介

在很多場合,我們都會聽到 memcached 這個名字,但很多同學只是聽過,並沒有用過或實際瞭解過,只知道它是一個很不錯的東東。這裡簡單介紹一下,memcached 是高效、快速的分布式記憶體對象緩衝系統,主要用於加速 WEB Live App程式。

二、memcached 安裝

首先是下載 memcached 了,目前最新版本是 1.1.12,直接從官方網站即可下載到 memcached-1.1.12.tar.gz。除此之外,memcached 用到了 libevent,我下載的是 libevent-1.1a.tar.gz。

接下來是分別將 libevent-1.1a.tar.gz 和 memcached-1.1.12.tar.gz 解開包、編譯、安裝:

複製代碼 代碼如下:

# tar -xzf libevent-1.1a.tar.gz
# cd libevent-1.1a
# ./configure --prefix=/usr
# make
# make install
# cd ..
# tar -xzf memcached-1.1.12.tar.gz
# cd memcached-1.1.12
# ./configure --prefix=/usr
# make
# 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 能夠如此高效快速的原因。注意,這些對象並不是持久的,服務停止之後,裡邊的資料就會丟失。
image001.png

三、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' 的對象資料進行存取操作:

複製代碼 代碼如下:

<?php
// 包含 memcached 類檔案
require_once('memcached-client.php');
// 選項設定
$options = array(
'servers' => array('192.168.1.1:11211'), //memcached 服務的地址、連接埠,可用多個數組元素表示多個 memcached 服務
'debug' => true, //是否開啟 debug
'compress_threshold' => 10240, //超過多少位元組的資料時進行壓縮
'persistant' => false //是否使用持久串連
);
// 建立 memcached 對象執行個體
$mc = new memcached($options);
// 設定此指令碼使用的唯一識別碼
$key = 'mykey';
// 往 memcached 中寫入對象
$mc->add($key, 'some random strings');
$val = $mc->get($key);
echo "n".str_pad('$mc->add() ', 60, '_')."n";
var_dump($val);
// 替換已寫入的對象資料值
$mc->replace($key, array('some'=>'haha', 'array'=>'xxx'));
$val = $mc->get($key);
echo "n".str_pad('$mc->replace() ', 60, '_')."n";
var_dump($val);
// 刪除 memcached 中的對象
$mc->delete($key);
$val = $mc->get($key);
echo "n".str_pad('$mc->delete() ', 60, '_')."n";
var_dump($val);
?>

是不是很簡單,在實際應用中,通常會把資料庫查詢的結果集儲存到 memcached 中,下次訪問時直接從 memcached 中擷取,而不再做資料庫查詢操作,這樣可以在很大程度上減輕資料庫的負擔。通常會將 SQL 陳述式 md5() 之後的值作為唯一識別碼 key。下邊是一個利用 memcached 來快取資料庫查詢結果集的樣本(此程式碼片段緊接上邊的範例程式碼):
複製代碼 代碼如下:

<?php
$sql = 'SELECT * FROM users';
$key = md5($sql); //memcached 物件識別碼
if ( !($datas = $mc->get($key)) ) {
// 在 memcached 中未擷取到快取資料,則使用資料庫查詢擷取記錄集。
echo "n".str_pad('Read datas from MySQL.', 60, '_')."n";
$conn = mysql_connect('localhost', 'test', 'test');
mysql_select_db('test');
$result = mysql_query($sql);
while ($row = mysql_fetch_object($result))
$datas[] = $row;
// 將資料庫中擷取到的結果集資料儲存到 memcached 中,以供下次訪問時使用。
$mc->add($key, $datas);
} else {
echo "n".str_pad('Read datas from memcached.', 60, '_')."n";
}
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() 方法中解決,通過判斷時間,符合條件則更新資料庫資料。

五、相關資源

  • memcached 官方網站
  • PHP memcached client
  • 下載 memcached-client.php

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.