關於memcached的基礎知識可以查看博客其他博文,這里只記錄了搭建的過程,謝謝!
1、分別在三台服務器上安裝Memcached並啟動
第一、由於memcached是基於libevent的事件處理,所以需要安裝libevent
yum install libevent libevent-devel
第二、上傳Memcached到三台服務器(192.168.176.129/192.168.176.130/192.168.176.131)解壓並安裝
tar -zxvf memcached-1.2.5.tar.gz cd memcached-1.2.5 ./configure make make install 默認情況下安裝到/usr/local/bin下
第三、啟動三台服務器的memcached服務
/usr/local/bin/memcached -u root -p 1211 -m 64m -vv -vv:用very vrebose模式啟動,調試信息和錯誤輸出到控制台 -d:座位deamon在后台啟動 -d選項是啟動一個守護進程, -m是分配給Memcache使用的內存數量,單位是MB,我這里是10MB, -u是運行Memcache的用戶,我這里是root, -l是監聽的服務器IP地址,如果有多個地址的話,我這里指定了服務器的IP地址192.168.0.200, -p是設置Memcache監聽的端口,我這里設置了12000,最好是1024以上的端口, -c選項是最大運行的並發連接數,默認是1024,我這里設置了256,按照你服務器的負載量來設定, -P是設置保存Memcache的pid文件,我這里是保存在 /tmp/memcached.pid,
2、編寫客戶端代碼
雖然Memcached是分布式的,但是本身是不支持的,我們需要在客戶端編寫分布式策略,具體代碼里面注釋寫的非常詳細
/** * */ package com.benxq.test; import java.io.IOException; import java.util.Date; import java.util.Iterator; import java.util.Map; import org.apache.log4j.Logger; import com.whalin.MemCached.MemCachedClient; import com.whalin.MemCached.SockIOPool; /** * @ClassName: MemcachedUtils * @Description: Memcached工具類 * Created by qucf on 2016年1月14日. */ public class MemcachedUtils { private static final Logger logger = Logger.getLogger(MemcachedUtils.class); //如果多個memcached必須制定memcachedName private static SockIOPool sockIOPool=SockIOPool.getInstance("memcached1"); //服務器列表 格式:127.0.0.1:port private static String[] servers=new String[]{"192.168.176.131:1211","192.168.176.129:1211"}; //服務器權重 所有權重的最大公約數應該是1 否則會造成資源浪費 private static Integer[] serverWeights=new Integer[]{1,1}; private static MemCachedClient cachedClient; static { //設置服務器列表 sockIOPool.setServers(servers); //設置服務器的權重 權重和服務器的位置一一對應 sockIOPool.setWeights(serverWeights); //設置開始時每個cache服務器的可用連接數 sockIOPool.setInitConn(2); //設置每個服務器最少可用連接數 sockIOPool.setMinConn(2); //設置每個服務器最大可用連接數 sockIOPool.setMaxConn(10); //設置可用連接池的最長等待時間 ms sockIOPool.setMaxIdle(5000); /** *設置連接池維護線程的睡眠時間 *設置為0,維護線程不啟動 *維護線程主要通過log輸出socket的運行狀況,監測連接數目及空閑等待時間等參數以控制連接創建和關閉。 */ sockIOPool.setMaintSleep(0); //設置是否使用Nagle算法,因為我們的通訊數據量通常都比較大(相對TCP控制數據)而且要求響應及時,因此該值需要設置為false(默認是true) sockIOPool.setNagle(true); //設置socket的讀取等待超時值 ms sockIOPool.setSocketTO(3000); //設置socket的連接等待超時值 ms sockIOPool.setSocketConnectTO(2000); /** *設置連接心跳監測開關。 *設為true則每次通信都要進行連接是否有效的監測,造成通信次數倍增,加大網絡負載,因此該參數應該在對HA要求比較高的場合設為TRUE,默認狀態是false。 */ sockIOPool.setAliveCheck(false); /** *設置連接失敗恢復開關 *設置為TRUE,當宕機的服務器啟動或中斷的網絡連接后,這個socket連接還可繼續使用,否則將不再使用,默認狀態是true,建議保持默認。 */ sockIOPool.setFailback(true); /** *設置容錯開關 *設置為TRUE,當當前socket不可用時,程序會自動查找可用連接並返回,否則返回NULL,默認狀態是true,建議保持默認。 */ sockIOPool.setFailover(true); /** *設置hash算法 * alg=0 使用String.hashCode()獲得hash code,該方法依賴JDK,可能和其他客戶端不兼容,建議不使用 * alg=1 使用original 兼容hash算法,兼容其他客戶端 * alg=2 使用CRC32兼容hash算法,兼容其他客戶端,性能優於original算法 * alg=3 使用MD5 hash算法 *采用前三種hash算法的時候,查找cache服務器使用余數方法。采用最后一種hash算法查找cache服務時使用consistent方法。 */ sockIOPool.setHashingAlg(3); //設置完pool參數后最后調用該方法,啟動pool。 sockIOPool.initialize(); if (cachedClient == null){ cachedClient = new MemCachedClient("memcached1"); /** *設定是否壓縮放入cache中的數據 *默認值是ture *如果設定該值為true,需要設定CompressThreshold? */ cachedClient.setCompressEnable(true); // 設定需要壓縮的cache數據的閾值 默認值是30k cachedClient.setCompressThreshold(30); /*設置cache數據的原始類型是String 默認值是false 只有在確定cache的數據類型是string的情況下才設為true,這樣可以加快處理速度。 */ cachedClient.setPrimitiveAsString(false); } } private MemcachedUtils() { } /** * 向緩存添加新的鍵值對。如果鍵已經存在,則之前的值將被替換。 * @param key 鍵 * @param value 值 * @return */ public static boolean set(String key, Object value) { return setExp(key, value, null); } /** * 向緩存添加新的鍵值對。如果鍵已經存在,則之前的值將被替換。 * @param key 鍵 * @param value 值 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ public static boolean set(String key, Object value, Date expire) { return setExp(key, value, expire); } /** * 向緩存添加新的鍵值對。如果鍵已經存在,則之前的值將被替換。 * @param key 鍵 * @param value 值 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ private static boolean setExp(String key, Object value, Date expire) { boolean flag = false; try { flag = cachedClient.set(key, value, expire); } catch (Exception e) { // 記錄Memcached日志 logger.error("Memcached set方法報錯,key值:" + key + "\r\n"); } return flag; } /** * * 僅當緩存中不存在鍵時,add 命令才會向緩存中添加一個鍵值對。 * @param key 鍵 * @param value 值 * @return */ public static boolean add(String key, Object value) { return addExp(key, value, null); } /** * 僅當緩存中不存在鍵時,add 命令才會向緩存中添加一個鍵值對。 * @param key 鍵 * @param value 值 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ public static boolean add(String key, Object value, Date expire) { return addExp(key, value, expire); } /** * 僅當緩存中不存在鍵時,add 命令才會向緩存中添加一個鍵值對。 * @param key 鍵 * @param value 值 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ private static boolean addExp(String key, Object value, Date expire) { boolean flag = false; try { flag = cachedClient.add(key, value, expire); } catch (Exception e) { // 記錄Memcached日志 logger.error("Memcached add方法報錯,key值:" + key + "\r\n"); } return flag; } /** * 僅當鍵已經存在時,replace 命令才會替換緩存中的鍵。 * @param key 鍵 * @param value 值 * @return */ public static boolean replace(String key, Object value) { return replaceExp(key, value, null); } /** * 僅當鍵已經存在時,replace 命令才會替換緩存中的鍵。 * @param key 鍵 * @param value 值 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ public static boolean replace(String key, Object value, Date expire) { return replaceExp(key, value, expire); } /** * 僅當鍵已經存在時,replace 命令才會替換緩存中的鍵。 * @param key 鍵 * @param value 值 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ private static boolean replaceExp(String key, Object value, Date expire) { boolean flag = false; try { flag = cachedClient.replace(key, value, expire); } catch (Exception e) { logger.error("Memcached replace方法報錯,key值:" + key + "\r\n"); } return flag; } /** * get 命令用於檢索與之前添加的鍵值對相關的值。 * @param key 鍵 * @return */ public static Object get(String key) { Object obj = null; try { obj = cachedClient.get(key); } catch (Exception e) { logger.error("Memcached get方法報錯,key值:" + key + "\r\n"); } return obj; } /** * 刪除 memcached 中的任何現有值。 * @param key 鍵 * @return */ public static boolean delete(String key) { return deleteExp(key, null); } /** * 刪除 memcached 中的任何現有值。 * @param key 鍵 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ public static boolean delete(String key, Date expire) { return deleteExp(key, expire); } /** * 刪除 memcached 中的任何現有值。 * @param key 鍵 * @param expire 過期時間 New Date(1000*10):十秒后過期 * @return */ private static boolean deleteExp(String key, Date expire) { boolean flag = false; try { flag = cachedClient.delete(key, expire); } catch (Exception e) { logger.error("Memcached delete方法報錯,key值:" + key + "\r\n"); } return flag; } /** * 清理緩存中的所有鍵/值對 * @return */ public static boolean flashAll() { boolean flag = false; try { flag = cachedClient.flushAll(); } catch (Exception e) { logger.error("Memcached flashAll方法報錯\r\n"); } return flag; } public static void main(String[] args) { MemcachedUtils.add("teacher", "zhangsan"); // Object obj = MemcachedUtils.get("room"); // System.out.println("===="+obj+"===="); } }
如有問題,大家可以聯系我QQ 752432995 一同交流技術分享學習的快樂!
