尊重作者辛勤勞動,轉載請注明!
(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:被請求的工作線程的總數量。這個解釋是協議文檔給的,具體什么意思,我目前還沒搞明白。