Memcached的好处没必要多说,网上一搜一大把的,那就简单说说Memcached适合用于场合:
1、Memcached是“分布式”的内存对象缓存系统,那些不是分布式的,不需要共享的,memcached不会带来任何好处,相反还会拖慢系统效率,因为网络连接同样需要资源。
2、Memcached在很多时候都是作为数据库前端cache或者一些不重要信息的缓存。因为它比数据库少了很多SQL解析、IO操作等开销,而且它是使用内存来管理数据的,所以它可以提供比直接读取数据库更好的性能。在游戏中,访问同样的数据是很频繁的,memcached可以大大降低数据库压力,使系统执行效率提升。另外,memcached也经常作为服务器之间数据共享的存储媒介,例如游戏中的聊天数据就可以保存在memcached中,被多个服务器共享。
3、Memcached使用内存管理数据,当服务器重启,或者memcached进程中止,数据便会丢失,所以memcached不能用来持久保存数据。memcached使用内存并不会得到成百上千的读写速度提高,它的实际瓶颈在于网络连接,它和使用磁盘的数据库系统相比,好处在于没有过多的开销和直接的读写方式,它可以轻松应付非常大的数据交换量,所以经常会出现两条千兆网络带宽都满负荷了,memcached进程本身并不占用多少CPU资源的情况。
接下来说一下memcached管理工具的实现。
自定义的xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<memcached>
<pool name="sys" servers="127.0.0.1:11211" weights="3" init_conn="3" min_conn="3" max_conn="10"/> <!-- 保存系统数据 -->
<pool name="chat" servers="127.0.0.1:11211" weights="3" init_conn="3" min_conn="3" max_conn="10"/> <!-- 保存聊天数据 -->
</memcached>
</root>
管理器的实现:
public class MemCachedMgr {
// 用一个池管理memcached
private static Map<String, MemCachedClient> pools = new HashMap<String, MemCachedClient>();
/**
* 初始化MemCacheClient
* @param element
*/
private static void initPool(Element element) {
SockIOPool pool = null;
String name = element.attributeValue("name"); // 解析自定义的xml,并取得数据(代码中未实现)
String[] servers = element.attributeValue("servers").split(",");
String[] strs = element.attributeValue("weights").split(",");
Integer[] weights = new Integer[strs.length];
int initConn = Integer.parseInt(element.attributeValue("init_conn"));
int minConn = Integer.parseInt(element.attributeValue("min_conn"));
int maxConn = Integer.parseInt(element.attributeValue("max_conn"));
for (int i = 0; i < strs.length; i++) {
weights[i] = Integer.parseInt(strs[i]);
}
pool = SockIOPool.getInstance(name);
pool.setServers(servers);
pool.setWeights(weights);
pool.setFailover(true);
// 设置初始连接数、最小和最大连接数
pool.setInitConn(initConn);
pool.setMinConn(minConn);
pool.setMaxConn(maxConn);
// 设置一个连接最大空闲时间6小时
pool.setMaxIdle(1000 * 60 * 60 * 6);
// 设置主线程的睡眠时间 (5分钟)
pool.setMaintSleep(300);
// 设置TCP的参数
// 关闭nagle算法
pool.setNagle(false);
// 设置 读取 超时50 毫秒
pool.setSocketTO(50);
// 不设置连接超时
pool.setSocketConnectTO(10);
//
pool.setAliveCheck(true);
// 初始化
pool.initialize();
MemCachedClient memCachedClient = new MemCachedClient(name);
pools.put(name, memCachedClient);
}
/**
* 设置memecached
* @param poolName 连接名
* @param key 关键字
* @param value 数据
* @param minute
*/
public static void set(String poolName, String key, Object value, long time) {
try {
if (key == null || value == null || "".equals(key))
return;
// minute 为 -1时候表示时间不限
MemCachedClient memCachedClient = pools.get(poolName);
if (time == -1) {
memCachedClient.set(key, value);
} else {
// 相对时间
memCachedClient.set(key, value, new Date(time));
}
} catch (Exception e) {
}
}
/**
* 替换memecached
* @param poolName 连接名
* @param key 关键字
* @param value 数据
* @param minute
*/
public static void replace(String poolName, String key, Object value, long time) {
// minute 为 -1时候表示时间不限
MemCachedClient memCachedClient = pools.get(poolName);
if (time == -1) {
memCachedClient.replace(key, value);
} else {
// 相对时间
memCachedClient.replace(key, value, new Date(time));
}
}
/**
* 添加数据到memecached
* @param poolName 连接名
* @param key 关键字
* @param value 数据
* @param minute
*/
public static void add(String poolName, String key, Object value, long time) {
// minute 为 -1时候表示时间不限
MemCachedClient memCachedClient = pools.get(poolName);
if (time == -1) {
memCachedClient.add(key, value);
} else {
memCachedClient.add(key, value, new Date(time));
}
}
/**
* 从Memcached中取数据
* @param poolName
* @param key
* @return
*/
public static Object get(String poolName, String key) {
try {
if (key == null || "".equals(key))
return null;
// 从memcached中取得缓存的值
MemCachedClient memCachedClient = pools.get(poolName);
Object object = memCachedClient.get(key);
return object;
} catch (Exception e) {
}
return null;
}
/**
* 删除
* @param poolName
* @param key
*/
public static void delete(String poolName, String key) {
if (key == null || "".equals(key))
return;
MemCachedClient memCachedClient = pools.get(poolName);
if (memCachedClient.keyExists(key)) {
memCachedClient.delete(key);
}
}
}
这个管理工具是在我们线上服务器一直稳定运行着的,经过了真实数据的验证。