導航:首頁 > 編程語言 > memcachedjava客戶端

memcachedjava客戶端

發布時間:2023-02-11 09:23:41

① 如何配置Memcached伺服器

Windows下的Memcache安裝
1. 下載memcache的windows穩定版,解壓放某個盤下面,比如在c:\memcached
2. 在終端(也即cmd命令界面)下輸入 c:\memcached\memcached.exe -d install --安裝memcached成為服務,這樣才能正常運行,否則運行失敗!

3. 再輸入: c:\memcached\memcached.exe -d start --啟動memcached的。

以後memcached將作為windows的一個服務每次開機時自動啟動。這樣伺服器端已經安裝完畢了。

linux下的安裝:
1.下載memcached和libevent,放到 /tmp 目錄下
# cd /tmp
# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz
# wget http://www.monkey.org/~provos/libevent-1.2.tar.gz
2.先安裝libevent:
# tar zxvf libevent-1.2.tar.gz
# cd libevent-1.2
# ./configure –prefix=/usr
# make
# make install
3.測試libevent是否安裝成功:
# ls -al /usr/lib | grep libevent
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent-1.2.so.1 -> libevent-1.2.so.1.0.3
-rwxr-xr-x 1 root root 263546 11?? 12 17:38 libevent-1.2.so.1.0.3
-rw-r–r– 1 root root 454156 11?? 12 17:38 libevent.a
-rwxr-xr-x 1 root root 811 11?? 12 17:38 libevent.la
lrwxrwxrwx 1 root root 21 11?? 12 17:38 libevent.so -> libevent-1.2.so.1.0.3

4.安裝memcached,同時需要安裝中指定libevent的安裝位置:
# cd /tmp
# tar zxvf memcached-1.2.0.tar.gz
# cd memcached-1.2.0
# ./configure –with-libevent=/usr
# make
# make install
如果中間出現報錯,請仔細檢查錯誤信息,按照錯誤信息來配置或者增加相應的庫或者路徑。
安裝完成後會把memcached放到 /usr/local/bin/memcached ,
5.測試是否成功安裝memcached:
# ls -al /usr/local/bin/mem*
-rwxr-xr-x 1 root root 137986 11?? 12 17:39 /usr/local/bin/memcached
-rwxr-xr-x 1 root root 140179 11?? 12 17:39 /usr/local/bin/memcached-debug

memcached的基本設置:
1.啟動Memcache的伺服器端:
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 12000 -c 256 -P /tmp/memcached.pid
-d選項是啟動一個守護進程,
-m是分配給Memcache使用的內存數量,單位是MB,這里是10MB,
-u是運行Memcache的用戶,這里是root,
-l是監聽的伺服器IP地址,如果有多個地址的話,這里指定了伺服器的IP地址192.168.0.200,
-p是設置Memcache監聽的埠,這里設置了12000,最好是1024以上的埠,
-c選項是最大運行的並發連接數,默認是1024,這里設置了256,按照你伺服器的負載量來設定,
-P是設置保存Memcache的pid文件,這里是保存在 /tmp/memcached.pid,
2.如果要結束Memcache進程,執行:
# kill `cat /tmp/memcached.pid`
也可以啟動多個守護進程,不過埠不能重復。
3.重啟apache,service httpd restart

java的客戶端連接程序:
將java_memcached-release_1.6.zip解壓後的目錄中的java_memcached-release_2.0.jar文件復制到java項目的lib目錄下。

package utils.cache;
import java.util.Date;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;

/**
* 使用memcached的緩存實用類.
*/
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 sockIOPool = SockIOPool.getInstance();
// 設置伺服器信息
sockIOPool.setServers( servers );
sockIOPool.setWeights( weights );
// 設置初始連接數、最小和最大連接數以及最大處理時間
sockIOPool.setInitConn( 5 );
sockIOPool.setMinConn( 5 );
sockIOPool.setMaxConn( 250 );
sockIOPool.setMaxIdle( 1000 * 60 * 60 * 6 );
// 設置主線程的睡眠時間
sockIOPool.setMaintSleep( 30 );
// 設置TCP的參數,連接超時等
sockIOPool.setNagle( false );
sockIOPool.setSocketTO( 3000 );
sockIOPool.setSocketConnectTO( 0 );
//sockIOPool.setFailover(bFailover);
//sockIOPool.setAliveCheck(bAliveCheck);
// 初始化連接池
sockIOPool.initialize();
// 壓縮設置,超過指定大小(單位為K)的數據都會被壓縮
if (memCachedClient == null)
{
mcc = new MemCachedClient(sPoolName);
mcc.setCompressEnable(true);
mcc.setCompressThreshold(4096);
mcc.setPrimitiveAsString(true);
}
}
/*
<h3>基於Spring的配置,如下:</h3>
<pre>
<bean id="memCachedService" class="com.ms.memcached.MemCachedServiceImpl">
<constructor-arg index="0" value="${memcached.pool.name}" />
<constructor-arg index="1" value="${memcached.pool.servers}" />
<constructor-arg index="2" value="${memcached.pool.initConn}" />
<constructor-arg index="3" value="${memcached.pool.maxConn}" />
<constructor-arg index="4" value="${memcached.pool.minConn}" />
<constructor-arg index="5" value="${memcached.pool.socketTO}" />
<constructor-arg index="6" value="${memcached.pool.maintSleep}" />
<constructor-arg index="7" value="${memcached.pool.nagle}" />
<constructor-arg index="8" value="${memcached.pool.failover}" />
<constructor-arg index="9" value="${memcached.pool.aliveCheck}" />
</bean>
</pre>
<h3>利用com.MS.cache.properties來設置參數,如下:</h3>
<pre>
memcached.pool.name = MS
memcached.pool.servers = 192.168.9.132:12000,192.168.9.133:12000
memcached.pool.initConn = 128
memcached.pool.maxConn = 1024
memcached.pool.minConn = 20
memcached.pool.socketTO = 3000
memcached.pool.maintSleep = 30
memcached.pool.nagle = false
memcached.pool.failover = true
memcached.pool.aliveCheck = true
</pre>
*/

/**
* 保護型構造方法,不允許實例化!
*/
protected MemCached()
{

}

/**
* 獲取唯一實例.
*/
public static MemCached getInstance()
{
return memCached;
}

/**
* 添加一個指定的值到緩存中.
* @param key
* @param value
*/
//新增指定key的緩存內容,但不覆蓋已存在的內容。
public boolean add(String key, Object value)
{
return mcc.add(key, value);
}

//expiry過期時間
public boolean add(String key, Object value, Date expiry)
{
return mcc.add(key, value, expiry);
}

//新增或覆蓋指定Key的緩存內容
public boolean set(String key, Object value)
{
return mcc.set(key, value);
}

//lExpiry過期時間
public boolean set(String key, Object value, long lExpiry)
{
return mcc.set(key, value, new Date(lExpiry));
}

//根據指定的Key獲取緩存內容
public boolean get(String key)
{
return mcc.get(key);
}

//根據指定Key更新緩存內容
public boolean replace(String key, Object value)
{
return mcc.replace(key, value);
}

//lExpiry 指定的時間
public boolean replace(String key, Object value, long lExpiry)
{
return mcc.replace(key, value, new Date(lExpiry));
}
//根據指定Key刪除緩存內容
public boolean delete(String key, Object value)
{
return mcc.delete(key, value);
}

//根據指定Key在指定時間後刪除緩存內容
public boolean delete(String key, Object value, long lExpiry)
{
return mcc.delete(key, value, new Date(lExpiry));
}

//檢測Cache中當前Key是否存在
public boolean exists(String key)
{
return mcc.exists(key);
}
//根據指定一批Key批量獲取緩存內容。
/*
* @param sKeys 指定的一批Key。
* @return Object[oValue]
*/
public Object[] getMultiArray(String[] sKeys) throws ServiceException
{
return memCachedClient.getMultiArray(sKeys);
}
/**
* 根據指定一批Key批量獲取緩存內容。
*
* @param sKeys 指定的一批Key。
* @return Map<sKey, oValue>
*/
public Map<String, Object> getMulti(String[] sKeys) throws ServiceException
{
return memCachedClient.getMulti(sKeys);
}

public static void main(String[] args)
{
MemCached memCached= MemCached.getInstance();
memCached.add("hello", 234);
System.out.print("get value : " + memCached.get("hello"));
}
}

那麼我們就可以通過簡單的像main方法中操作的一樣存入一個變數,然後再取出進行查看,我們可以看到先調用了add,然後再進行get,我們運行一次 後,234這個值已經被我們存入了memcached的緩存中的了,我們將main方法中紅色的那一行注釋掉後,我們再運行還是可以看到get到的 value也是234,即緩存中我們已經存在了數據了。
對基本的數據我們可以操作,對於普通的POJO而言,如果要進行存儲的話,那麼比如讓其實現java.io.Serializable介面,因為 memcached是一個分布式的緩存伺服器,多台伺服器間進行數據共享需要將對象序列化的,所以必須實現該介面,否則會報錯的。
Entity
/**
* 獲取當前實體的緩存Id
*
* @return
*/
public String getCacheId()
{
return getCacheId(this.getClass(), sBreedId);
}

get
public Breed getBreedById(String sBreedId) throws ServiceException
{
Breed breed = (Breed)memCachedService.get(getCacheId(Breed.class, sBreedId));

if(breed == null)
{
breed = service.get("breed.getBreedById", sBreedId);

if(breed != null)
{
memCachedService.set(breed.getBreedId(), breed);
}
}

return breed;
}

save
memCachedService.set(spider.getCacheId(), breed);

update
memCachedService.replace(spider.getCacheId(), breed);

remove
memCachedService.delete(getCacheId(Spider.class, IbreedId));

memCachedService.delete(breed.getCacheId());
listAll
public List listAll() throws ServiceException
{
List breeds = new ArrayList ();

List breedIds = (List)memCachedService.get(getKeyByMap("Breed", null));

if(ObjectUtils.isEmpty(breedIds))
{
breeds = service.list("breed.getAllBreed", null);

if (!ObjectUtils.isEmpty(breeds))
{
breedIds = new ArrayList();

for (Breed breed : breeds)
{
breedIds.add(breed.getBreedId());
}

memCachedService.set(getKeyByMap("Breed", null), breedIds);
}
}
else
{
for (String sBreedId : breedIds)
{
Breed breed = getBreedById(sBreedId);

if (breed != null)
{
breeds.add(breed);
}
}
}

return breeds;
}

② 我做java的簡易聊天室,已經可以群聊和私聊,如何把創建房間加進去,且只能同一個房間里才能群聊和私聊

我說下思路:
1、客戶端創建房間時給每個房間分配惟一的一個房間ID,房間是公開的,每個連接的客戶端都可以看到,房間屬性,比如密碼,比如黑名單,房間保存在Server內存當中,如果你使用了集群,建議存儲到分布式緩存當中(Redis是最好的選擇,其次是memcached),當創建完成後,將房間信息發送給所有客戶端。新客戶端連接進來時,客戶端要主動從服務端拉取房間信息。建議採用服務端主動通知(房間增減,服務端主動通知給所有客戶端)和客戶端定時輪詢(客戶端起個定時任務,每隔一定時間主動向服務端拉取房間列表)的方式來保證房間列表的動態更新。
2、當客戶端選擇加入房間時,如果設置有加入條件,比如密碼,那就提示客戶端輸入,如果是其他條件就判斷加入客戶端是否符合這個條件。服務端保存房間同客戶端的關聯關系(可以設計成一對多,也就是一個客戶端只能在一個房間聊天,也可以設計成多對多,一個客戶端可以同時加入多個房間聊天,主要看設計),並將這個消息通知給這個房間所有的客戶端列表「歡迎***進入房間」(消息的發送者為系統,房間ID這個房間的ID,接收人無,表示是這個房間的公開消息,消息內容即:歡迎***進入房間。)
3、把聊天內容當成消息的話,那消息應該有這樣的屬性,發送人,房間ID(如果沒有房間ID就當成系統公告消息,在所有房間顯示),接收人(如果沒有指定接收人,則是公開消息,如果有接收人,就是私聊消息,只能在同一個房間私聊,那在發消息的時候要判斷下接收客戶端的是否在這個房間列表當中)。
4、再來說消息路由設置,當客戶端發送消息時,根據房間ID,找到這個這個房間內所有的客戶端列表,如果沒有指定接收人,那消息就推送給這個房間關聯的所有客戶端,如果指定有接收人,接收人不在這個房間,直接提示「***已經離開」,如果還在就把消息推送給這個指定的客戶端。
5、房間的管理:踢人,把這個客戶端從房間同客戶端關聯關系解除,並在房間顯示消息「***被踢出房間」等等

php面試題 memcache和redis的區別

Redis與Memcached的區別傳統MySQL+ Memcached架構遇到的問題實際MySQL是適合進行海量數據存儲的,通過Memcached將熱點數據載入到cache,加速訪問,很多公司都曾經使用過這樣的架構,但隨著業務數據量的不斷增加,和訪問量的持續增長,我們遇到了很多問題:1.MySQL需要不斷進行拆庫拆表,Memcached也需不斷跟著擴容,擴容和維護工作占據大量開發時間。2.Memcached與MySQL資料庫數據一致性問題。3.Memcached數據命中率低或down機,大量訪問直接穿透到DB,MySQL無法支撐。4.跨機房cache同步問題。眾多NoSQL百花齊放,如何選擇最近幾年,業界不斷涌現出很多各種各樣的NoSQL產品,那麼如何才能正確地使用好這些產品,最大化地發揮其長處,是我們需要深入研究和思考的問題,實際歸根結底最重要的是了解這些產品的定位,並且了解到每款產品的tradeoffs,在實際應用中做到揚長避短,總體上這些NoSQL主要用於解決以下幾種問題1.少量數據存儲,高速讀寫訪問。此類產品通過數據全部in-momery 的方式來保證高速訪問,同時提供數據落地的功能,實際這正是Redis最主要的適用場景。2.海量數據存儲,分布式系統支持,數據一致性保證,方便的集群節點添加/刪除。3.這方面最具代表性的是dynamo和bigtable 2篇論文所闡述的思路。前者是一個完全無中心的設計,節點之間通過gossip方式傳遞集群信息,數據保證最終一致性,後者是一個中心化的方案設計,通過類似一個分布式鎖服務來保證強一致性,數據寫入先寫內存和redo log,然後定期compat歸並到磁碟上,將隨機寫優化為順序寫,提高寫入性能。4.Schema free,auto-sharding等。比如目前常見的一些文檔資料庫都是支持schema-free的,直接存儲json格式數據,並且支持auto-sharding等功能,比如mongodb。面對這些不同類型的NoSQL產品,我們需要根據我們的業務場景選擇最合適的產品。Redis適用場景,如何正確的使用前面已經分析過,Redis最適合所有數據in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差別,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用Memcached,何時使用Redis呢?如果簡單地比較Redis與Memcached的區別,大多數都會得到以下觀點:1 Redis不僅僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。2 Redis支持數據的備份,即master-slave模式的數據備份。3 Redis支持數據的持久化,可以將內存中的數據保持在磁碟中,重啟的時候可以再次載入進行使用。拋開這些,可以深入到Redis內部構造去觀察更加本質的區別,理解Redis的設計。在Redis中,並不是所有的數據都一直存儲在內存中的。這是和Memcached相比一個最大的區別。Redis只會緩存所有的 key的信息,如果Redis發現內存的使用量超過了某一個閥值,將觸發swap的操作,Redis根據「swappability = age*log(size_in_memory)」計 算出哪些key對應的value需要swap到磁碟。然後再將這些key對應的value持久化到磁碟中,同時在內存中清除。這種特性使得Redis可以 保持超過其機器本身內存大小的數據。當然,機器本身的內存必須要能夠保持所有的key,畢竟這些數據是不會進行swap操作的。同時由於Redis將內存 中的數據swap到磁碟中的時候,提供服務的主線程和進行swap操作的子線程會共享這部分內存,所以如果更新需要swap的數據,Redis將阻塞這個 操作,直到子線程完成swap操作後才可以進行修改。使用Redis特有內存模型前後的情況對比:VM off: 300k keys, 4096 bytes values: 1.3G usedVM on: 300k keys, 4096 bytes values: 73M usedVM off: 1 million keys, 256 bytes values: 430.12M usedVM on: 1 million keys, 256 bytes values: 160.09M usedVM on: 1 million keys, values as large as you want, still: 160.09M used當 從Redis中讀取數據的時候,如果讀取的key對應的value不在內存中,那麼Redis就需要從swap文件中載入相應數據,然後再返回給請求方。 這里就存在一個I/O線程池的問題。在默認的情況下,Redis會出現阻塞,即完成所有的swap文件載入後才會相應。這種策略在客戶端的數量較小,進行 批量操作的時候比較合適。但是如果將Redis應用在一個大型的網站應用程序中,這顯然是無法滿足大並發的情況的。所以Redis運行我們設置I/O線程 池的大小,對需要從swap文件中載入相應數據的讀取請求進行並發操作,減少阻塞的時間。如果希望在海量數據的環境中使用好Redis,我相信理解Redis的內存設計和阻塞的情況是不可缺少的。補充的知識點:memcached和redis的比較1 網路IO模型Memcached是多線程,非阻塞IO復用的網路模型,分為監聽主線程和worker子線程,監聽線程監聽網路連接,接受請求後,將連接描述字pipe 傳遞給worker線程,進行讀寫IO, 網路層使用libevent封裝的事件庫,多線程模型可以發揮多核作用,但是引入了cache coherency和鎖的問題,比如,Memcached最常用的stats 命令,實際Memcached所有操作都要對這個全局變數加鎖,進行計數等工作,帶來了性能損耗。(Memcached網路IO模型)Redis使用單線程的IO復用模型,自己封裝了一個簡單的AeEvent事件處理框架,主要實現了epoll、kqueue和select,對於單純只有IO操作來說,單線程可以將速度優勢發揮到最大,但是Redis也提供了一些簡單的計算功能,比如排序、聚合等,對於這些操作,單線程模型實際會嚴重影響整體吞吐量,CPU計算過程中,整個IO調度都是被阻塞住的。2.內存管理方面Memcached使用預分配的內存池的方式,使用slab和大小不同的chunk來管理內存,Item根據大小選擇合適的chunk存儲,內存池的方式可以省去申請/釋放內存的開銷,並且能減小內存碎片產生,但這種方式也會帶來一定程度上的空間浪費,並且在內存仍然有很大空間時,新的數據也可能會被剔除,原因可以參考Timyang的文章:/memcached/)。Memcached的客戶端軟體實現非常多,包括C/C++, PHP, Java, Python, Ruby, Perl, Erlang, Lua等。當前Memcached使用廣泛,除了LiveJournal以外還有Wikipedia、Flickr、Twitter、Youtube和WordPress等。在Window系統下,Memcached的安裝非常方便,只需從以上給出的地址下載可執行軟體然後運行memcached.exe –d install即可完成安裝。在Linux等系統下,我們首先需要安裝libevent,然後從獲取源碼,make && make install即可。默認情況下,Memcached的伺服器啟動程序會安裝到/usr/local/bin目錄下。在啟動Memcached時,我們可以為其配置不同的啟動參數。1.1 Memcache配置Memcached伺服器在啟動時需要對關鍵的參數進行配置,下面我們就看一看Memcached在啟動時需要設定哪些關鍵參數以及這些參數的作用。1)-p Memcached的TCP監聽埠,預設配置為11211;2)-U Memcached的UDP監聽埠,預設配置為11211,為0時表示關閉UDP監聽;3)-s Memcached監聽的UNIX套接字路徑;4)-a 訪問UNIX套接字的八進制掩碼,預設配置為0700;5)-l 監聽的伺服器IP地址,默認為所有網卡;6)-d 為Memcached伺服器啟動守護進程;7)-r 最大core文件大小;8)-u 運行Memcached的用戶,如果當前為root的話需要使用此參數指定用戶;9)-m 分配給Memcached使用的內存數量,單位是MB;10)-M 指示Memcached在內存用光的時候返回錯誤而不是使用LRU演算法移除數據記錄;11)-c 最大並發連數,預設配置為1024;12)-v –vv –vvv 設定伺服器端列印的消息的詳細程度,其中-v僅列印錯誤和警告信息,-vv在-v的基礎上還會列印客戶端的命令和相應,-vvv在-vv的基礎上還會列印內存狀態轉換信息;13)-f 用於設置chunk大小的遞增因子;14)-n 最小的chunk大小,預設配置為48個位元組;15)-t Memcached伺服器使用的線程數,預設配置為4個;16)-L 嘗試使用大內存頁;17)-R 每個事件的最大請求數,預設配置為20個;18)-C 禁用CAS,CAS模式會帶來8個位元組的冗餘;2. Redis簡介Redis是一個開源的key-value存儲系統。與Memcached類似,Redis將大部分數據存儲在內存中,支持的數據類型包括:字元串、哈希表、鏈表、集合、有序集合以及基於這些數據類型的相關操作。Redis使用C語言開發,在大多數像Linux、BSD和Solaris等POSIX系統上無需任何外部依賴就可以使用。Redis支持的客戶端語言也非常豐富,常用的計算機語言如C、C#、C++、Object-C、PHP、Python、Java、Perl、Lua、Erlang等均有可用的客戶端來訪問Redis伺服器。當前Redis的應用已經非常廣泛,國內像新浪、淘寶,國外像Flickr、Github等均在使用Redis的緩存服務。Redis的安裝非常方便,只需從bin目錄下。在啟動Redis伺服器時,我們需要為其指定一個配置文件,預設情況下配置文件在Redis的源碼目錄下,文件名為redis.conf。php面試題 memcache和redis的區別

④ memcached和ecache的區別

Ehcache是純Java編寫的,通信是通過RMI方式,適用於基於Java技術的項目。MemCached伺服器端是C編寫的,客戶端有多個語言實現,如C,PHP(淘寶,sina等各大門戶網站),Python(豆瓣網), Java(Xmemcached,spymemcached)。MemcaChed伺服器端是使用文本或者二進制通信的。
分布式:MemcaChed不完全。集群默認不實現,Ehcache支持。
集群:MemcaChed可通過客戶端實現。Ehcache支持(默認是非同步同步)。
持久化:MemcaChed可通過第三方應用實現,如sina研發的memcachedb,將cache的數據保存到[url=]Berkerly DB[/url]。Ehcache支持。持久化到本地硬碟,生成一個.data和.index文件。cache初始化時會自動查找這兩個文件,將數據放入cache。
效率:MemcaChed高。Ehcache高於Memcache。
容災:MemcaChed可通過客戶端實現。Ehcache支持。
緩存數據方式:MemcaChed緩存在MemCached server向系統申請的內存中。Ehcache可以緩存在內存(JVM中),也可以緩存在硬碟。通過CacheManager管理cache。多個CacheManager可配置在一個JVM內,CacheManager可管理多個cache。
緩存過期移除策略:MemcaChed是LRU。Ehcache是LRU(默認),FIFO,LFU。
缺點:MemcaChed功能不完善,相對於Ehcache效率低。Ehcache只適用於java體系,只能用java編寫客戶端。
優點:MemcaChed簡潔,靈活,所有支持socket的語言都能編寫其客戶端。Ehcache效率高。功能強大。

⑤ Memcached 在 Spring 里怎麼用

本文將對在Java環境下Memcached應用進行詳細介紹。Memcached主要是集群環境下的緩存解決方案,可以運行在Java或者.NET平台上,這里我們主要講的是Windows下的Memcached應用。

這些天在設計SNA的架構,接觸了一些遠程緩存、集群、session復制等的東西,以前做企業應用的時候感覺作用不大,現在設計面對internet的系統架構時就非常有用了,而且在調試後看到壓力測試的情況還是比較好的。

在緩存的選擇上有過很多的思考,雖然說memcached結合java在序列化上性能不怎麼樣,不過也沒有更好的集群環境下的緩存解決方案了,就選擇了memcached。本來計劃等公司買的伺服器到位裝個linux再來研究memcached,但這兩天在找到了一個windows下的Memcached版本,就動手開始調整現有的框架了。

Windows下的Server端很簡單,不用安裝,雙擊運行後默認服務埠是11211,沒有試著去更改埠,因為反正以後會用Unix版本,到時再記錄安裝步驟。下載客戶端的JavaAPI包,介面非常簡單,參考API手冊上就有現成的例子。

目標,對舊框架緩存部分進行改造:

1、緩存工具類

2、hibernate的provider

3、用緩存實現session機制

今天先研究研究緩存工具類的改造,在舊框架中部分函數用了ehcache對執行結果進行了緩存處理,現在目標是提供一個緩存工具類,在配置文件中配置使用哪種緩存(memcached或ehcached),使其它程序對具體的緩存不依賴,同時使用AOP方式來對方法執行結果進行緩存。

首先是工具類的實現:

在Spring中配置
Java代碼

<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>classpath:ehcache.xmlvalue>
property>
bean>

<bean id="localCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
<property name="cacheName"
value="×××.cache.LOCAL_CACHE" />
bean>

<bean id="cacheService"
class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">
<property name="cacheServerList" value="${cache.servers}"/>
<property name="cacheServerWeights" value="${cache.cacheServerWeights}"/>
<property name="cacheCluster" value="${cache.cluster}"/>
<property name="localCache" ref="localCache"/>
bean>

<bean id="cacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>classpath:ehcache.xmlvalue>
property>
bean>
<bean id="localCache"
class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager" ref="cacheManager" />
<property name="cacheName"
value="×××.cache.LOCAL_CACHE" />
bean>

<bean id="cacheService"
class="×××.core.cache.CacheService" init-method="init" destroy-method="destory">
<property name="cacheServerList" value="${cache.servers}"/>
<property name="cacheServerWeights" value="${cache.cacheServerWeights}"/>
<property name="cacheCluster" value="${cache.cluster}"/>
<property name="localCache" ref="localCache"/>
bean>
在properties文件中配置${cache.servers} ${cache.cacheServerWeights} ${cache.cluster}

具體工具類的代碼

Java代碼
/**
* @author Marc
*
*/
public class CacheService {
private Log logger = LogFactory.getLog(getClass());
private Cache localCache;
String cacheServerList;
String cacheServerWeights;
boolean cacheCluster = false;
int initialConnections = 10;
int minSpareConnections = 5;
int maxSpareConnections = 50;
long maxIdleTime = 1000 * 60 * 30; // 30 minutes
long maxBusyTime = 1000 * 60 * 5; // 5 minutes
long maintThreadSleep = 1000 * 5; // 5 seconds
int socketTimeOut = 1000 * 3; // 3 seconds to block on reads
int socketConnectTO = 1000 * 3; // 3 seconds to block on initial
// connections. If 0, then will use blocking
// connect (default)
boolean failover = false; // turn off auto-failover in event of server
// down
boolean nagleAlg = false; // turn off Nagle's algorithm on all sockets in
// pool
MemCachedClient mc;
public CacheService(){
mc = new MemCachedClient();
mc.setCompressEnable(false);
}
/**
* 放入
*
*/
public void put(String key, Object obj) {
Assert.hasText(key);
Assert.notNull(obj);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.set(key, obj);
} else {
Element element = new Element(key, (Serializable) obj);
localCache.put(element);
}
}
/**
* 刪除
*/
public void remove(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.delete(key);
}else{
localCache.remove(key);
}
}
/**
* 得到
*/
public Object get(String key) {
Assert.hasText(key);
Assert.notNull(localCache);
Object rt = null;
if (this.cacheCluster) {
rt = mc.get(key);
} else {
Element element = null;
try {
element = localCache.get(key);
} catch (CacheException cacheException) {
throw new DataRetrievalFailureException("Cache failure: "
+ cacheException.getMessage());
}
if(element != null)
rt = element.getValue();
}
return rt;
}
/**
* 判斷是否存在
*
*/
public boolean exist(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
return mc.keyExists(key);
}else{
return this.localCache.isKeyInCache(key);
}
}
private void init() {
if (this.cacheCluster) {
String[] serverlist = cacheServerList.split(",");
Integer[] weights = this.split(cacheServerWeights);
// initialize the pool for memcache servers
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(serverlist);
pool.setWeights(weights);
pool.setInitConn(initialConnections);
pool.setMinConn(minSpareConnections);
pool.setMaxConn(maxSpareConnections);
pool.setMaxIdle(maxIdleTime);
pool.setMaxBusyTime(maxBusyTime);
pool.setMaintSleep(maintThreadSleep);
pool.setSocketTO(socketTimeOut);
pool.setSocketConnectTO(socketConnectTO);
pool.setNagle(nagleAlg);
pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);
pool.initialize();
logger.info("初始化memcached pool!");
}
}

private void destory() {
if (this.cacheCluster) {
SockIOPool.getInstance().shutDown();
}
}
}
/**
* @author Marc
*
*/
public class CacheService {
private Log logger = LogFactory.getLog(getClass());
private Cache localCache;
String cacheServerList;
String cacheServerWeights;
boolean cacheCluster = false;
int initialConnections = 10;
int minSpareConnections = 5;
int maxSpareConnections = 50;
long maxIdleTime = 1000 * 60 * 30; // 30 minutes
long maxBusyTime = 1000 * 60 * 5; // 5 minutes
long maintThreadSleep = 1000 * 5; // 5 seconds
int socketTimeOut = 1000 * 3; // 3 seconds to block on reads
int socketConnectTO = 1000 * 3; // 3 seconds to block on initial
// connections. If 0, then will use blocking
// connect (default)
boolean failover = false; // turn off auto-failover in event of server
// down
boolean nagleAlg = false; // turn off Nagle's algorithm on all sockets in
// pool
MemCachedClient mc;
public CacheService(){
mc = new MemCachedClient();
mc.setCompressEnable(false);
}
/**
* 放入
*
*/
public void put(String key, Object obj) {
Assert.hasText(key);
Assert.notNull(obj);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.set(key, obj);
} else {
Element element = new Element(key, (Serializable) obj);
localCache.put(element);
}
}
/**
* 刪除
*/
public void remove(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
mc.delete(key);
}else{
localCache.remove(key);
}
}
/**
* 得到
*/
public Object get(String key) {
Assert.hasText(key);
Assert.notNull(localCache);
Object rt = null;
if (this.cacheCluster) {
rt = mc.get(key);
} else {
Element element = null;
try {
element = localCache.get(key);
} catch (CacheException cacheException) {
throw new DataRetrievalFailureException("Cache failure: "
+ cacheException.getMessage());
}
if(element != null)
rt = element.getValue();
}
return rt;
}
/**
* 判斷是否存在
*
*/
public boolean exist(String key){
Assert.hasText(key);
Assert.notNull(localCache);
if (this.cacheCluster) {
return mc.keyExists(key);
}else{
return this.localCache.isKeyInCache(key);
}
}
private void init() {
if (this.cacheCluster) {
String[] serverlist = cacheServerList.split(",");
Integer[] weights = this.split(cacheServerWeights);
// initialize the pool for memcache servers
SockIOPool pool = SockIOPool.getInstance();
pool.setServers(serverlist);
pool.setWeights(weights);
pool.setInitConn(initialConnections);
pool.setMinConn(minSpareConnections);
pool.setMaxConn(maxSpareConnections);
pool.setMaxIdle(maxIdleTime);
pool.setMaxBusyTime(maxBusyTime);
pool.setMaintSleep(maintThreadSleep);
pool.setSocketTO(socketTimeOut);
pool.setSocketConnectTO(socketConnectTO);
pool.setNagle(nagleAlg);
pool.setHashingAlg(SockIOPool.NEW_COMPAT_HASH);
pool.initialize();
logger.info("初始化memcachedpool!");
}
}
private void destory() {
if (this.cacheCluster) {
SockIOPool.getInstance().shutDown();
}
}
}
然後實現函數的AOP攔截類,用來在函數執行前返回緩存內容

Java代碼
public class CachingInterceptor implements MethodInterceptor {

private CacheService cacheService;
private String cacheKey;

public void setCacheKey(String cacheKey) {
this.cacheKey = cacheKey;
}

public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}

public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = cacheService.get(cacheKey);
//如果函數返回結果不在Cache中,執行函數並將結果放入Cache
if (result == null) {
result = invocation.proceed();
cacheService.put(cacheKey,result);
}
return result;
}
}
public class CachingInterceptor implements MethodInterceptor {

private CacheService cacheService;
private String cacheKey;

public void setCacheKey(String cacheKey) {
this.cacheKey = cacheKey;
}

public void setCacheService(CacheService cacheService) {
this.cacheService = cacheService;
}

public Object invoke(MethodInvocation invocation) throws Throwable {
Object result = cacheService.get(cacheKey);
//如果函數返回結果不在Cache中,執行函數並將結果放入Cache
if (result == null) {
result = invocation.proceed();
cacheService.put(cacheKey,result);
}
return result;
}
}
Spring的AOP配置如下:

Java代碼

<aop:config proxy-target-class="true">
<aop:advisor
pointcut="execution(* ×××.PoiService.getOne(..))"
advice-ref="PoiServiceCachingAdvice" />
aop:config>

<bean id="BasPoiServiceCachingAdvice"
class="×××.core.cache.CachingInterceptor">
<property name="cacheKey" value="PoiService" />
<property name="cacheService" ref="cacheService" />
bean>
轉載

⑥ java中memcache怎麼用

1. memcached client for java客戶端API:memcached client for java

引入jar包:java-memcached-2.6.2.jar

package com.pcitc.memcached;

import com.danga.MemCached.*;

public class TestMemcached {
public static void main(String[] args) {
/* 初始化SockIOPool,管理memcached的連接池 */
String[] servers = { "192.168.1.111:11211" };
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 < 10; 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客戶端API:spymemcached client

引入jar包:spymemcached-2.10.3.jar

package com.pcitc.memcached;

import java.net.InetSocketAddress;
import java.util.concurrent.Future;

import net.spy.memcached.MemcachedClient;

public class MClient {

public static void main(String[] args) {
setValue();
getValue();
}

// 用spymemcached將對象存入緩存
public static void setValue() {
try {
/* 建立MemcachedClient 實例,並指定memcached服務的IP地址和埠號 */
MemcachedClient mc = new MemcachedClient(new InetSocketAddress(
"192.168.1.111", 11211));
Future<Boolean> b = null;
/* 將key值,過期時間(秒)和要緩存的對象set到memcached中 */
b = mc.set("neead", 900, "someObject");
if (b.get().booleanValue() == true) {
mc.shutdown();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}

// 用spymemcached從緩存中取得對象
public static void getValue() {
try {
/* 建立MemcachedClient 實例,並指定memcached服務的IP地址和埠號 */
MemcachedClient mc = new MemcachedClient(new InetSocketAddress(
"192.168.1.111", 11211));
/* 按照key值從memcached中查找緩存,不存在則返回null */
Object b = mc.get("neead");
mc.shutdown();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}

3.兩種API比較
memcached client for java:較早推出的memcached JAVA客戶端API,應用廣泛,運行比較穩定。
spymemcached:A simple, asynchronous, single-threaded memcached client written in java. 支持非同步,單線程的memcached客戶端,用到了java1.5版本的concurrent和nio,存取速度會高於前者,但是穩定性不好,測試中常報timeOut等相關異常。
由於memcached client for java發布了新版本,性能上有所提高,並且運行穩定,所以建議使用memcached client for java

⑦ 怎樣用MemCached存儲自己創建的對象

各種監控設備開啟時候需要進行注冊(就像手機開機時總是要找個基站注冊一樣,或類似互聯網站的登錄操作),設備數量為千至萬的級別,他們注冊到不同的「基站」中,由基站再統一連接到中心伺服器上(java程序,協議為http based,多台集群布屬)。注冊要牽扯到不少表/對象,不僅僅只是設備對象,而且系統要求設備注冊要非常快。設備運行時,總是不時會發生各種安全報警、故障報警、狀態報警發送到「基站」,由「基站」轉發到中控伺服器。發生報警時候,若有預設預案,則設備按照該預案執行響應。預案是操作員事前在中控伺服器上定製,在設備注冊時返回給設備的。還有一部分操作員,就是整天盯著監控客戶端,實時人工處理警報,同時他們還會處理一些小量請求,比如偶爾調整一下設備基本信息(如GIS信息),增加一個設備,增加一個用戶,注釋一下各種報警事件等等。

閱讀全文

與memcachedjava客戶端相關的資料

熱點內容
time庫中的clock函數python 瀏覽:987
cad視覺移動命令怎麼打開 瀏覽:819
安卓java調用python 瀏覽:395
java標准時間 瀏覽:137
華為伺服器湖北渠道商雲主機 瀏覽:30
韓式面部護理解壓視頻 瀏覽:301
pdf換成jpg圖片 瀏覽:897
dh加密演算法 瀏覽:107
安卓手機如何隱藏微信信息提示 瀏覽:632
nodejs解壓縮 瀏覽:262
直流雙轉子壓縮機 瀏覽:952
pythonxmlstring 瀏覽:822
用私鑰加密之後可以用公鑰解密 瀏覽:788
ug如何啟動伺服器 瀏覽:444
csgo防抖動命令 瀏覽:960
如何弄到手機app頁面的源碼 瀏覽:441
androidwindows7破解版 瀏覽:363
解壓視頻動畫怎麼拍 瀏覽:748
連漲啟動源碼 瀏覽:163
小奔運動app網路異常怎麼回事 瀏覽:449