MemCached



MemCached

什么是MemCached?

MemCached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。

 

工作机制(原理)?

通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap来实现的。

注:MemCached可以这样理解:将数据放进缓存,然后开始从缓存中取出,如果发现所提供的Key没有命中,那么就很直白的告诉你,你这个key没有任何对应的东西在缓存里,去数据库或者其它方取;当你在外部数据源取到的时候,可以直接将数据置入到Cache中,这样下次就可以命中了。

 

MemCached的使用?

要在Java中使用MemCached技术需要以下几个jar文件:

· alisoft-xplatform-asf-cache-2.5.1.jar

· commons-logging.jar

· log4j-1.2.15.jar

同时还需要一个服务器软件:memcached-1.2.1-win32.zip

在测试时,必须首先运行服务器软件,将该服务器启动。

 

现在开始在编写测试程序,其原理是利用JDBC技术将数据从数据库中查询出来,再将查询出来的数据利用MemCached技术放入到缓存中,以便下次使用时不再与数据可直接交互,提高软件性能。

 

首先,创建一个Web Project工程,将以上三个jar文件加入到Webroot目录下的WEB-INF文件夹下的lib文件夹下;

其次,依次创建实体类、数据库访问类和查询类;如下:

实体类 User.java,该类必须实现序列化,代码如下:

package cn.cheng.entity;

 

import java.io.Serializable;

 

public class User implements Serializable {

/**

* 序列号

*/

private static final long serialVersionUID = -3896605600471191953L;

private int uid;

private String uname;

private String upass;

 

public int getUid() {

return uid;

}

public void setUid(int uid) {

this.uid = uid;

}

public String getUname() {

return uname;

}

public void setUname(String uname) {

this.uname = uname;

}

public String getUpass() {

return upass;

}

public void setUpass(String upass) {

this.upass = upass;

}

}

数据可访问基类 BaseDao.java,代码如下:

package cn.cheng.dao;

 

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

 

public class BaseDao {

// 定义数据库连接常量

private final static String DRIVER = “com.mysql.jdbc.Driver”;

private final static String URL = “jdbc:mysql://localhost:3306/cheng”;

private final static String DBNAME = “root”;

private final static String DBPASS = “root”;

 

/**

* 得到数据库连接

* @return

* @throws ClassNotFoundException

* @throws SQLException

*/

public Connection getConn() throwsClassNotFoundException,SQLException {

// 加载驱动

Class.forName(DRIVER);

// 通过DriverManager对象得到连接

Connection conn = DriverManager.getConnection(URL,DBNAME,DBPASS);

// 返回数据库连接

return conn;

}

}

 

数据查询类 UserDao.java,代码如下:

package cn.cheng.dao;

 

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.ArrayList;

import java.util.List;

 

import cn.cheng.entity.User;

 

public class UserDao extends BaseDao {

// 定义全局变量

Connection conn = null;

PreparedStatement pstmt = null;

ResultSet rs = null;

 

/**

* 根据Id查询用户

* @param uid

* @return

*/

public User getUserById(int uid) {

// 创建User对象

User user = null;

// 创建SQL语句

String sql = “select *from tbl_user where uid=?”;

 

try {

// 获得数据库连接

conn = this.getConn();

// 通过Connection对象创建PrepareStatement对象

pstmt = conn.prepareStatement(sql);

// 设置SQL语句的参数

pstmt.setInt(1, uid);

// 执行查询,将查询结果赋给ResultSet对象

rs = pstmt.executeQuery();

// 遍历指针

while (rs.next())

{

user = new User();

user.setUid(rs.getInt(“uid”));

user.setUname(rs.getString(“uname”));

user.setUpass(rs.getString(“upass”));

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

}

return user;

}

 

/**

* 查询所有用户

* @return

*/

@SuppressWarnings(“unchecked”)

public List getUserList() {

// 创建ArrayList对象

List userList = new ArrayList();

 

// 创建SQL对象

String sql = “select * fromtbl_user”;

 

try {

conn = this.getConn();

pstmt = conn.prepareStatement(sql);

rs = pstmt.executeQuery();

while (rs.next())

{

User user = new User();

user.setUid(rs.getInt(“uid”));

user.setUname(rs.getString(“uname”));

user.setUpass(rs.getString(“upass”));

 

userList.add(user);

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

}

return userList;

}


}

最后编写测试类,利用MemCached技术将从数据库得到的数据存入到缓存中;

package cn.cheng.memcachedtest;

 

import java.util.Date;

import java.util.List;

 

import cn.cheng.dao.UserDao;

import cn.cheng.entity.User;

 

importcom.alisoft.xplatform.asf.cache.memcached.client.MemCachedClient;

importcom.alisoft.xplatform.asf.cache.memcached.client.SockIOPool;

 

public class MemcachedManager {

// 创建MemCachedClient全局对象

private static MemCachedClient mcc = new MemCachedClient();

 

static {

// 创建服务器列表及其权重

String[] servers = {“127.0.0.1:11211″};

Integer[] weights = {3};

 

// 创建Socket连接池对象

SockIOPool pool = SockIOPool.getInstance();

 

// 设置服务器信息

pool.setServers(servers);

pool.setWeights(weights);

pool.setFailover(true);

 

// 设置初始连接数、最小和最大连接数以及最大处理时间

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.setAliveCheck(true);

 

// 初始化连接池

pool.initialize();

 

// 压缩设置,超过指定大小(单位为K)的数据都会被压缩

mcc.setCompressEnable(true);

mcc.setCompressThreshold(64 * 1024);

}

 

/**

* 无参构造

*/

protected MemcachedManager (){

 

}

 

// 受保护的对象

protected static MemcachedManager instance = new MemcachedManager();

 

/**

* 为受保护的对象提供一个公共的访问方法

*/

public static MemcachedManager getInstance () {

return instance;

}

 

/**

* 添加对象到缓存中,构成方法重载

* @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);

}

 

/**

* 根据指定的关键字获取对象

*/

public Object get(String key) {

return mcc.get(key);

}

 

 

 

/**

* 利用MemCached测试将单个对象存入缓存,并从缓存中取出

*/

// public static void main(String[] args) {

// // 得到MemcachedManager实例

// MemcachedManager cache = MemcachedManager.getInstance();

//

// // 创建UserDao对象

// UserDao userDao = new UserDao();

// // 查询单个User对象

// User user = userDao.getUserById(4);

//

// // 将User对象添加到缓存中

// cache.add(“user”, user.getUname());

//

// // 将User对象从缓存中取出来

// String uname = (String)cache.get(“user”);

//

// System.out.println(“从缓存中取出的对象为:” + uname);

// }

 

 

 

/**

* 利用MemCached对象将集合存入缓存,并从缓存中取出

*/

@SuppressWarnings(“unchecked”)

public static void main(String[] args) {

// 得到MemcachedManager实例

MemcachedManager cache = MemcachedManager.getInstance();

 

// 创建UserDao对象

UserDao userDao = new UserDao();

// 得到集合对象

List userList = userDao.getUserList();

 

// 创建User对象

User user = null;

for (int i=0; i<userList.size(); i++)

{

// 循环遍历集合对象

user = (User)userList.get(i);

user.getUid();

user.getUname();

user.getUpass();

 

// 将集合对象存入缓存中

cache.add(“userList” + i,user.getUname());

 

// 将集合从缓存中取出

String uname = (String)cache.get(“userList”+i);

 

System.out.println(“从缓存中取得的集合为:” + uname);

}

}

 

}

 

 

 

 

 

补充:Java缓存优化其它解决方案:

· OSCache

· EHCache

· Memcached

· JBossCache