A. 如何在javaweb中使用memcached
一、 概念
Memcached是danga.com(運營LiveJournal的技術團隊)開發的一套分布式內存對象緩存系統,用於在動態系統中減少資料庫負載,提升性能。
二、 適用場合
1. 分布式應用。由於memcached本身基於分布式的系統,所以尤其適合大型的分布式系統。
2. 資料庫前段緩存。資料庫常常是網站系統的瓶頸。資料庫的大並發量訪問,常常造成網站內存溢出。當然我們也可以使用hibernate的緩存機制。但memcached是基於分布式的,並可獨立於網站應用本身,所以更適合大型網站進行應用的拆分。
3. 伺服器間數據共享。舉例來講,我們將網站的登錄系統、查詢系統拆分為兩個應用,放在不同的伺服器上,並進行集群,那這個時候用戶登錄後,登錄信息如何從登錄系統伺服器同步到查詢系統伺服器呢?這時候,我們便可以使用memcached,登錄系統將登錄信息緩存起來,查詢系統便可以獲得登錄信息,就像獲取本地信息一樣。
4.代碼如下:
package com.demo.memcached;
importJava.util.Date;
import com.danga.MemCached.MemCachedClient;
import com.danga.MemCached.SockIOPool;
public class MemCached {
private static MemCachedClient cachedClient = new MemCachedClient(); // memcached客戶端單例
/**
* 初始化連接池
*/
static {
System.out.println("初始化連接池");
// 獲取連接池的實例
SockIOPool pool = SockIOPool.getInstance();
// 伺服器列表及其權重
String[] servers = { "172.20.0.196:11211"};
Integer[] weights = { 3 };
// 設置伺服器信息
pool.setServers(servers);
pool.setWeights(weights);
// 設置初始連接數、最小連接數、最大連接數、最大處理時間
pool.setInitConn(10);
pool.setMinConn(10);
pool.setMaxConn(1000);
// pool.setMaxIdle(1000 * 60 * 60);
pool.setMaxIdle(1000 * 60 * 60);
//設置主線程睡眠時間,每3秒蘇醒一次,維持連接池大小
//maintSleep 千萬不要設置成30,訪問量一大就出問題,單位是毫秒,推薦30000毫秒。
pool.setMaintSleep(30000);
//關閉套接字緩存
pool.setNagle(false);
//連接建立後的超時時間
pool.setSocketTO(3000);
//連接建立時的超時時間
pool.setSocketConnectTO(0);
// 初始化並啟動連接池
pool.initialize();
// 壓縮設置,超過指定大小的都壓縮
// cachedClient.setCompressEnable(true);
// cachedClient.setCompressThreshold(1024*1024);
}
public static boolean add(String key, Object value) {
return cachedClient.add(key, value);
}
/**
* 新增緩存數據,該KEY值如果沒有則插入
* @param key
* 鍵(key)
* @param value
* @param expire
* 過期時間(單位是秒)
*
* @return
*/
public static boolean add(String key, Object value, Integer expire) {
return cachedClient.add(key, value, expire);
}
public static boolean add(String key, Object value, Date expireDate) {
return cachedClient.add(key, value, expireDate);
}
public static boolean set(String key, Object value) {
return cachedClient.set(key, value);
}
/**
* 設置緩存中的對象(value),如果沒有則插入,如果有則修改。
* @param key
* @param value
* @param expire
* @return
*/
public static boolean set(String key, Object value, Integer expire) {
return cachedClient.set(key, value, expire);
}
/**
*
* @param key
* @param value
* @param expireDate
* 失效日期
* @return
*/
public static boolean set(String key, Object value, Date expireDate) {
return cachedClient.set(key, value, expireDate);
}
public static boolean replace(String key, Object value) {
return cachedClient.replace(key, value);
}
/**
* 該鍵的新值(new value),如果有則修改。
* @param key
* @param value
* @param expire
* @return
*/
public static boolean replace(String key, Object value, Integer expire) {
return cachedClient.replace(key, value, expire);
}
public static boolean replace(String key, Object value, Date expireDate) {
return cachedClient.replace(key, value, expireDate);
}
public static Object get(String key) {
return cachedClient.get(key);
}
/**
* 清空所有對象
*/
public static void flushAll(){
cachedClient.flushAll();
}
}
public class MemcachedTest {
public static void main(String[] agr){
// MemCached.set("mem", "12e3232", 1);
// MemCached.set("mem1", "mem1mem1");
// Date date=new Date(4000);
// MemCached.set("mem", "12e3232", date);
try{
// Thread.sleep(3000);
String mem=(String)MemCached.get("mem");
System.out.println("mem="+mem);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
B. 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>
轉載
C. 如何配置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;
}
D. memcached跟jdk版本有關系嗎
Memcached是一個開源的,C寫的分布式key-value緩存,XMemcached只是它的一個訪問客戶端。
Memcached通過網路協議跟客戶端交互,通過客戶端你才可以去使用memcached,xmemcached是它的java客戶端之一。
E. 談談redis,memcache的區別和具體應用場景
Memcached是以LiveJurnal旗下DangaInteractive公司的BardFitzpatric為首開發的高性能分布式內存緩存伺服器。其本質上就是一個內存key-value資料庫,但是不支持數據的持久化,伺服器關閉之後數據全部丟失。Memcached使用C語言開發,在大多數像Linux、BSD和Solaris等POSIX系統上,只要安裝了libevent即可使用。Memcached的客戶端軟體實現非常多,包括C/C++,PHP,Java,Python,Ruby,Perl,Erlang,Lua等。當前Memcached使用廣泛,除了LiveJournal以外還有Wikipedia、Flickr、Twitter、Youtube和WordPress等。
F. 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
G. 如何用java redis hbase
比如 MongoDB 和 CouchDB。每個數據存儲都有其優勢和劣勢,特別是當應用於特定領域時。 本期的 Java 開發 2.0 關注的是 Redis,一種輕量級鍵值對數據存儲。多數 NoSQL 實現本質上都是鍵值對,但是 Redis 支持非常豐富的值集,其中包括字元串、列表、集以及散列。因此,Redis 通常被稱為數據結構伺服器。Redis 也以異常快速而聞名,這使得它成為某一特定類型使用案例的最優選擇。 當我們想要了解一種新事物時,將其同熟知的事物進行比較可能會有所幫助,因此,我們將通過對比其與 memcached 的相似性以開啟 Redis 探索之旅。接著我們將介紹 Redis 的主要功能,這些功能可以使其在某些應用場景可以勝過 memcached。最後我將向您展示如何將 Redis 作為一個傳統數據存儲用於模型對象。Redis 和 memcached Memcached 是一個眾所周知的內存對象緩存系統,通過將目標鍵和值導入內存緩存運行。因此,Memcached 能迴避讀取磁碟時發生的 I/O 成本問題。在 Web 應用程序和資料庫之間粘貼 memcached 時會產生更好的讀取性能。因此,對於那些需要快速數據查詢的應用程序,Memcached 是一個不錯的選擇。其中的一個例子為股票查詢服務,需要另外訪問資料庫獲取相對靜態數據,如股票名稱或價格信息。 MemcacheDB 將Redis 與 memcached 相比較並不公平,它與 MemcacheDB 相比要好的多,MemcacheDB 是一個分布式鍵值對存儲系統,專為數據持久化而設計。MemcacheDB 與 Redis 較為相似,其新增優勢可以使其輕松地與 memcached 實現的客戶端進行通信。 但是memcached 也有其局限性,其中一個事實就是它所有的值均是簡單的字元串。Redis 作為 memcached 的替代者,支持更加豐富的功能集。一些基準 (benchmarks) 也表明 Redis 的速度要比 memcached 快很多。Redis 提供的豐富數據類型使其可以在內存中存儲更為復雜的數據,這是使用 memcached 無法實現的。同 memcached 不一樣,Redis 可以持久化其數據。 Redis 解決了一個重大的緩存問題,而其豐富的功能集又為其找到了其他用途。由於 Redis 能夠在磁碟上存儲數據以及跨節點復制數據,因而可以作為數據倉庫用於傳統數據模式(也就是說,您可以使用 Redis,就像使用 RDBMS 一樣)。Redis 還經常被用作隊列系統。在本用例中,Redis 是備份和工作隊列持久化存儲(利用 Redis 的列表類型)的基礎。GitHub 是以此種方法使用 Redis 的大規模基礎架構示例准備好 Redis,立即開始! 要開始使用 Redis,您需要訪問它,可以通過本地安裝或者託管供應商來實現訪問。如果您使用的 MAC,安裝過程可能就不那麼簡單。
H. 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效率高。功能強大。
I. 你使用過 Memcache 緩存嗎如果使用過,能夠簡單的描述一下它的工作原理嗎
首先 memcached 是以守護程序方式運行於一個或多個伺服器中,隨時接受客戶端的連接操作,客戶端可以由各種語言編寫,目前已知的客戶端 API 包括 Perl/PHP/Python/Ruby/Java/C#/C 等等。PHP 等客戶端在與 memcached 服務建立連接之後,接下來的事情就是存取對象了,每個被存取的對象都有一個唯一的標識符 key,存取操作均通過這個 key 進行,保存到 memcached 中的對象實際上是放置內存中的,並不是保存在 cache 文件中的,這也是為什麼PHP內存緩存技術memcached 能夠如此高效快速的原因。注意,這些對象並不是持久的,服務停止之後,里邊的數據就會丟失。