Memcached 的Java应用
往memcached中插入数据,以及读取数据
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,即缓存中我们已经存在了数据了。
对基本的数据我们可以操作,对于普通的POJO而言,如果要进行存储的话,那么比如让其实现java.io.Serializable接口,因为 memcached是一个分布式的缓存服务器,多台服务器间进行数据共享需要将对象序列化的,所以必须实现该接口,否则会报错的 。比如我们写一个简单的测 试Bean如下:
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方法中加入如下几行代码:
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等方法来进行修改 。
注意:memcached是以Key -Value 的方式进行数据存储的,Key的大小限制:key(max) <= 250个字符。
value在存储是有限制:value(max)<=1M;
memcached默认过期时间:ExpiresTime(max)= 30(days).通过Spring注入使用memcached Spring注入配置:
<bean id="memcachedPool" class= "com.danga.MemCached.SockIOPool" factory-method="getInstance"
init-method="initialize" destory-method="shutDowm">
<constructor-arg>
<value>neeaMemcachedPool</value>
</constructor-arg>
<property name="servers">
<list>
<value>192.168.1.233:11211</value>
</list>
</property>
<property name="initConn">
<value>20</value>
</property>
<property name="minConn">
<value>10</value>
</property>
<property name="maxConn">
<value>50</value>
</property>
<property name="mainSleep">
<value>30</value>
</property>
<property name="nagle">
<value>false</value>
</property>
<property name="socketTO">
<value>3000</value>
</property>
</bean>
<bean id="memcachedClient" class="com.danga.MemCached.MemCachedClient">
<constructor-arg>
<value>neeaMemcachedPool</value>
</constructor-arg>
<property name="compressEnable">
<value>true</value>
</property>
<property name="compressThreshold">
<value>4096</value>
</property>
</bean>