memcache 使用

轉自:[url]http://www.iteye.com/topic/264010[/url]
1 Memcache是什麼
Memcache是danga.com的一個項目,最早是爲 LiveJournal 服務的,目前全世界不少人使用這個緩存項目來構建自己大負載的網站,來分擔數據庫的壓力。

它可以應對任意多個連接,使用非阻塞的網絡IO。由於它的工作機制是在內存中開闢一塊空間,然後建立一個HashTable,Memcached自管理這些HashTable。



爲什麼會有Memcache和memcached兩種名稱?

其實Memcache是這個項目的名稱,而memcached是它服務器端的主程序文件名,



Memcache官方網站:http://www.danga.com/memcached,



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



與許多 cache 工具類似,Memcached 的原理並不複雜。它採用了C/S的模式,在 server 端啓動服務進程,在啓動時可以指定監聽的 ip,自己的端口號,所使用的內存大小等幾個關鍵參數。一旦啓動,服務就一直處於可用狀態。Memcached 的目前版本是通過C實現,採用了單進程,單線程,異步I/O,基於事件 (event_based) 的服務方式.使用 libevent 作爲事件通知實現。多個 Server 可以協同工作,但這些 Server 之間是沒有任何通訊聯繫的,每個 Server 只是對自己的數據進行管理。Client 端通過指定 Server 端的 ip 地址(通過域名應該也可以)。需要緩存的對象或數據是以 key->value 對的形式保存在Server端。key 的值通過 hash 進行轉換,根據 hash 值把 value 傳遞到對應的具體的某個 Server 上。當需要獲取對象數據時,也根據 key 進行。首先對 key 進行 hash,通過獲得的值可以確定它被保存在了哪臺 Server 上,然後再向該 Server 發出請求。Client 端只需要知道保存 hash(key) 的值在哪臺服務器上就可以了。



其實說到底,memcache 的工作就是在專門的機器的內存裏維護一張巨大的 hash 表,來存儲經常被讀寫的一些數組與文件,從而極大的提高網站的運行效率。



3 如何使用
建立Manager類
Java代碼
package com.alisoft.sme.memcached;

import java.util.Date;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

public class MemCachedManager {

// 創建全局的唯一實例
protected static MemCachedClient mcc = new MemCachedClient();

protected static MemCachedManager memCachedManager = new MemCachedManager();

// 設置與緩存服務器的連接池
static {
// 服務器列表和其權重
String[] servers = { "127.0.0.1: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 MemCachedManager() {

}

/**
* 獲取唯一實例.
*
* @return
*/
public static MemCachedManager getInstance() {
return memCachedManager;
}

/**
* 添加一個指定的值到緩存中.
*
* @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) {
MemCachedManager cache = MemCachedManager.getInstance();
cache.add("hello", 234);
System.out.print("get value : " + cache.get("hello"));
}
}

package com.alisoft.sme.memcached;

import java.util.Date;

import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

public class MemCachedManager {

// 創建全局的唯一實例
protected static MemCachedClient mcc = new MemCachedClient();

protected static MemCachedManager memCachedManager = new MemCachedManager();

// 設置與緩存服務器的連接池
static {
// 服務器列表和其權重
String[] servers = { "127.0.0.1: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 MemCachedManager() {

}

/**
* 獲取唯一實例.
*
* @return
*/
public static MemCachedManager getInstance() {
return memCachedManager;
}

/**
* 添加一個指定的值到緩存中.
*
* @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) {
MemCachedManager cache = MemCachedManager.getInstance();
cache.add("hello", 234);
System.out.print("get value : " + cache.get("hello"));
}
}
建立數據對象
Java代碼
package com.alisoft.sme.memcached;

import java.io.Serializable;

public class TBean implements Serializable {

private static final long serialVersionUID = 1945562032261336919L;

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

package com.alisoft.sme.memcached;

import java.io.Serializable;

public class TBean implements Serializable {

private static final long serialVersionUID = 1945562032261336919L;

private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
Java代碼
</SPAN></SPAN>
<PRE class=java name="code"> </PRE>
</H1>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"><SPAN lang=EN-US><SPAN><SPAN style="FONT-FAMILY: &apos"> </SPAN></SPAN></SPAN><SPAN><SPAN style="FONT-SIZE: large">創建測試用例</SPAN></SPAN></H2>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"> </H2>
<PRE class=java name="code">package com.alisoft.sme.memcached.test;

import junit.framework.TestCase;

import org.junit.Test;

import com.alisoft.sme.memcached.MemCachedManager;
import com.alisoft.sme.memcached.TBean;

public class TestMemcached extends TestCase {

private static MemCachedManager cache;

@Test
public void testCache() {

TBean tb = new TBean();
tb.setName("E網打進");
cache.add("bean", tb);

TBean tb1 = (TBean) cache.get("bean");
System.out.println("name=" + tb1.getName());
tb1.setName("E網打進_修改的");

tb1 = (TBean) cache.get("bean");
System.out.println("name=" + tb1.getName());
}

@Override
protected void setUp() throws Exception {
super.setUp();
cache = MemCachedManager.getInstance();
}

@Override
protected void tearDown() throws Exception {
super.tearDown();
cache = null;
}

}
</PRE>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"> <SPAN>測試結果</SPAN></H2>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"><SPAN>
<PRE class=java name="code">[INFO] ++++ serializing for key: bean for class: com.alisoft.sme.memcached.TBean
[INFO] ++++ memcache cmd (result code): add bean 8 0 93 (NOT_STORED)
[INFO] ++++ data not stored in cache for key: bean
[INFO] ++++ deserializing class com.alisoft.sme.memcached.TBean
name=E網打進
[INFO] ++++ deserializing class com.alisoft.sme.memcached.TBean
name=E網打進
</PRE>
</SPAN></H2>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章