Memcached總結文檔
memcached簡介:
概念:
Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它通過在內存中緩存數據和對象來減少讀取數據庫的次數,從而提高動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,但是客戶端可以用任何語言來編寫,並通過memcached協議與守護進程通信。
Memcached與memcache
Memcache是danga的一個項目,最早是LiveJournal 服務的,最初爲了加速 LiveJournal 訪問速度而開發的,後來被很多大型的網站採用。
Memcached是以守護程序方式運行於一個或多個服務器中,隨時會接收客戶端的連接和操作
特點:
memcached作爲高速運行的分佈式緩存服務器,具有以下的特點。1.協議簡單:memcached的服務器客戶端通信並不使用複雜的XML等格式,而使用簡單的基於文本行的協議。因此,通過telnet也能在memcached上保存數據、取得數據。
2. 基於libevent的事件處理:ibevent是個程序庫,它將Linux的epoll、BSD類操作系統的kqueue等事件處理功能封裝成統一的接口。即使對服務器的連接數增加,也能發揮O(1)的性能。memcached使用這個libevent庫,因此能在Linux、BSD、Solaris等操作系統上發揮其高性能。
3.存儲方式:memcached默認情況下采用了名爲Slab Allocatoion的機制分配,管理內存。內容容量達到指定值之後,就基於LRU(Least Recently Used)算法自動刪除不使用的緩存。
4.通信分佈式memcached儘管是“分佈式”緩存服務器,但服務器端並沒有分佈式功能。而是基於客戶端實現的。
Memcached運行原理示意圖
linux安裝memcached服務端
下載memcached客戶端:另外,Memcache用到了libevent這個庫用於Socket的處理,所以還需要安裝libevent,如果你的系統已經安裝了libevent,可以不用安裝如果沒有也必須下載安裝。
1.在linux中打開終端:分別把memcached和libevent下載回來,放到 /tmp 目錄下:
Linux終端輸入語句:
# cd /tmp 進入tmp文件夾
# wget http://www.danga.com/memcached/dist/memcached-1.2.0.tar.gz
# wget
http://www.monkey.org/~provos/libevent-1.2.tar.gz
自動下載memcached-1.2.0.tar.gz和libevent-1.2.tar.gz
如在虛擬機linux中無法下載,看錯誤中的解決方案
2.先安裝libevent:依次執行下列語句
# tar zxvf libevent-1.2.tar.gz
# cd libevent-1.2
# ./configure –prefix=/usr
# make
# make install
3 測試libevent是否安裝成功:
# ls -al /usr/lib | grep libevent
如輸出一下信息則安裝成功
4.安裝memcached,安裝時需要指定libevent的安裝位置:(順序執行以下語句)
# cd /tmp
# tar zxvf memcached-1.2.0.tar.gz
# cd memcached-1.2.0
# ./configure –with-libevent=/usr
# make
# make install
安裝完成後會把memcached放到 /usr/local/bin/memcached
5.測試memcached是否安裝成功
# ls -al /usr/local/bin/mem*
如果輸出一下信息,則安裝成功
啓動memcached服務端
# /usr/local/bin/memcached -d -m 10 -u root -l 192.168.141.64 -p 12000 -c 256 -P /tmp/memcached.pid
語句中各個參數的含義
如果要結束memcached,則執行: # kill ‘cat /tmp/memcached.pid’
查看memcached運行狀態
ps -ef|grep memcached
注意:可以啓動多個守護進程,不過端口不能重複。
測試memcached
按照下圖執行語句,如果可以輸出信息,則表示正常
安裝時遇到錯誤
下載時無法下載
解決方案:
在windows裏通過瀏覽器直接下載,然後通過ssh工具直接複製到 /tmp下
步驟:1.在linux裏輸入下面語句設置ip
ifconfig eth0 ip地址
2.在windows下通過ssh連接linux
連接成功之後點擊如下按鈕
會出現
在本地window中找到下載的文件複製到linux中的/tmp目錄下
啓動memcached時遇到的錯:
解決方案
Memcached緩存簡單字符串
1.引入commons-pool-1.5.6.jar,java_memcached-release_2.5.1.jar,slf4j-api-1.6.1.jar,slf4j-simple-1.6.1.jar
同時導入junit 包和 log4j包,若不使用junit測試或者打印日誌信息可不導入
2.創建memcached工具類:
public class MemcachedUtil {
//log4j
private static Logger logger = Logger.getLogger(MemcachedUtil.class);
//實例化memcached客戶端
public static MemCachedClient mcc = null;
//SockIOPool是Memcached客戶端提供的一個套接字連接池,通俗講,就是與Memcached服務器端交換數據的對象。
private static SockIOPool pool = null;
//初始調用init方法
static {
init();
}
/**
* 初始化連接池
*/
public static void init() {
String sockPoolName = "MEM_CAHCE";
String serverlist = "";
//初始連接數
int initConn = 5;
//最小連接數
int minConn = 5;
//最大連接數
int maxConn = 50;
Properties properties = new Properties();
try {
//加載配置文件
properties.load(new FileInputStream(MemcachedUtil.class.getResource("/test/memcache.properties").getFile()));
sockPoolName = properties.getProperty("memcache.poolName", sockPoolName);
serverlist = properties.getProperty("memcache.serverlist", serverlist);
initConn = Integer.parseInt(properties.getProperty("memcache.initConn", "5"));
minConn = Integer.parseInt(properties.getProperty("memcache.minConn", "5"));
maxConn = Integer.parseInt(properties.getProperty("memcache.maxConn", "50"));
} catch (IOException e) {
logger.warn("not found finle memcache.properties in classpath", e);
}
logger.info("Initializing memcached pool");
if (pool == null) {
try {
pool = SockIOPool.getInstance(sockPoolName);
pool.setServers(serverlist.split(","));
if (!pool.isInitialized()) {
pool.setInitConn(initConn);
pool.setMinConn(minConn);
pool.setMaxConn(maxConn);
pool.setMaintSleep(30);
pool.setNagle(false);
//最大處理時間
pool.setSocketTO(60 * 60);
//設置TCP參數,連接超時
pool.setSocketConnectTO(0);
//初始化並啓動連接池
pool.initialize();
}
} catch (Exception ex) {
logger.error(ex.getMessage());
}
}
if (mcc == null) {
mcc = new MemCachedClient(sockPoolName);
mcc.setClassLoader(MemcachedUtil.class.getClassLoader());
mcc.setCompressEnable(false);
mcc.setCompressThreshold(0);
}
}
/**
* 關閉連接池
*/
public static void closePool() {
pool.shutDown();
mcc = null;
pool = null;
logger.info("Memcached pool closed");
}
/**
* 設置緩存
*
* @param key 鍵
* @param obj 值
*/
public static boolean set(String key, Object obj) {
try {
return mcc.set(key, obj);
} catch (Exception e) {
logger.error("Pool set error!");
e.printStackTrace();
}
return false;
}
/**
* 設置緩存
*
* @param key 鍵
* @param obj 值
*/
public static boolean set(String key, Object obj, long time) {
try {
return mcc.set(key, obj, new Date(time));
} catch (Exception e) {
logger.error("Pool set error!");
e.printStackTrace();
}
return false;
}
/**
* 設置緩存
*
* @param key 鍵
* @param obj 值
* @param time 緩存時間(毫秒)
*/
public static boolean set(String key, Serializable obj, long time) {
try {
return mcc.set(key, obj, new Date(time));
} catch (Exception e) {
logger.error("Pool set error!");
e.printStackTrace();
}
return false;
}
public static void replace(String key, Serializable value, long cachelTime) {
try {
mcc.replace(key, value, new Date(cachelTime));
} catch (Exception e) {
logger.error(" pool set error!");
}
}
/**
* 獲取緩存
*
* @param key 鍵
* @return 值
*/
public static Object get(String key) {
Object result = null;
try {
result = mcc.get(key);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
/**
* 緩存數值
*
* @param key 鍵
* @param count 數值
*/
public static void setCounter(String key, long count) {
try {
mcc.storeCounter(key, count);
} catch (Exception e) {
logger.error("Pool setCounter error!");
}
}
/**
* 緩存的數值加1
*
* @param key 鍵
*/
public static void addCounter(String key) {
try {
mcc.incr(key);
} catch (Exception e) {
logger.error("Pool setCounter error!");
}
}
/**
* 增加緩存數值
*
* @param key 鍵
* @param addValue 增加的值
*/
public static void addCounter(String key, long addValue) {
try {
mcc.incr(key, addValue);
} catch (Exception e) {
logger.error(" pool setCounter error!");
}
}
/**
* 獲取緩存數值
*
* @param key 鍵
* @return 值
*/
public static long getCounter(String key) {
long result = 0;
try {
result = mcc.getCounter(key);
} catch (Exception e) {
logger.error(e.getMessage());
}
return result;
}
/**
* 刪除緩存
*
* @param key 鍵
*/
public static boolean delete(String key) {
try {
return mcc.delete(key);
} catch (Exception e) {
logger.error(e.getMessage());
}
return false;
}
/**
* 刪除緩存數值
*
* @param key 鍵
*/
public static long deleteCounter(String key) {
try {
return mcc.decr(key);
} catch (Exception e) {
logger.error(" pool setCounter error!");
}
return 0;
}
}
數據寫入操作方法的解釋:
set方法
將數據保存到cache服務器,如果保存成功則返回true
如果cache服務器存在同樣的key,則替換之
set有5個重載方法,key和value是必須的參數,還有過期時間,hash碼,value是否字符串三個可選參數
add方法
將數據添加到cache服務器,如果保存成功則返回true
如果cache服務器存在同樣key,則返回false
add有4個重載方法,key和value是必須的參數,還有過期時間,hash碼兩個可選參數
· replace方法
將數據替換cache服務器中相同的key,如果保存成功則返回true
如果cache服務器不存在同樣key,則返回false
replace有4個重載方法,key和value是必須的參數,還有過期時間,hash 碼兩個可選參數
其中過期時間的單位爲毫秒
數據讀取方法的解釋:
cache數據讀取操作方法
使用get方法從cache服務器獲取一個數據
3.創建測試用例:
//調用工具類的set方法 往memcached裏添加值(設置過期時間的時候不能低於1000毫秒)
MemcachedUtil.set("hello", "world", 1000);
//調用工具類的get方法根據鍵獲取值
Object hello = MemcachedUtil.get("hello");
//直接輸出沒有睡眠時間,即不超過緩存的過期時間System.out.println(hello+"--------------------------------");
//調用睡眠方法使程序停止運行2000毫秒
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//再次調用get方法
Object hello2 = MemcachedUtil.get("hello");
System.out.println(hello2+"--------------------------------");
Assert.assertEquals("world", hello);
Memcached緩存實體對象
1.創建JavaBean 對象並實現Serializable否則會緩存不到memcached中其他步驟與緩存簡單字符一樣
設置多個端口進行緩存:
在配置文件中,在serverlist中設置多個端口,不同端口之間用,分割
附(配置文件):memcached.properties
memcache.poolName=MEM_CAHCE
#memcache.serverlist=127.0.0.1:11211
memcache.serverlist=192.168.192.128:12244,192.168.192.128:12233
memcache.initCon=5
memcache.minConn=5
memcache.maxConn=508
遇錯總結:
1.在windows中使用Java程序連接linux時必須保證linux的防火牆是關閉的否則會出現如下錯誤
com.schooner.MemCached.SchoonerSockIOPool Thu Aug 21 00:09:00 CST 2014 - ++++ failed to get SockIO obj for: 192.168.192.128:1223
com.schooner.MemCached.SchoonerSockIOPool Thu Aug 21 00:09:00 CST 2014 - ++++ failed to create connection to: 192.168.192.128:1223 -- only 0 created.
com.schooner.MemCached.SchoonerSockIOPool Thu Aug 21 00:09:01 CST 2014 - ++++ failed to get SockIO obj for: 192.168.192.128:1223
設置過期時間的時候必須保證過期時間大於1000毫秒,否則設置過期時間不起作用