最近一直在作一個項目的前期設計工做,考慮到後期系統的擴展和性能問題也找了不少解決方法,有一個就是用到了數據庫的緩存工具memcached(固然該工具並不只僅侷限於數據庫的緩存)。先簡單的介紹下什麼是memcached。 java
Memcached是高性能的,分佈式的內存對象緩存系統,用於在動態應用中減小數據庫負 載,提高訪問速度。Memcached由Danga Interactive開發,用於提高LiveJournal.com訪問速度的。LJ每秒動態頁面訪問量幾千次,用戶700萬。Memcached將數 據庫負載大幅度下降,更好的分配資源,更快速訪問。 web
上網baidu了不少東西,幾乎都差很少,並且基於java的說的不多,全部只有在研究了各個其餘語言類的應用後再來嘗試在java上進行簡單的操做應 用。先從memcached上進行說明,memcached的最新版是採用c語言進行開發和設計的,聽說舊版的是採用perl語言開發的,並且它是一個應 用軟件來的,是做爲緩存服務器的服務器端運行在服務器上的,須要使用特定的語言編寫客戶端與其進行通訊來進行數據的緩存和獲取。一般咱們是把 memcached安裝運行在web服務器上,而後經過對須要的數據進行緩存,據我目前所知,全部數據的緩存設置和存取操做,以及數據的更新後替換操做全 部須要程序來進行,而不是自動進行的(自動不知道能不能成功,呵呵)。下面從一個實際的例子來應用memcached。 數據庫
首先到http://danga.com/memcached/ 下 載memcached的windows版本和java客戶端jar包,目前最新版本是memcached-1.2.1-win32.zip和 java_memcached-release_1.6.zip,分別解壓後便可!首先是安裝運行memcached服務器,咱們將memcached- 1.2.1-win32.zip解壓後,進入其目錄,而後運行以下命令: windows
c:>memcached.exe -d install
c:>memcached.exe -l 127.0.0.1 -m 32 -d start 緩存
第一行是安裝memcached成爲服務,這樣才能正常運行,不然運行失敗!第一行是啓動memcached的,做爲測試咱們就簡單的只分配32M內存 了,而後監聽本機端口和以守護進行運行。執行完畢後,咱們就能夠在任務管理器中見到memcached.exe這個進程了。好了,咱們的服務器已經正常運 行了, 下面咱們就來寫java的客戶端鏈接程序。 服務器
咱們將java_memcached-release_1.6.zip解壓後的目錄中的java_memcached-release_1.6.jar文件複製到java項目的lib目錄下,而後咱們來編寫代碼,好比我提供的一個應用類以下: 分佈式
Java代碼
- package utils.cache;
-
- 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 {
- // 服務器列表和其權重
- String[] servers = {"127.0.0.1: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();
-
- // 壓縮設置,超過指定大小(單位爲K)的數據都會被壓縮
- mcc.setCompressEnable( true );
- mcc.setCompressThreshold( 64 * 1024 );
- }
-
- /**
- * 保護型構造方法,不容許實例化!
- *
- */
- 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);
- }
-
- 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
- * @return
- */
- public Object get(String key)
- {
- return mcc.get(key);
- }
-
- public static void main(String[] args)
- {
- MemCached cache = MemCached.getInstance();
- cache.add("hello", 234);
- System.out.print("get value : " + cache.get("hello"));
- }
- }
那麼咱們就能夠經過簡單的像main方法中操做的同樣存入一個變量,而後再取出進行查看,咱們能夠看到先調用了add,而後再進行get,咱們運行 一次後,234這個值已經被咱們存入了memcached的緩存中的了,咱們將main方法中紅色的那一行註釋掉後,咱們再運行仍是能夠看到get到的 value也是234,即緩存中咱們已經存在了數據了。 memcached
對基本的數據咱們能夠操做,對於普通的POJO而言,若是要進行存儲的話,那麼好比讓其實現java.io.Serializable接口,由於 memcached是一個分佈式的緩存服務器,多臺服務器間進行數據共享須要將對象序列化的,因此必須實現該接口,不然會報錯的 。好比咱們寫一個簡單的測 試Bean以下: 工具
Java代碼
- class TBean implements java.io.Serializable
- {
- private static final long serialVersionUID = 1945562032261336919L;
-
- private String name;
-
- public String getName()
- {
- return name;
- }
-
- public void setName(String name)
- {
- this.name = name;
- }
- }
而後咱們在main方法中加入以下幾行代碼: 性能
Java代碼
- TBean tb = new TBean();
- tb.setName("鐵木箱子");
- cache.add("bean", tb);
- TBean tb1 = (TBean)cache.get("bean");
- System.out.print("name=" + tb1.getName());
- tb1.setName("鐵木箱子_修改的");
- tb1 = (TBean)cache.get("bean");
- System.out.print("name=" + tb1.getName());
咱們首先把TBean的一個實例放入緩存中,而後再取出來,並進行名稱的 修改,而後咱們再取這個對象,咱們再看其名稱,發現修改的對象並非緩存中的對象,而是經過序列化過來的一個實例對象,這樣咱們就無須擔憂對原生類的無心 修改致使緩存數據失效了,呵呵~~看來我也是多此一想啊。因此這代表從緩存中獲取的對象是存入對象的一個副本,對獲取對象的修改並不能真正的修改緩存中的 數據,而應該使用其提供的replace等方法來進行修改 。
以上是我在windows下對memcached的一點小學習和實踐,在之後的項目開發過程當中將會更深刻的學習和應用這一緩存工具,也但願和有興趣的同行一塊兒討論學習該工具的使用~~