(轉)java中使用memcache


背景:公司項目中使用java和memcache相結合來搭建緩存,所以要了解下緩存的基礎知識!

1 了解memcache

1.1 基礎知識

什么是Memcache?

Memcache集群環境下緩存解決方案

Memcache是一個高性能的分布式的內存對象緩存系統,通過在內存里維護一個統一的巨大的hash表,它能夠用來存儲各種格式的數據,包括圖像、視頻、文件以及數據庫檢索的結果等。簡單的說就是將數據調用到內存中,然后從內存中讀取,從而大大提高讀取速度。  

Memcache是danga的一個項目,最早是LiveJournal 服務的,最初為了加速 LiveJournal 訪問速度而開發的,后來被很多大型的網站采用。  

Memcached是以守護程序方式運行於一個或多個服務器中,隨時會接收客戶端的連接和操作

 

為什么會有Memcache和memcached兩種名稱?

其實Memcache是這個項目的名稱,而memcached是它服務器端的主程序文件名,知道我的意思了吧。一個是項目名稱,一個是主程序文件名,在網上看到了很多人不明白,於是混用了。


Memcached是高性能的,分布式的內存對象緩存系統,用於在動態應用中減少數據庫負載,提升訪問速度。Memcached由Danga Interactive開發,用於提升LiveJournal.com訪問速度的。LJ每秒動態頁面訪問量幾千次,用戶700萬。Memcached將數據庫負載大幅度降低,更好的分配資源,更快速訪問。

1.2 linux服務器使用說明

Windows下的Memcache安裝

1.  安裝

在這里簡單介紹一下Windows下的Memcache的安裝:

1. 下載memcache的windows穩定版,解壓放某個盤下面,比如在c:\memcached

2. 在終端(也即cmd命令界面)下輸入‘c:\memcached\memcached.exe -d install’安裝

3. 再輸入:‘c:\memcached\memcached.exe -d start’啟動。NOTE: 以后memcached將作為windows的一個服務每次開機時自動啟動。這樣服務器端已經安裝完畢了。

2. memcached的基本設置

-p 監聽的端口

-l 連接的IP地址, 默認是本機

-d start 啟動memcached服務

-d restart 重起memcached服務

-d stop|shutdown 關閉正在運行的memcached服務

-d install 安裝memcached服務

-d uninstall 卸載memcached服務

-u 以的身份運行 (僅在以root運行的時候有效)

-m 最大內存使用,單位MB。默認64MB

-M 內存耗盡時返回錯誤,而不是刪除項

-c 最大同時連接數,默認是1024

-f 塊大小增長因子,默認是1.25

-n 最小分配空間,key+value+flags默認是48

-h 顯示幫助

3.  設置Memcache緩存大小和端口

Memcache的默認啟動時的參數可能不滿足實際生產環境的需要,於是就想到直接修改windows服務的啟動參數,操作如下:

打開注冊表,找到:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached Server

其中的ImagePath項的值為: c:\memcached\memcached.exe" -d runservice

改成:c:\memcached\memcached.exe" -p 12345 -m 128 -d runservice

其中,-p就是端口,-m就是緩存大小,以M為單位。

linux下的Memcache安裝

1)安裝Memcache服務端

sudo apt-get install memcached

安裝完Memcache服務端以后,我們需要啟動該服務:

memcached -d -m 128 -p 11111 -u root

這里需要說明一下memcached服務的啟動參數:

-p 監聽的端口
-l 連接的IP地址, 默認是本機 -d start 啟動memcached服務 -d restart 重起memcached服務 -d stop|shutdown 關閉正在運行的memcached服務 -d install 安裝memcached服務 -d uninstall 卸載memcached服務 -u 以的身份運行 (僅在以root運行的時候有效) -m 最大內存使用,單位MB。默認64MB -M 內存耗盡時返回錯誤,而不是刪除項 -c 最大同時連接數,默認是1024 -f 塊大小增長因子,默認是1.25-n 最小分配空間,key+value+flags默認是48 -h 顯示幫助

 

查看是否建立成功

telnet測試memcached
telnet 192.168.1.2 11211

Trying 192.168.1.2...
Connected to 192.168.1.2.
Escape character is '^]'

查看版本

version

對Memcached緩存服務的狀態查詢,可以先telnet連接上服務:telnet 127.0.0.1 11211 ,然后使用 stats命令查看緩存服務的狀態,會返回如下的數據:    

     time:    1255537291                               服務器當前的unix時間戳 
        total_items:    54 從服務器啟動以后存儲的items總數量 connection_structures: 19 服務器分配的連接構造數 version: 1.2.6 memcache版本 limit_maxbytes: 67108864 分配給memcache的內存大小(字節) cmd_get: 1645 get命令(獲取)總請求次數 evictions: 0 為獲取空閑內存而刪除的items數(分配給memcache的空間用滿后需 要刪除舊的items來得到空間分配給新的items) total_connections: 19 從服務器啟動以后曾經打開過的連接數 bytes: 248723 當前服務器存儲items占用的字節數 threads: 1 當前線程數 get_misses: 82 總未命中次數 pointer_size: 32 當前操作系統的指針大小(32位系統一般是32bit) bytes_read: 490982 總讀取字節數(請求字節數) uptime: 161 服務器已經運行的秒數 curr_connections: 18 當前打開着的連接數 pid: 2816 memcache服務器的進程ID bytes_written: 16517259 總發送字節數(結果字節數) get_hits: 1563 總命中次數 cmd_set: 54 set命令(保存)總請求次數 curr_items: 28 服務器當前存儲的items數量

 

ps:windows下同樣可以。

 

Ok,安裝memcached1.4.5成功。

1.3 數據讀寫測試

一些memcache相關命令可以慢慢搜索積累。

[root@odb ~]# telnet 127.0.0.1 10000

Trying 127.0.0.1…

Connected to localhost.localdomain (127.0.0.1).

Escape character is ‘^]’.

set key 0 0 8                       <—在10000端口設置key的值

88888888

STORED

quit

Connection closed by foreign host.

 

[root@odb ~]# telnet 127.0.0.1 11211

Trying 127.0.0.1…

Connected to localhost.localdomain (127.0.0.1).

Escape character is ‘^]’.

get key                     <—在11211端口獲取key的值成功

VALUE key 0 8

88888888

END

quit

Connection closed by foreign host.

 

[root@odb ~]# telnet 127.0.0.1 11212

Trying 127.0.0.1…

Connected to localhost.localdomain (127.0.0.1).

Escape character is ‘^]’.

get key                     <—在11212端口獲取key的值成功

VALUE key 0 8

88888888

END

quit

Connection closed by foreign host.

 

2 在java中使用memcache

2.1 基本使用方法

初始化memcache:

static {  
        String[] serverlist = { "server1.com:port", "server2.com:port" }; SockIOPool pool = SockIOPool.getInstance(); pool.setServers(serverlist); pool.initialize(); } 

 

創建一個client對象:

MemCachedClient mc = new MemCachedClient();  

創建一個緩存:

MemCachedClient mc = new MemCachedClient();  
 String key = "cacheKey1"; Object value = SomeClass.getObject(); mc.set(key, value); 

通過key刪除一個緩存:

MemCachedClient mc = new MemCachedClient();  
 String key = "cacheKey1"; mc.delete(key); 

通過key獲取緩存對象:

MemCachedClient mc = new MemCachedClient();  
 String key = "key"; Object value = mc.get(key);

獲取多個緩存對象:

MemCachedClient mc = new MemCachedClient();  
 String[] keys = { "key", "key1", "key2" }; Map<Object> values = mc.getMulti(keys); 

刷新全部緩存: 

MemCachedClient mc = new MemCachedClient();  
 mc.flushAll(); 

 2.2 memcache客戶端程序

Memcached的java客戶端已經存在三種了:

  官方提供的基於傳統阻塞io由Greg Whalin維護的客戶端

  Dustin Sallings實現的基於Java nio的Spymemcached

  XMemcached

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的集成、客戶端連接池、可擴展性好等。

下面給出這三種客戶端的示例程序。

2.3 三種api的示例程序

1)     memcached client for java

從前面介紹的Java環境的Memcached客戶端程序項目網址里,下載最新版的客戶端程序包:java_memcached-release_2.5.1.zip,解壓后,文件夾里找到java_memcached-release_2.5.1.jar,這個就是客戶端的JAR包。將此JAR包添加到項目的構建路徑里,則項目中,就可以使用Memcached了。

示例代碼如下:

package temp;
 
import com.danga.MemCached.*;
import org.apache.log4j.*;
 
public class CacheTest {
    public static void main(String[] args) {
       /**
        * 初始化SockIOPool,管理memcached的連接池
        * */
       String[] servers = { "10.11.15.222:10000" };
       SockIOPool pool = SockIOPool.getInstance();
       pool.setServers(servers);
       pool.setFailover(true);
       pool.setInitConn(10);
       pool.setMinConn(5);
       pool.setMaxConn(250);
       pool.setMaintSleep(30);
       pool.setNagle(false);
       pool.setSocketTO(3000);
       pool.setAliveCheck(true);
       pool.initialize();
      
       /**
        * 建立MemcachedClient實例
        * */
       MemCachedClient memCachedClient = new MemCachedClient();
       for (int i = 0; i < 1000; i++) {
           /**
            * 將對象加入到memcached緩存
            * */
           boolean success = memCachedClient.set("" + i, "Hello!");
           /**
            * 從memcached緩存中按key值取對象
            * */
           String result = (String) memCachedClient.get("" + i);
           System.out.println(String.format("set( %d ): %s", i, success));
           System.out.println(String.format("get( %d ): %s", i, result));
       }
    }
}

2)      spymemcached

spymemcached當前版本是2.5版本,官方網址是:http://code.google.com/p/spymemcached/。可以從地址:http://spymemcached.googlecode.com/files/memcached-2.5.jar下載最新版本來使用。

示例代碼如下:

package temp;
 
import java.NET.InetSocketAddress;
import java.util.concurrent.Future;
 
import net.spy.memcached.MemcachedClient;
 
public class TestSpyMemcache {
    public static void main(String[] args) {
       // 保存對象
       try {
           /* 建立MemcachedClient 實例,並指定memcached服務的IP地址和端口號 */
           MemcachedClient mc = new MemcachedClient(new InetSocketAddress("10.11.15.222", 10000));
           Future<Boolean> b = null;
           /* 將key值,過期時間(秒)和要緩存的對象set到memcached中 */
           b = mc.set("neea:testDaF:ksIdno", 900, "someObject");
           if (b.get().booleanValue() == true) {
              mc.shutdown();
           }
       } catch (Exception ex) {
           ex.printStackTrace();
       }
       // 取得對象
        try {
           /* 建立MemcachedClient 實例,並指定memcached服務的IP地址和端口號 */
           MemcachedClient mc = new MemcachedClient(new InetSocketAddress("10.11.15.222", 10000));
           /* 按照key值從memcached中查找緩存,不存在則返回null */
           Object b = mc.get("neea:testDaF:ksIdno");
           System.out.println(b.toString());
           mc.shutdown();
       } catch (Exception ex) {
           ex.printStackTrace();
       }
    }
}

3)      xmemcached

Xmemcached的官方網址是:http://code.google.com/p/xmemcached/,可以從其官網上下載最新版本的1.2.4來使用。地址是:http://xmemcached.googlecode.com/files/xmemcached-1.2.4-src.tar.gz

示例代碼如下:

package temp;
 
import java.io.IOException;
import java.util.concurrent.TimeoutException;
 
import net.rubyeye.xmemcached.utils.AddrUtil;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.exception.MemcachedException;
 
public class TestXMemcache {
    public static void main(String[] args) {
       MemcachedClientBuilder builder = new XMemcachedClientBuilder(AddrUtil
              .getAddresses("10.11.15.222:10000"));
       MemcachedClient memcachedClient;
       try {
           memcachedClient = builder.build();
      
           memcachedClient.set("hello", 0, "Hello,xmemcached");
           String value = memcachedClient.get("hello");
           System.out.println("hello=" + value);
           memcachedClient.delete("hello");
           value = memcachedClient.get("hello");
           System.out.println("hello=" + value);
           // close memcached client
           memcachedClient.shutdown();
       } catch (MemcachedException e) {
           System.err.println("MemcachedClient operation fail");
           e.printStackTrace();
       } catch (TimeoutException e) {
           System.err.println("MemcachedClient operation timeout");
           e.printStackTrace();
       } catch (InterruptedException e) {
           // ignore
       }catch (IOException e) {
           System.err.println("Shutdown MemcachedClient fail");
           e.printStackTrace();
       }
    }
}

 


免責聲明!

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



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