php memcached 快取機制配置架構

. 2010年1月10日 星期日
  • Agregar a Technorati
  • Agregar a Del.icio.us
  • Agregar a DiggIt!
  • Agregar a Yahoo!
  • Agregar a Google
  • Agregar a Meneame
  • Agregar a Furl
  • Agregar a Reddit
  • Agregar a Magnolia
  • Agregar a Blinklist
  • Agregar a Blogmarks
Bookmark and Share

因為工作關系,遇到某個專案,原架構是把所有圖片儲存在mysql裡,但是到流量高時,會造成mysql loading過大,讀圖速度異常的慢,思考之後決定把圖片,也cache一份在memcached裡面
原先的mysql就當備援使用,下圖為新架構的配置圖:





















1.第一次讀取時,先從mysql抓出資料,然後寫入一份到memcached,之後再讀取相同資料時,直接從memcached抓出,不透過mysql,另外在讀取資料的程式,加入304的判斷,如果內容沒有異動時,直接回傳304 Not Modified。

2.本次配置了三台memcached主機,各使用10g的空間,並搭配Consistent Hashing演算法,來達到分散式儲存的功能。

3.因為是在php4的開發環境,並沒有memcached function所以從網路上找了兩個class,一個負責處理memcached存取,一個負責Consistent Hashing演算法(演算法參考),本來是想直接使用pecl的套件,但是考慮到需另外complie,因為有風險,加上也很懶,所以就算了。

一、memcached主機安裝:
1.參考下列網址:http://blog.wu-boy.com/2007/09/22/120/

2.memcached 管理工具:
因為之前測式memcached發現有時候會突然自已掛掉,也不知道為什麼,好像都會有此問題,所以google一下,找到了deamon tools這個工具,可以監控某程序,讓它在掛掉時自動重啟。

參考網址如下:
1.安裝 deamon tools
2.設定 deamon tools for memcached

3.安裝php memcached管理工具:
此工具可以監控多台memcached目前的使用狀態。
下載位置:http://livebookmark.net/journal/2008/05/21/memcachephp-stats-like-apcphp/

下載之後放到 apache目錄下,打開檔案修改memcached server清單,加入自已的主機資訊,因為有三台,所以加了三組。
$MEMCACHE_SERVERS[] = '192.168.1.5:11211';
$MEMCACHE_SERVERS[] = '192.168.1.6:11211';
$MEMCACHE_SERVERS[] = '192.168.1.7:11211';

正常情況下會顯示如下圖:


二、memcached配置都完成後,接下來就是程式部份。
1.先include兩隻class:
include_once('ConsistentHash.class.php'); //處理演算法
include_once('MemCachedClient.class.php'); //處理memcached存取

2.判斷圖片內容是否有更新並輸出cache資料:

//快取時間三小時
$exp_time = 10800;
//因為我的讀圖程式有三個參數,分別是img=圖片名稱,width=圖片寬度,height=圖片高度
$key = sprintf("%s++%s++%s",$img,$width,$height);
$mc_key = md5($key);
$servers = array(
'192.168.1.5:11211',
'192.168.1.6:11211',
'192.168.1.7:11211'
);
$objCHash = new ConsistentHash($servers);
//利用演算法,取出該key所分配到的server是那一台
$host = $objCHash->Lookup($mc_key,1);
unset($objCHash);
//取得memcached資料
if(!empty($host)){
$mcObj = new MemCachedClient(array($host));
$mc_data = $mcObj->get($mc_key);
if(!empty($mc_data)){
$etag = md5($mc_data);
//利用header的etag判斷內容是否有異動,如果沒異動的話,就送出304 Not Modified反之就輸出memcached讀出的內容
header("Etag: $etag");
if (trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag){
header("HTTP/1.1 304 Not Modified");
exit;
}
header("Content-Type: image/jpeg");
echo $mc_data;
exit;
}
}

3.在讀出mysql資料後,同時寫入一份至memcached:
if(!empty($row)){
$mcObj->add($mc_key,$row,$exp_time);
}

三、結果:

1.從mysql connection流量圖來看,流量大約下降了三分之二。
2.firefox使用firebug來讀取圖片,時間上未加上304檢查時,時間與直接讀mysql差異不大,但是加上304判斷後,圖片讀取速度大概下降20~25%,不過還沒壓測過,等改天再用jemter壓測,再把結果po上來

1 意見:

huee11 提到...

這邊提出了一個很好的cache架構,利用memcache以及header來提升client端的瀏覽速度。