高性能的分布式的內存對象緩存系統 Memcache 簡介

fmms 12年前發布 | 50K 次閱讀 Memcache 緩存服務器 memcached

 Memcache是一個高性能的分布式的內存對象緩存系統,通過在內存里維護一個統一的巨大的hash表,它能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等。簡單的說就是將數據調用到內存中,然后從內存中讀取,從而大大提高讀取速度。

  Memcache是danga的一個項目,最早是LiveJournal 服務的,最初為了加速 LiveJournal 訪問速度而開發的,后來被很多大型的網站采用。
  Memcached是以守護程序方式運行于一個或多個服務器中,隨時會接收客戶端的連接和操作。

MemCache接口介紹

  Memcache客戶端包含兩組接口,一組是面向過程的接口,一組是面向對象的接口,具體可以參考PHP手冊
  MemCache“LXXV. Memcache Functions” 這章。
  Memcache面向對象的常用接口包括:
  Memcache::connect -- 打開一個到Memcache的連接
  Memcache::pconnect -- 打開一個到Memcache的長連接
  Memcache::close -- 關閉一個Memcache的連接
  Memcache::set -- 保存數據到Memcache服務器上
  Memcache::get -- 提取一個保存在Memcache服務器上的數據
  Memcache::replace -- 替換一個已經存在Memcache服務器上的項目(功能類似Memcache::set)
  Memcache::delete -- 從Memcache服務器上刪除一個保存的項目
  Memcache::flush -- 刷新所有Memcache服務器上保存的項目(類似于刪除所有的保存的項目)
  Memcache::getStats -- 獲取當前Memcache服務器運行的狀態

MemCache 協議分析

  如果你不喜歡 php_memcache.dll 擴展或者服務器器目前不支持這個擴展,那么就可以考慮自己構建.
  Memcahe的客戶端,要先了解Memcache協議的交互,這樣才能開發自己的客戶端,這里簡單的分析以下Memcache的協議。(更詳細的協議內容請在Memcache服務器端的源碼的 doc/protocol.txt 文件中)
  Memcache既支持TCP協議,也支持UDP協議,不過我們這里是以TCP協議的協議作為主要考慮對象,想了解UDP協議的過程,請參考 doc/protocol.txt 文件。
  [ 錯誤指令]
  Memcache的協議的錯誤部分主要是三個錯誤提示之提示指令:
  普通錯誤信息,比如指令錯誤之類的
  ERROR\r\n
  客戶端錯誤
  CLIENT_ERROR <錯誤信息>\r\n
  服務器端錯誤
  SERVER_ERROR <錯誤信息>\r\n
  [ 數據保存指令]
  數據保存是基本的功能,就是客戶端通過命令把數據返回過來,服務器端接收后進行處理。
  指令格式:
  <命令> <鍵> <標記> <有效期> <數據長度>\r\n
  <命令> - command name
  主要是三個儲存數據的三個命令, set, add, replace
  set 命令是保存一個叫做key的數據到服務器上
  add 命令是添加一個數據到服務器,但是服務器必須這個key是不存在的,能夠保證數據不會被覆蓋
  replace 命令是替換一個已經存在的數據,如果數據不存在,就是類似set功能
  <鍵> - key
  就是保存在服務器上唯一的一個表示符,必須是跟其他的key不沖突,否則會覆蓋掉原來的數據,這個key是為了能夠準確的存取一個數據項目
  <標記> - flag
  標記是一個16位的無符號整形數據,用來設置服務器端跟客戶端一些交互的操作
  <有效期> - expiration time
  是數據在服務器上的有效期限,如果是0,則數據永遠有效,單位是秒,Memcache服務器端會把一個數據的有效
  MemCache
  期設置為當前Unix時間 設置的有效時間
  <數據長度> - bytes
  數據的長度,block data 塊數據的長度,一般在這個個長度結束以后下一行跟著block data數據內容,發送完數據以后,客戶端一般等待服務器端的返回,服務器端的返回:
  數據保存成功
  STORED\r\n
  數據保存失敗,一般是因為服務器端這個數據key已經存在了
  NOT_STORED\r\n
  [ 數據提取命令]
  從服務器端提取數據主要是使用get指令,格式是:
  get <鍵>\r\n
  <鍵>
- key
  key是是一個不為空的字符串組合,發送這個指令以后,等待服務器的返回。如果服務器端沒有任何數據,則是返回:
  END\r\n
  證明沒有不存在這個key,沒有任何數據,如果存在數據,則返回指定格式:
  VALUE <鍵> <標記> <數據長度>\r\n
  <數據塊>\r\n
  返回的數據是以VALUE開始的,后面跟著key和flags,以及數據長度,第二行跟著數據塊。
  <鍵> -key
  是發送過來指令的key內容
  <標記> - flags
  是調用set指令保存數據時候的flags標記
  <數據長度> - bytes
  是保存數據時候定位的長度
  <數據塊> - data block
  數據長度下一行就是提取的數據塊內容
  [ 數據刪除指令]
  數據刪除指令也是比較簡單的,使用get指令,格式是:
  delete <鍵> <超時時間>\r\n
  <鍵> - key
  key是你希望在服務器上刪除數據的key鍵
  <超時時間> - timeout
  按照秒為單位,這個是個可選項,如果你沒有指定這個值,那么服務器上key數據將馬上被刪除,如果設置了這個值,那么數據將在超時時間后把數據清除,該項缺省值是0,就是馬上被刪除
  刪除數據后,服務器端會返回:
  DELETED\r\n
  刪除數據成功
  NOT_FOUND\r\n
  這個key沒有在服務器上找到
  如果要刪除所有服務器上的數據,可以使用flash_all指令,格式:
  flush_all\r\n
  這個指令執行后,服務器上所有緩存的數據都被刪除,并且返回:
  OK\r\n
  這個指令一般不要輕易使,除非你卻是想把所有數據都干掉,刪除完以后可以無法恢復的。
  [其他指令]
  如果想了解當前Memcache服務器的狀態和版本等信息,可以使用狀態查詢指令和版本查詢指令。
  如果想了解當前所有Memcache服務器運行的狀態信息,可以使用stats指令,格式
  stats\r\n
  服務器將返回每行按照 STAT 開始的狀態信息,包括20行,20項左右的信息,包括守護進程的pid、版本、保存的項目數量、內存占用、最大內存限制等等信息。
  如果只是想獲取部分項目的信息,可以指定參數,格式:
  stats <參數>\r\n
  這個指令將只返回指定參數的項目狀態信息。
  如果只是想單獨了解當前版本信息,可以使用version指令,格式:
  version\r\n
  將返回以 VERSION 開頭的版本信息
  如果想結束當前連接,使用quit指令,格式:
  quit\r\n
  將斷開當前連接
  另外還有其他指令,包括incr, decr 等,我也不太了解作用,就不做介紹了,如果感興趣,可以自己去研究。

MemCache在中型網站中的應用

  使用Memcache的網站一般流量都是比較大的,為了緩解數據庫的壓力,讓Memcache作為一個緩存區域,把部分信息保存在內存中,在前端能夠迅速的進行存取。那么一般的焦點就是集中在如何分擔數據庫壓力和進行分布式,畢竟單臺Memcache的內存容量的有限的。我這里簡單提出我的個人看法,未經實踐,權當參考。
  [ 分布式應用]
  Memcache本來支持分布式,我們客戶端稍加改造,更好的支持。我們的key可以適當進行有規律的封裝,比如以user為主的網站來說,每個用戶都有User ID,那么可以按照固定的ID來進行提取和存取,比如1開頭的用戶保存在第 MemCache一臺Memcache服務器上,以2開頭的用戶的數據保存在第二胎Mecache服務器上,存取數據都先按照User ID來進行相應的轉換和存取。
  但是這個有缺點,就是需要對User ID進行判斷,如果業務不一致,或者其他類型的應用,可能不是那么合適,那么可以根據自己的實際業務來進行考慮,或者去想更合適的方法。
  [ 減少數據庫壓力]
  這個算是比較重要的,所有的數據基本上都是保存在數據庫當中的,每次頻繁的存取數據庫,導致數據庫性能極具下降,無法同時服務更多的用戶,比如MySQL,特別頻繁的鎖表,那么讓Memcache來分擔數據庫的壓力吧。我們需要一種改動比較小,并且能夠不會大規模改變前端的方式來進行改變目前的架構。

項目主頁:http://www.baiduhome.net/lib/view/home/1328604242718

 本文由用戶 fmms 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!