一.基本原理
Memcached是一種分佈式數據緩存技術,其基本原理是預先分配合理適當的內存空間,保存數據時根據保存Key的哈希碼除模取餘數的方法來選擇分佈式網絡中的一臺服務器保存數據。當需要查詢數據時候使用同樣的算法來取值。同JBoss Cache或EHCache比較,個人認爲有如下有點:
(1)。配置使用簡單,沒有JBoss Cache,EHCache配置那樣複雜,特別是相對於JbossCache來說,不需要配置複雜的JGoss TCP和UTP通訊;它只需要簡單地給出多個服務器的IP地址就可以了。
(2)。可以異步查詢或保存根據數據;也可以同步執行,這一步是由spymemcached來完成,其主要原理是使用了JDK5的java.util.concurrent包下的相關技術到達異步執行;
二.實驗:
(1)安裝Memcached服務端;
(2)啓動Memcached服務端:
(3)查詢MemCached服務端信息:
再輸入:
Stats Slabs
得到如下:
(3)下載spymemcached客戶端jar包,建立一個工程:
源碼包:
本測試的做法是使用多個線程同時使用HttpClient去請求{ "http://www.sina.com/",
"http://www.yahoo.com/", "http://www.sohu.com/" };中的任意隨機一個,Memcached緩衝時間爲12秒。
初始化服務端:本機測試
String[] servers = { "127.0.0.1:11211" };
Integer[] weights = { 3 };
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(servers);
pool.setWeights(weights);
設置最小最大初始Memcached連接線程大小
pool.setInitConn(5);
pool.setMinConn(5);
pool.setMaxConn(250);
//線程空閒時間
pool.setMaxIdle(1000 * 60 * 60 * 6);
pool.setMaintSleep(30);
pool.setNagle(false);
pool.setSocketTO(3000);
pool.setSocketConnectTO(0);
pool.initialize();
//啓用壓縮緩衝
mcc.setCompressEnable(true);
mcc.setCompressThreshold(64 * 1024);
pool.initialize();
//啓用壓縮緩衝
mcc.setCompressEnable(true);
mcc.setCompressThreshold(64 * 1024);
測試的主函數:
TestCached tt = new TestCached();
每次一百個線程,每個線程連續50個Http請求
int count = 100;
//不使用緩衝請求,false表示非false
MemCachedThread r = new MemCachedThread(tt, false);
long begin = System.currentTimeMillis();
Thread[] ths = new Thread[count];
for (int i = 0; i < count; i++)
{
ths = new Thread(r);
ths.start();
}
等待所有的線程執行完畢統計時間
for (int i = 0; i < count; i++)
{
ths.join();
}
long end = System.currentTimeMillis();
long f = (end - begin) / 1000;
//先清除MemCached服務端對應值,這一部及時是多餘,我們還沒有緩衝
for (int i = 0; i < urls.length; i++)
{
mcc.delete(urls);
}
//使用緩衝請求,true表示使用緩衝
tt.time = 0;
r = new MemCachedThread(tt, true);
begin = System.currentTimeMillis();
ths = new Thread[count];
for (int i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
ths.join();
}
end = System.currentTimeMillis();
System.out.println("沒有使用MemCached緩衝機制時間 time is -------: " + f);
System.out.println("使用MemCached緩衝機制時間 time is -------: " + (end - begin)
/ 1000);
public class MemCachedThread implements Runnable {
TestCached tt;
boolean useCahced;
public void run() {
if(!useCahced)
{
for(int i=0;i<50;i++)
{
tt.unUseCahceOutput();
}
}
else
{
for(int i=0;i<50;i++)
{
tt.useCahceOutput();
}
}
}
保存緩衝,每個url和對應值保存時間
public void bulidCache(String key, String response)
{
mcc.set(key, response, new Date(12000));
}
使用緩衝,從緩衝先得到數據,如果沒有則http請求。得到之後保存
public void useCahceOutput()
{
String url = urls[rd.nextInt(urls.length)];
String response = (String) mcc.get(url);
if (response == null)
{
bulidCache(url, httpConnect(url));
}
output();
}
10個線程,每個線程10個隨機請求測試結果:
50個線程,每個線程10個隨機請求測試結果:
100個線程,每個線程10個隨機請求測試結果:
200個線程,每個線程10個隨機請求測試結果,這時內存溢出。
解決辦法,修改Eclipse啓動參數:
--launcher.XXMaxPermSize
256m
-vmargs
-Xms40m
-Xmx256m
緩衝優化方法:
(1)適當提高服務器連接數:pool.setMaxConn();
(2)改變Memcached服務端緩衝啓動大小: Memcached .exe –m 128 默認64
總結:
通過Memcached緩存數據查詢結果,減少數據庫等訪問次數,以提高動態Web應用的速度、提高可擴展性。