memcached与mysql结合使用

本文介绍了一种使用Memcached作为数据库缓存的方法,通过实际案例展示了如何将MySQL查询结果存储到Memcached中,以减少数据库负载并提高访问速度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载自郭无心的文章,帮助了我的项目开发

作者:郭无心
链接:https://www.zhihu.com/question/40752932/answer/88067718
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

memcached的客户端jar包我知道的有两个
alisoft-xplatform-asf-cache-2.5.1.jar -------- alisoft-xplatform-asf-cache是阿里的架构师岑文初进行封装的,用作memcache的访问和操作,里面的注释都是中文的。
memcached-2.5.jar
Memcached的客户端API包,官方出品。
-----------------------------------------------------------------------------------------
我所知道的memcached的mysql缓存封装方式,简单来看就是先通过sql语句通过网络进行访问,取到数据之后存放到memcached当中去,然后当需要使用数据的时候,首先从memcached当中获取,当获取不到再从mysql当中获取。

在数据量和访问量不大的情况下,使用memcached的必要性不大,因为memcached吃内存很厉害,所以开单机的memcached不划算,还不如将数据直接用map存放到内存中去,游戏服务器一般都是这么做的,服务器启动初始化过程中就将游戏静态配置数据加载到内存中去,然后直接在需要的时候访问内存就可以了。

----------------------------------------------------------------------------------------------
在大型web应用中,每张表都很大,所以读取压力很大,因此设计分布式的memcached十分有必要。
-----------------------------------------------------------------------------------------------
提供一个简单示例,通过memcached来缓存数据。
<img src="https://pic1.zhimg.com/50/caa7d59647b9c730bc3e7e5642c4a03e_hd.jpg" data-rawwidth="336" data-rawheight="327" class="content_image" width="336">
package bean;

import java.io.Serializable;

public class User implements Serializable {

	private static final long serialVersionUID = -3896605600471191953L;
	private int id;
	private String username;
	private String password;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password="
				+ password + "]";
	}
	
	
}

package memcachedTest;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.List;

import util.UserDao;
import bean.User;

import com.alisoft.xplatform.asf.cache.memcached.client.MemCachedClient;
import com.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对象将集合存入缓存,并从缓存中取出
	 * @throws UnsupportedEncodingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException, InterruptedException {
		// 得到MemcachedManager实例
		final MemcachedManager cache = MemcachedManager.getInstance();

		// 创建UserDao对象
		final UserDao userDao = new UserDao();
		// 得到集合对象
		final List<User> userList = userDao.getUserList();

		System.out.println("从数据库当中取出数据" + userList);

		// 创建User对象
	       User user = null;
	       for (int i=0; i<userList.size(); i++)
	       {
	           // 循环遍历集合对象
	           user = (User)userList.get(i);
	           
	           // 将集合对象存入缓存中
	           cache.add(String.valueOf(user.getId()),user.getUsername());
	           
	           // 将集合从缓存中取出
	           String uname = (String)cache.get(String.valueOf(user.getId()));
	           
	           System.out.println("从缓存中取得的集合为:" + uname);
	       }
	       
	       
	    //下面尝试获取id用户
	    User user2 = userDao.getUserById(3,cache);
	    System.out.println(user2);
	}

}

package util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcConnector {
  // 定义数据库连接常量
    private final static String DRIVER = "com.mysql.jdbc.Driver";
    private final static String URL = "jdbc:mysql://127.0.0.1:3306/guowuxin";
    private final static String DBNAME = "root";
    private final static String DBPASS = "admin";
    
    /**
     * 得到数据库连接
     * @return
     * @throws ClassNotFoundException
     * @throws SQLException
     */
    public Connection getConn()throws ClassNotFoundException,SQLException {
       // 加载驱动
       Class.forName(DRIVER);
       // 通过DriverManager对象得到连接
       Connection conn = DriverManager.getConnection(URL,DBNAME,DBPASS);
       // 返回数据库连接
       return conn;
    }
}
package util;

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 memcachedTest.MemcachedManager;
import bean.User;

public class UserDao extends JdbcConnector {
	// 定义全局变量
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;

	/**
	 * 根据Id查询用户
	 * 
	 * @param uid
	 * @return
	 */
	public User getUserById(int uid,MemcachedManager cache) {
		
		// 创建User对象
		User user = null;
		if(cache.get(String.valueOf(uid)) != null)
		{
		    user = new User();
		    user.setUsername((String)cache.get(String.valueOf(uid)));
		    System.out.println("从Cache中命中用户" + uid);
		    return user;
		}
		
		// 创建SQL语句
		String sql = "select * from user where id=?";

		try {
			// 获得数据库连接
			conn = this.getConn();
			// 通过Connection对象创建PrepareStatement对象
			pstmt = conn.prepareStatement(sql);
			// 设置SQL语句的参数
			pstmt.setInt(1, uid);
			// 执行查询,将查询结果赋给ResultSet对象
			rs = (ResultSet) pstmt.executeQuery();
			// 遍历指针
			while (rs.next()) {
				user = new User();
				user.setId(rs.getInt("id"));
				user.setUsername(rs.getString("username"));
				user.setPassword(rs.getString("password"));
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return user;
	}

	/**
	 * 查询所有用户
	 */
	public List<User> getUserList() {
		// 创建ArrayList对象
		List<User> userList = new ArrayList<User>();

		// 创建SQL对象
		String sql = "select * from user";

		try {
			conn = this.getConn();
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				User user = new User();
				user.setId(rs.getInt("id"));
				user.setUsername(rs.getString("username"));
				user.setPassword(rs.getString("password"));
				userList.add(user);
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return userList;
	}
}

package util;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5 {
	private static final char[] HEX_TABLE = { '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	public static String md5(final String source)
			throws NoSuchAlgorithmException, UnsupportedEncodingException {
		MessageDigest messageDigest = MessageDigest.getInstance("MD5");
		messageDigest.reset();
		messageDigest.update(source.getBytes("utf-8"));
		final byte[] bytes = messageDigest.digest();

		return byteToHexString(bytes);
	}

	private static String byteToHexString(final byte[] bytes) {
		return byteToHexString(bytes, 0, bytes.length - 1);
	}

	private static String byteToHexString(final byte[] bytes, final int begin,
			final int end) {
		if (bytes == null) {
			return null;
		}
		final int length = bytes.length;
		if (begin < 0 || begin > end || end > length) {
			return null;
		}

		final StringBuilder builder = new StringBuilder();
		for (int i = begin; i <= end; i++) {
			final byte data = bytes[i];
			builder.append(HEX_TABLE[data & 0xFF >>> 4]);
			builder.append(HEX_TABLE[data & 0x0F]);
		}
		return builder.toString();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值