程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> PHP & memcached

PHP & memcached

編輯:PHP綜合

一、memcached 簡介

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

二、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
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved