java客戶端提交數據到memcached方法memcached+java+client個人總結


尊重作者辛勤勞動,轉載請注明!

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM