Memcached使用心得

在项目中使用Memcached缓存数据虽然让性能提高了很多,但是在管理缓存的过程中确有很多的问题。

这在先晒下配置

memcached.properties:

memcached.host=127.0.0.1
memcached.port=11211

memcached.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.0.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">


<bean name="memcachedClientBuilder" class="net.rubyeye.xmemcached.XMemcachedClientBuilder">
<!--
XMemcachedClientBuilder have two arguments.First is server list,and
second is weights array.
-->
<constructor-arg>
<bean class="java.net.InetSocketAddress">
<constructor-arg>
<value>${memcached.host}</value>
</constructor-arg>
<constructor-arg>
<value>${memcached.port}</value>
</constructor-arg>
</bean>
</constructor-arg>
<constructor-arg>
<value>1</value>
</constructor-arg>
<property name="connectionPoolSize" value="2"></property>
<property name="commandFactory">
<bean class="net.rubyeye.xmemcached.command.TextCommandFactory"></bean>
</property>
<property name="sessionLocator">
<bean class="net.rubyeye.xmemcached.impl.KetamaMemcachedSessionLocator"></bean>
</property>
<property name="transcoder">
<bean class="net.rubyeye.xmemcached.transcoders.SerializingTranscoder" />
</property>
</bean>
<!-- Use factory bean to build memcached client -->
<bean name="memcachedClient" factory-bean="memcachedClientBuilder"
factory-method="build" destroy-method="shutdown" />
</beans>


配置就不介绍了,自己也上网上找的。主要也是主机和端口这些东西。


这里主要讲一下自己对memcached中key的管理

都知道memcached就像map<string,T>一样。

如果让自己的key不重复,让memcached中的东西不常驻内存。

这里为memcached设置了一套操作接口

package com.zhr.memcached.operat.service;


import java.util.Set;


/**
 * memcached 操作服务接口
 * 
 * @author zhr
 * 
 */
public interface IMemcachedOperatService {


/**
* 获得此操作相关的key

* @param key
* @return
* @throws Exception
*/
public String getKey(String key) throws Exception;


/**
* 取出此操作相关的所有keySet

* @return
* @throws Exception
*/
public Set<String> getKeySet() throws Exception;


/**
* 清除此操作相关的所有cache

* @throws Exception
*/
public void clearMemcached() throws Exception;


/**
* 将对象放置到memcached内,默认过期时间到一天的结束

* @param <T>
* @param key
* @param t
* @throws Exception
*/
public <T> void put2Memcached(String key, T t) throws Exception;


/**
* 将对象放置到memcached内

* @param <T>
* @param key
* @param time
*            过期时间
* @param t
* @throws Exception
*/
public <T> void put2Memcached(String key, int time, T t) throws Exception;


/**
* 从memcached内取出对象

* @param <T>
* @param key
* @return
* @throws Exception
*/
public <T> T getFMemcached(String key) throws Exception;


/**
* 删除memcached内对象

* @param key
*            key,默认是不完整的key(即通过上面的getKey()方法来获得key)
* @throws Exception
*/
public void deleteFMemcached(String key) throws Exception;


/**
* 删除memcached内对象

* @param key
*            key
* @param isComplete
*            是否完整的key
* @throws Exception
*/
public void deleteFMemcached(String key, boolean isComplete)
throws Exception;


}


工具方法DateTimeUtil.getLastSecondFromNextDay();


public static final Long SECONDOFHOUR = 60L * 60;

private static final Long MSOFHOUR = SECONDOFHOUR * 1000;

public static int getLastSecondFromNextDay() {


Long timeMillis = System.currentTimeMillis();


int lastHours = 24 - Calendar.getInstance().get(Calendar.HOUR_OF_DAY) - 1;


Long last = (MSOFHOUR + 1000 - (timeMillis + MSOFHOUR) % MSOFHOUR) / 1000;


return (int) (lastHours * SECONDOFHOUR) + last.intValue();
}


实现:

package com.zhr.memcached.operat.service.impl;
import java.util.HashSet;
import java.util.Set;
import net.rubyeye.xmemcached.MemcachedClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zhr.memcached.operat.service.IMemcachedOperatService;


@Service
public class MemcachedOperatServiceImpl implements IMemcachedOperatService {


public String MEMCACHEDKEYPREFIX = "memcached-key-";


private String sign = "";


public void setSign(String sign) {
this.sign = sign;
}


public String getSign() {
return this.sign;
}


public String getMemcachedKeyPrefix(String key) {

return this.MEMCACHEDKEYPREFIX + getSign() + key;

}

public String getMemcachedKeySet() {

return this.MEMCACHEDKEYPREFIX + getSign() + "set";

}

@Autowired
private MemcachedClient memcachedClient;

@Override
public void clearMemcached() throws Exception {

Set<String> keySet = getKeySet();

for (String string : keySet) {

memcachedClient.delete(string);

}

}

@Override
public <T> T getFMemcached(String key) throws Exception {

// System.out.println("get from memcached -----> key : " + key + " , \tvalue : " + memcachedClient.get(key));

return memcachedClient.get(key);

}

@Override
public String getKey(String key) throws Exception {

String temp_key = getMemcachedKeyPrefix(key);
//每次返回key的时候都把相关的key保存起来
addKey2Set(temp_key);

return temp_key;
}

private void addKey2Set(String tempKey) throws Exception {

Set<String> keySet = getKeySet();

keySet.add(tempKey);

saveKeySet(keySet);
}

private void saveKeySet(Set<String> keySet) throws Exception {

put2Memcached(getMemcachedKeySet(), keySet);

}

@Override
public Set<String> getKeySet() throws Exception {

Set<String> keySet = getFMemcached(getMemcachedKeySet());

if (null == keySet) {
keySet = new HashSet<String>();
}

return keySet;
}

@Override
public <T> void put2Memcached(String key, T t) throws Exception {

int time = DateTimeUtil.getLastSecondFromNextDay();

put2Memcached(key, time, t);
}

@Override
public <T> void put2Memcached(String key, int time, T t) throws Exception {
if(null != t){
memcachedClient.set(key, time, t);
}

// System.out.println("put into memcached -----> key : " + key + " ,\tvalue : " + t);

}

@Override
public void deleteFMemcached(String key) throws Exception {

memcachedClient.delete(getKey(key));

}

@Override
public void deleteFMemcached(String key, boolean isComplete)
throws Exception {


memcachedClient.delete(isComplete ? key : getKey(key));

}
}

在这里为每一个memcached操作类配置一个标志sign属性代表这个操作。如:

<bean id="merchantNameMemcachedOperatServiceImpl" class="com.zhr.memcached.operat.service.impl.MemcachedOperatServiceImpl">
<property name="sign" value="merchant-name-"/>
</bean>

在service层配置

@Autowired
@Qualifier("merchantNameMemcachedOperatServiceImpl")
private IMemcachedOperatService memcachedNameOperatService;


@Override
public String getMerchantNameByCardId(Long id) throws Exception {
return memcachedNameOperatService.getFMemcached(memcachedNameOperatService.getKey(String.valueOf(id)));
}
@Override
public void setMerchantNameByCardId(Long id, String merchant)
throws Exception {
memcachedNameOperatService.put2Memcached(memcachedNameOperatService.getKey(String.valueOf(id)), merchant);
}

@Override

public void clearMerchantNameCache(){

memcachedNameOperatService.clearMemcached();

}

@Override

public void deleteMerchantNameById(Long id){

memcachedNameOperatService.deleteFMemcached(String.valueOf(id));

}

//在一些情况下,已经知道自己要清除的key的就用这方法

@Override

public void deleteMerchantNameByKey(String key){

memcachedNameOperatService.deleteFMemcached(key,true);

}


这样就把每一个memcached的操作都缓存起来了。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值