尊重作者辛勤勞動,轉載請注明!
(2013-3-22續)本人新用simple-spring-memcached配置在spring-mvc中,感覺非常方便,有興趣的朋友可以去看看
(2013-4-9續)本人信用spring-aop + memcached配置memcached的更新操作,存取list<bean>,更實際使用,點擊這里
(2013-4-10續 本人實現了不用數據庫臨時表的方法,見 利用Spring AOP 更新memcached 緩存策略的實現(二))
2013-4-28續 spring配置xmemcached及使用
終於把nginx+memcached+tomcat集群windows下布置完成,但是遇到java客戶端提交數據到memcached的問題,上網看了好多人的帖子,發現了3種方法
1. 三種API比較
1) memcached client for java
較早推出的memcached JAVA客戶端API,應用廣泛,運行比較穩定。
2) spymemcached
A simple, asynchronous, single-threaded memcached client written in java. 支持異步,單線程的memcached客戶端,用到了java1.5版本的concurrent和nio,存取速度會高於前者,但是穩定性不好,測試中常報timeOut等相關異常。
3) xmemcached
XMemcached 同樣是基於java nio的客戶端,java nio相比於傳統阻塞io模型來說,有效率高(特別在高並發下)和資源耗費相對較少的優點。傳統阻塞IO為了提高效率,需要創建一定數量的連接形成連接池,而nio僅需要一個連接即可(當然,nio也是可以做池化處理),相對來說減少了線程創建和切換的開銷,這一點在高並發下特別明顯。因此 XMemcached與Spymemcached在性能都非常優秀,在某些方面(存儲的數據比較小的情況下)Xmemcached比 Spymemcached的表現更為優秀,具體可以看這個Java Memcached Clients Benchmark。
2. 建議
由於memcached client for java發布了新版本,性能上有所提高,並且運行穩定,所以建議使用memcached client for java。
XMemcached 也使用得比較廣泛,而且有較詳細的中文API文檔,具有如下特點:高性能、支持完整的協議、支持客戶端分布、允許設置節點權重、動態增刪節點、支持 JMX、與Spring框架和Hibernate-memcached的集成、客戶端連接池、可擴展性好等。
我使用的是建議方法memcached client for java,
Memcached-Java-Client官網jar包的下載地址:
https://github.com/gwhalin/Memcached-Java-Client/downloads
Memcached-Java-Client的說明文檔:
https://github.com/gwhalin/Memcached-Java-Client
具體實現步驟為:
1.將jar包引入項目中,我引入了4個commons-pool-1.5.6.jar,java_memcached-release_2.6.2.jar,slf4j-api-1.6.1.jar,slf4j-simple-1.6.1.jar
2.寫測試代碼:
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 {
// 服務器列表和其權重,個人memcached地址和端口號
String[] servers = {"192.168.88.137: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();
}
/**
* 保護型構造方法,不允許實例化!
*
*/
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);
}
/**
* 替換一個指定的值到緩存中.
* @param key
* @param value
* @return
*/
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
* @param value
* @return
*/
public boolean delete(String key)
{
return mcc.delete(key);
}
/**
* 根據指定的關鍵字獲取對象.
* @param key
* @return
*/
public Object get(String key)
{
return mcc.get(key);
}
public static void main(String[] args)
{
MemCached cache = MemCached.getInstance();
//cache.add("zf", 18);
//cache.replace("zf", 19);
cache.delete("zf");
System.out.println("zf get value : " + cache.get("zf"));
}
}
3.測試階段
1)取消cache.add("zf",18)注釋,將cache.replace("zf", 19);和cache.delete("zf");注釋掉,增加zf到memcached中
2)將cache.add("zf",18);cache.replace("zf", 19);和cache.delete("zf");注釋,輸出結果為剛才添加的內容,表示該值已經存入memcached中
3) 將cache.delete("zf");取消注釋,再運行,控制台輸出 zf get value : null,該值已刪除
其他測試方法:
使用telnet命令語句查看:
1)cmd中輸入telnet 192.168.88.137 11211(自己memcached地址及端口號)
2)輸入命令stats,查看 STAT curr_items 數量,增加、修改、刪除此數量隨之變化
具體memcached輸入stats命令解釋如下:(轉載:http://www.cnblogs.com/suger/archive/2011/09/06/2168319.html)
STAT pid 1552
STAT uptime 3792
STAT time 1262517674
STAT version 1.2.6
STAT pointer_size 32
STAT curr_items 1
STAT total_items 2
STAT bytes 593
STAT curr_connections 2
STAT total_connections 28
STAT connection_structures 9
STAT cmd_get 3
STAT cmd_set 2
STAT get_hits 2
STAT get_misses 1
STAT evictions 0
STAT bytes_read 1284
STAT bytes_written 5362
STAT limit_maxbytes 67108864
STAT threads 1
END
這里顯示了很多狀態信息,下邊詳細解釋每個狀態項:
1. pid: memcached服務進程的進程ID
2. uptime: memcached服務從啟動到當前所經過的時間,單位是秒。
3. time: memcached服務器所在主機當前系統的時間,單位是秒。
4. version: memcached組件的版本。這里是我當前使用的1.2.6。
5. pointer_size:服務器所在主機操作系統的指針大小,一般為32或64.
6. curr_items:表示當前緩存中存放的所有緩存對象的數量。不包括目前已經從緩存中刪除的對象。
7. total_items:表示從memcached服務啟動到當前時間,系統存儲過的所有對象的數量,包括目前已經從緩存中刪除的對象。
8. bytes:表示系統存儲緩存對象所使用的存儲空間,單位為字節。
9. curr_connections:表示當前系統打開的連接數。
10. total_connections:表示從memcached服務啟動到當前時間,系統打開過的連接的總數。
11. connection_structures:表示從memcached服務啟動到當前時間,被服務器分配的連接結構的數量,這個解釋是協議文檔給的,具體什么意思,我目前還沒搞明白。
12. cmd_get:累積獲取數據的數量,這里是3,因為我測試過3次,第一次因為沒有序列化對象,所以獲取數據失敗,是null,后邊有2次是我用不同對象測試了2次。
13. cmd_set:累積保存數據的樹立數量,這里是2.雖然我存儲了3次,但是第一次因為沒有序列化,所以沒有保存到緩存,也就沒有記錄。
14. get_hits:表示獲取數據成功的次數。
15. get_misses:表示獲取數據失敗的次數。
16. evictions:為了給新的數據項目釋放空間,從緩存移除的緩存對象的數目。比如超過緩存大小時根據LRU算法移除的對象,以及過期的對象。
17. bytes_read:memcached服務器從網絡讀取的總的字節數。
18. bytes_written:memcached服務器發送到網絡的總的字節數。
19. limit_maxbytes:memcached服務緩存允許使用的最大字節數。這里為67108864字節,也就是是64M.與我們啟動memcached服務設置的大小一致。
20. threads:被請求的工作線程的總數量。這個解釋是協議文檔給的,具體什么意思,我目前還沒搞明白。
