MemCache學習筆記

簡介

Memcache是一個高性能的分佈式的內存對象緩存系統,通過在內存裏維護一個統一的巨大的hash表,它能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等。簡單的說就是將數據調用到內存中,然後從內存中讀取,從而大大提高讀取速度。Memcache是danga的一個項目,最早是LiveJournal 服務的,最初爲了加速 LiveJournal 訪問速度而開發的,後來被很多大型的網站採用。Memcached是以守護程序方式運行於一個或多個服務器中,隨時會接收客戶端的連接和操作

特徵

memcached作爲高速運行的分佈式緩存服務器,具有以下的特點。

  • 協議簡單
  • 基於libevent的事件處理
  • 內置內存存儲方式
  • memcached不互相通信的分佈式

存儲方式

爲了提高性能,memcached中保存的數據都存儲在memcached內置的內存存儲空間中。由於數據僅存在於內存中,因此重啓memcached、重啓操作系統會導致全部數據消失。另外,內容容量達到指定值之後,就基於LRU(Least Recently Used)算法自動刪除不使用的緩存。memcached本身是爲緩存而設計的服務器,因此並沒有過多考慮數據的永久性問題。


適合什麼場合

隨着數據量的增大、訪問的集中,就會出現RDBMS的負擔加重、數據庫響應惡化、網站顯示延遲等重大影響。這時就該memcached大顯身手了。memcached是高性能的分佈式內存緩存服務器。一般的使用目的是,通過緩存數據庫查詢結果,減少數據庫訪問次數,以提高動態Web應用的速度、提高可擴展性。

memcached不是萬能的,它也不是適用在所有場合。

Memcached 是“分佈式”的內存對象緩存系統,那麼就是說,那些不需要“分佈”的,不需要共享的,或者乾脆規模小到只有一臺服務器的應用, memcached不會帶來任何好處,相反還會拖慢系統效率,因爲網絡連接同樣需要資源,即使是UNIX本地連接也一樣。測試數據中顯示, memcached本地讀寫速度要比直接PHP內存數組慢幾十倍,而APC、共享內存方式都和直接數組差不多。可見,如果只是本地級緩存,使用 memcached是非常不划算的。

Memcached在很多時候都是作爲數據庫前端cache使用的。因爲它比數據庫少了很多SQL解析、磁盤操作等開銷,而且它是使用內存來管理數據的,所以它可以提供比直接讀取數據庫更好的性能,在大型系統中,訪問同樣的數據是很頻繁的, memcached可以大大降低數據庫壓力,使系統執行效率提升。另外,memcached也經常作爲服務器之間數據共享的儲媒介,例如在SSO系統中保存系統單點登陸狀態的數據就可以保存在memcached中,被多個應用共享。

需要注意的是,memcached使用內存管理數據,所以它是易失的,當服務器重啓,或者memcached進程中止,數據便會丟失,所以 memcached不能用來持久保存數據。很多人的錯誤理解,memcached的性能非常好,好到了內存和硬盤的對比程度,其實memcached使用內存並不會得到成百上千的讀寫速度提高,它的實際瓶頸在於網絡連接,它和使用磁盤的數據庫系統相比,好處在於它本身非常“輕”,因爲沒有過多的開銷和直接的讀寫方式,它可以輕鬆應付非常大的數據交換量,所以經常會出現兩條千兆網絡帶寬都滿負荷了,memcached進程本身並不佔用多少CPU資源的情況。

LiveJournal.com使用了memcached在前端進行緩存,取得了良好的效果,而像wikipedia,sourceforge等也採用了或即將採用memcached作爲緩存工具。memcached可以大規模網站應用發揮巨大的作用。

工作原理

Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提供動態、數據庫驅動網站更快的運行速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護進程通信。但是它並不提供冗餘(例如,複製其hashmap條目);當某個服務器S停止運行或崩潰了,所有存放在S上的鍵/值對都將丟失。

memcached 是以守護程序方式運行於一個或多個服務器中,隨時接受客戶端的連接操作,客戶端可以由各種語言編寫,目前已知的客戶端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等客戶端在與 memcached 服務建立連接之後,接下來的事情就是存取對象了,每個被存取的對象都有一個唯一的標識符 key,存取操作均通過這個 key 進行,保存到 memcached 中的對象實際上是放置內存中的,並不是保存在 cache 文件中的,這也是爲什麼 memcached 能夠如此高效快速的原因。


安裝

  • install libevent
    $ wget http://www.monkey.org/~provos/libevent-2.0.12-stable.tar.gz
    $ tar xzvf libevent-2.0.12-stable.tar.gz
    $ cd libevent-2.0.12
    $ ./configure
    $ make
    $ sudo make install
    

    或者

    $ sudo yum install libevent libevent-devel
    
  • install memcache
    $ wget http://www.danga.com/memcached/dist/memcached-1.4.5.tar.gz
    $ tar zxf memcached-1.4.5.tar.gz
    $ cd memcached-1.2.5
    $ ./configure
    $ make
    $ sudo make install
    

    或者

    $ sudo yum install memcached
    

Now memcached is installed. You can test it:

$ memcached -m 512 -u nobody -vv

First, you start up the memcached daemon on as many spare machines as you have. The daemon has no configuration file, just a few command line options, only 3 or 4 of which you'll likely use:

$ memcached -p 11211 -u nobody -m 512 -vv

memcache服務端使用

$ memcached -d -m 2048 -l 10.0.25.8 -p 11211  -u nobody
  • -d 以守護程序(daemon)方式運行 memcached;
  • -m 設置 memcached 可以使用的內存大小,單位爲 M;
  • -l 設置監聽的 IP 地址,如果是本機的話,通常可以不設置此參數;
  • -p 設置監聽的端口,默認爲 11211,所以也可以不設置此參數;
  • -u 指定用戶,如果當前爲 root 的話,需要使用此參數指定用戶。

Java客戶端訪問

memcached-2.3.1.jar

import net.spy.memcached.MemcachedClient;
import java.io.IOException;
import java.io.Serializable;
import java.net.InetSocketAddress;
//spymemcached也自帶了幾個例子,大家可以看看
//http://code.google.com/p/spymemcached/wiki/Examples
class User implements Serializable{ //必須將對象序列化才能保存
public String userName;
public String password;
}
public class MemcachedTest {
public static void main(String[] args) throws IOException {
MemcachedClient c = new MemcachedClient(new InetSocketAddress("10.0.25.8", 11211));
//存取一個簡單的Integer
// Store a value (async) for one hour
c.set("someKey", 3600, new Integer(4));
// Retrieve a value (synchronously).
Object myObject = c.get("someKey");
Integer result = (Integer) myObject;
System.out.println(result);	
//存取一個序列化的對象	
System.out.println("存之前的時間:" + System.currentTimeMillis());		
User user1 = new User();
user1.userName = "ZhangSan";
user1.password = "alongpasswordhere";
c.set("user1", 3600, user1);		
System.out.println("取之前的時間:" + System.currentTimeMillis());		
User myUser1 = (User)(c.get("user1"));
System.out.println(myUser1.userName + " " + myUser1.password);		
System.out.println("取之後的時間:" + System.currentTimeMillis());
c.shutdown();
}
}

執行的測試結果:

4
存之前的時間:1310259282865
取之前的時間:1310259282872
ZhangSan alongpasswordhere
取之後的時間:1310259282877

注意

如果連接不上,多半是防火牆的原因

關閉防火牆
$ /etc/init.d/iptables stop

安裝問題

  • checking build system type... Invalid configuration `x86_64-unknown-linux-': machine `x86_64-unknown-linux' not recognized
    $ yum install gcc
    $ yum install gcc-c++
    $ yum install automake14


基於內存緩存的業界解決方案

基於內存緩存的真實案例

驗證工程

  • 基於Maven的Demo項目
    • 項目源代碼:cache-demo.zip
    • 項目依賴:alisoft-xplatform-asf-cache-2.5.1.jar
    • 注意alisoft-xplatform-asf-cache-2.5.1.jar是一個外部以來jar,所以用maven需要先下載到本地後,在本地安裝此jar到本地庫
      mvn install:install-file -Dfile=alisoft-xplatform-asf-cache-2.5.1.jar -DgroupId=alisoft-xplatform-asf-cache 
      -DartifactId=alisoft-xplatform-asf-cache -Dversion=2.5.1 -Dpackaging=jar
      
  • 性能測試
    • 測試準備:開啓memcached服務
      memcached -d -m 2048 -l 10.0.25.8 -p 33000  -u nobody -vv
      memcached -d -m 2048 -l 10.0.25.8 -p 33001  -u nobody -vv
      memcached -d -m 2048 -l 10.0.25.8 -p 33002  -u nobody -vv
      memcached -d -m 2048 -l 10.0.25.8 -p 33003  -u nobody -vv
      memcached -d -m 2048 -l 10.0.25.8 -p 33004  -u nobody -vv
      memcached -d -m 2048 -l 10.0.25.8 -p 33005  -u nobody -vv
      memcached -d -m 2048 -l 10.0.25.8 -p 33006  -u nobody -vv
      memcached -d -m 2048 -l 10.0.25.8 -p 33007  -u nobody -vv
      
    • cache-demo中包涵了壓力測試以及其他性能測試代碼


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章