緣起: 在數據驅動的web開發中,經常要重複從數據庫中取出相同的數據,這種重複極大的增加了數據庫負載。緩存是解決這個問題的好辦法。
Memcached是什麼?
Memcached是由Danga
Interactive開發的,高性能的,分佈式的內存對象緩存系統,用於在動態應用中減少數據庫負載,提升訪問速度。
Memcached能緩存什麼?
通過在內存裏維護一個統一的巨大的hash表,Memcached能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等。
Memcached快麼?
非常快。Memcached使用了libevent(如果可以的話,在linux下使用epoll)來均衡任何數量的打開鏈接,使用非阻塞的網絡I/O,對內部對象實現引用計數(因此,針對多樣的客戶端,對象可以處在多樣的狀態),
使用自己的頁塊分配器和哈希表, 因此虛擬內存不會產生碎片並且虛擬內存分配的時間複雜度可以保證爲O(1).。
Danga
Interactive爲提升Danga
Interactive的速度研發了Memcached。目前,LiveJournal.com每天已經在向一百萬用戶提供多達兩千萬次的頁面訪問。而這些,是由一個由web服務器和數據庫服務器組成的集羣完成的。Memcached幾乎完全放棄了任何數據都從數據庫讀取的方式,同時,它還縮短了用戶查看頁面的速度、更好的資源分配方式,以及Memcache失效時對數據庫的訪問速度。
Memcached的特點
Memcached的緩存是一種分佈式的,可以讓不同主機上的多個用戶同時訪問,
因此解決了共享內存只能單機應用的侷限,更不會出現使用數據庫做類似事情的時候,磁盤開銷和阻塞的發生。
Memcached的使用
一 、Memcached服務器端的安裝 (此處將其作爲系統服務安裝)
下載文件:memcached 1.2.1
for Win32 binaries (Dec 23, 2006)
1 解壓縮文件到c:/memcached
2 命令行輸入
'c:/memcached/memcached.exe -d install'
3 命令行輸入
'c:/memcached/memcached.exe -d start' ,該命令啓動 Memcached ,默認監聽端口爲 11211
通過
memcached.exe -h 可以查看其幫助
二、客戶端使用
下載memcached java
client:http://www.whalin.com/memcached/#download
1
解壓後將java_memcached-release_2.0.1.jar jar包添加到工程的classpath中
2
利用memcached java client 一個簡單的應用
import java.util.Date;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
/**
* 使用memcached的緩存實用類.
*
* @author 鐵木箱子
*
*/
public class MemCached
{
// 創建全局的唯一實例
protected static MemCachedClient mcc = new MemCachedClient();
protected static MemCached memCached = new MemCached();
// 設置與緩存服務器的連接池
static {
// 服務器列表和其權重
String[] servers = {"192.168.124.134:11211"};
Integer[] weights = {3};
// 獲取socke連接池的實例對象
SockIOPool pool = SockIOPool.getInstance();
// 設置服務器信息
pool.setServers( servers );
pool.setWeights( weights );
// 設置初始連接數、最小和最大連接數以及最大處理時間
pool.setInitConn( 5 );
pool.setMinConn( 5 );
pool.setMaxConn( 250 );
pool.setMaxIdle( 1000 * 60 * 60 * 6 );
// 設置主線程的睡眠時間
pool.setMaintSleep( 30 );
// 設置TCP的參數,連接超時等
pool.setNagle( false );
pool.setSocketTO( 3000 );
pool.setSocketConnectTO( 0 );
// 初始化連接池
pool.initialize();
// 壓縮設置,超過指定大小(單位爲K)的數據都會被壓縮
mcc.setCompressEnable( true );
mcc.setCompressThreshold( 64 * 1024 );
}
/**
* 保護型構造方法,不允許實例化!
*
*/
protected MemCached()
{
}
/**
* 獲取唯一實例.
* @return
*/
public static MemCached getInstance()
{
return memCached;
}
/**
* 添加一個指定的值到緩存中.
* @param key
* @param value
* @return
*/
public boolean add(String key, Object value)
{
return mcc.add(key, value);
}
public boolean add(String key, Object value, Date expiry)
{
return mcc.add(key, value, expiry);
}
public boolean replace(String key, Object value)
{
return mcc.replace(key, value);
}
public boolean replace(String key, Object value, Date expiry)
{
return mcc.replace(key, value, expiry);
}
/**
* 根據指定的關鍵字獲取對象.
* @param key
* @return
*/
public Object get(String key)
{
return mcc.get(key);
}
public static void main(String[] args)
{
MemCached cache = MemCached.getInstance();
cache.add("hello", 234);
cache.add("chx", 5555);
System.out.print("get value : " + cache.get("chx"));
TBean tb = new TBean();
tb.setName("鐵木箱子");
cache.add("bean", tb);
TBean tb1 = (TBean)cache.get("bean");
System.out.print("name=" + tb1.getName());
tb1.setName("鐵木箱子_修改的");
tb1 = (TBean)cache.get("bean");
System.out.print("name=" + tb1.getName());
}
}
class TBean implements java.io.Serializable
{
/**
*
*/
private static final long serialVersionUID = 1945562032261336919L;
private String name;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}