memcached怎麼樣mysql結合使用?


最常用的用法當然是作為mysql前面的緩存,大概處理邏輯如下:

  • 讀取:讀cache-&>miss則讀資料庫-&>保存至cache-&>返回數據
    • 一致性要求不高:寫db-&>寫成功後將cache失效-&>等待下次讀取
    • 部分實現一致性要求高:將cache失效-&>寫db(此時會加鎖導致其它讀取等待)-&>再次將cache失效,確保cache不會有臟數據-&>等待下次讀取

其次可以在使用MC作為mysql query cache,但配置略為複雜,而且受限於mysql cache本身機制,不如前一種方法更通用。

MC的定位就是緩存,丟了只能重新取,因此需要持久化的數據最好使用redis,如session。

MC不支持集群,需要自己寫client進行sharding或主備等集群實現,可參考微博實現。


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來緩存數據。

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& userList = userDao.getUserList();

System.out.println("從資料庫當中取出數據" + userList);

// 創建User對象
User user = null;
for (int i=0; i&

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& getUserList() {
// 創建ArrayList對象
List& userList = new ArrayList&();

// 創建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();
}
}


推薦閱讀:

Redis 的極限壓力為啥大於 Memcache?
Redis 和 Memcached 各有什麼優缺點,主要的應用場景是什麼樣的?
Redis 性能比 Memcached 好嗎?有哪些網站採用 Redis?使用 Memcached 的出色網站有哪些?
redis、memcache和mongodb各自的優點是什麼,怎麼選擇呢?

TAG:MySQL | Memcached | 資料庫設計 |