一、windows下安装

环境:win7专业版+memcached_win32_1.4.5

步骤:

1、cmd切换到指定解压目录
2、memcached -d install安装
3、输入memcached –h,出现下图窗口说明已经安装成功

memcached的使用_服务器

4、telnet测试是否正常运行 telnet 127.0.0.1 11211 如下图:

memcached的使用_sed_02

memcached的使用_sed_03

5、stats命令查看运行状态如下图:

memcached的使用_服务器_04

二、linux下安装

环境:redhat5+memcached-1.4.25
所需安装包:
步骤:
1、解压libevent
tar -zxvf libevent-2.0.21-stable.tar.gz  
2、安装libevent
./configure --prefix /etc/libevent/  
make clean  
make  
make install 
3、解压memcached
tar -zxvf memcached-1.4.21.tar.gz
4、安装memcached
./configure --prefix /etc/memcached/ --with-libevent=/etc/libevent/  
make clean  
make  
make install
5.启动memcached
cd /etc/memcached/bin  
./memcached -d -u root
6.telnet看memcached是否启动成功,stat查看运行状态
 
7.查看memcached运行的进程
8.关闭memcached
三、使用memcached
http://www.cnblogs.com/netWild/archive/2013/05/14/memcached.html
3.1 所需jar包
3.2 MemCachedConfig.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. ***** memcached数据库配置文件 *****
  4. ***********************************
  5. -->
  6. <MemCachedConfig>
  7. <!--
  8. Enabled : 是否启用memcached内存数据库选项
  9. 可选值 : true - 启用; false - 停用
  10. -->
  11. <Enabled>true </Enabled>
  12. <!--
  13. Servers : 可用的memcached服务器列表,各服务器根据weight(负载权重值)实现分布式任务均衡
  14. 注意 : 各memcached服务器负载权重值的最大公约数最好为1,可在一定程度上简化其内部的负载均衡算法
  15. 规则 : <Server host="memcached服务器IP或域名" post="memcached服务端口(默认11211)" weight="负载权重值" />
  16. -->
  17. <Servers>
  18. <!--
  19. <Server host="192.168.1.10" post="11211" weight="2" />
  20. <Server host="192.168.1.11" post="11211" weight="1" />
  21. <Server host="192.168.1.12" post="11211" weight="1" />
  22. -->
  23. <Server host="192.168.78.128" post="11211" weight="1" />
  24. </Servers>
  25. <!--
  26. Config : memcached数据库配置选项
  27. initConn : 初始连接数
  28. minConn : 最小连接数
  29. maxConn : 最大连接数
  30. maxIdle : 连接最大空闲时间(毫秒)
  31. maintSleep : 主线程的维护周期(每隔多少秒维护一次连接池,0表示不启用主线程)
  32. socketTO : 读取操作的超时限制(毫秒)
  33. socketConnTO : 连接操作的超时限制(毫秒,0表示不限制)
  34. compressEnable : 是否启用自动压缩(该参数从java_memcached-release_2.6.1开始不再支持)
  35. compressThreshold : 超过指定大小(bytes)的数据都会被压缩(该参数从java_memcached-release_2.6.1开始不再支持)
  36. -->
  37. <Config>
  38. <property name="initConn">5 </property>
  39. <property name="minConn">5 </property>
  40. <property name="maxConn">250 </property>
  41. <property name="maxIdle">21600000 </property>
  42. <property name="maintSleep">30 </property>
  43. <property name="socketTO">10000 </property>
  44. <property name="socketConnTO">0 </property>
  45. <property name="compressEnable">true </property>
  46. <property name="compressThreshold">65536 </property>
  47. </Config>
  48. </MemCachedConfig>
3.3 MemCached.java
  1. package com.kysis.util;
  2. import java.io.File;
  3. import java.text.DecimalFormat;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.Calendar;
  7. import java.util.Iterator;
  8. import java.util.LinkedList;
  9. import java.util.List;
  10. import java.util.Date;
  11. import java.util.HashMap;
  12. import java.util.LinkedHashMap;
  13. import java.util.Map;
  14. import org.apache.commons.net.telnet.TelnetClient;
  15. import org.dom4j.Document;
  16. import org.dom4j.Element;
  17. import org.dom4j.Node;
  18. import org.dom4j.io.SAXReader;
  19. import com.danga.MemCached.MemCachedClient;
  20. import com.danga.MemCached.SockIOPool;
  21. /**
  22. * @category memcached内存数据库操作类
  23. * @version 1.0
  24. */
  25. public class MemCached {
  26. //是否启用MemCached内存数据库
  27. protected static boolean enUsed = true;
  28. //创建全局唯一的可实例化对象
  29. protected static MemCached memCached = new MemCached();
  30. //初始化MemCached客户端对象
  31. protected static MemCachedClient memClient = new MemCachedClient();
  32. //定义MemCached服务器运行环境配置文件名称
  33. private static final String MemCachedConfigFile_NAME = "MemCachedConfig.xml";
  34. //定义可用的MemCached服务器列表,用于分布式存储
  35. private static String[] serverListArr = new String[ 1];
  36. //定义各MemCached服务器的负载权重列表,与服务器列表按先后顺序对应
  37. private static Integer[] weightListArr = new Integer[ 1];;
  38. //定义MemCached服务器运行环境表,配置文件中关于参数相关数据将保存到该表
  39. private static Map<String, String> serverConfig;
  40. //定义MemCached服务器运行状态表,用于保存各状态的中文解释
  41. protected static HashMap<String, String> statsItems;
  42. //设置全局静态参数,以下代码在整个服务器运行周期内仅运行一次!
  43. static {
  44. //初始化MemCached运行环境配置
  45. //首先初始化各参数默认值,然后加载配置文件,遍历其中的参数值并进行覆盖。
  46. initConfig();
  47. if(enUsed){ //如果已启用memcached缓存服务
  48. //获取socke连接池的实例对象
  49. SockIOPool pool = SockIOPool.getInstance();
  50. //设置可用的MemCached服务器信息,实现分布式存储
  51. pool.setServers(serverListArr);
  52. //设置各MemCached服务器的负载权重,根据可支配内存实现负载均衡
  53. pool.setWeights(weightListArr);
  54. //设置初始连接数
  55. pool.setInitConn(Integer.parseInt(serverConfig.get( "initConn").toString()));
  56. //设置最小连接数
  57. pool.setMinConn(Integer.parseInt(serverConfig.get( "minConn").toString()));
  58. //设置最大连接数
  59. pool.setMaxConn(Integer.parseInt(serverConfig.get( "maxConn").toString()));
  60. //设置连接最大空闲时间
  61. pool.setMaxIdle(Long.parseLong(serverConfig.get( "maxIdle").toString()));
  62. //设置主线程的睡眠时间,每隔该时间维护一次各连接线程状态
  63. pool.setMaintSleep(Long.parseLong(serverConfig.get( "maintSleep").toString()));
  64. //关闭nagle算法
  65. pool.setNagle( false);
  66. //读取操作的超时限制
  67. pool.setSocketTO(Integer.parseInt(serverConfig.get( "socketTO").toString()));
  68. //连接操作的超时限制,0为不限制
  69. pool.setSocketConnectTO(Integer.parseInt(serverConfig.get( "socketConnTO").toString()));
  70. //初始化连接池
  71. pool.initialize();
  72. //压缩设置,超过指定大小的数据都会被压缩
  73. //从java_memcached-release_2.6.1开始已经不再支持内置的数据压缩功能
  74. //memClient.setCompressEnable(Boolean.parseBoolean(serverConfig.get("compressEnable").toString()));
  75. //memClient.setCompressThreshold(Long.parseLong(serverConfig.get("compressThreshold").toString()));
  76. }
  77. }
  78. /**
  79. * @category 初始化MemCached运行环境配置
  80. * @category 注:该方法在整个服务器周期内仅运行一次
  81. */
  82. protected static void initConfig(){
  83. //初始化可用的MemCached服务器列表默认值(本机)
  84. serverListArr[ 0] = "127.0.0.1:11211";
  85. weightListArr[ 0] = 1;
  86. //初始化MemCached服务器运行环境表(默认值),当某参数未在配置文件中进行定义时,将使用该默认值
  87. serverConfig = new HashMap<String, String>(){
  88. private static final long serialVersionUID = 1L;
  89. {
  90. put( "initConn", "5"); //设置初始连接数
  91. put( "minConn", "5"); //设置最小连接数
  92. put( "maxConn", "250"); //设置最大连接数
  93. put( "maxIdle", "21600000"); //设置连接最大空闲时间(6小时)
  94. put( "maintSleep", "30"); //设置主线程的睡眠时间(30秒)
  95. put( "socketTO", "10000"); //读取操作的超时限制(10秒)
  96. put( "socketConnTO", "0"); //连接操作的超时限制(不限制)
  97. put( "compressEnable", "true"); //是否启用自动压缩(启用)
  98. put( "compressThreshold", "65536"); //超过指定大小的数据都会被压缩(64K)
  99. }
  100. };
  101. //开始读取配置文件,并将其中的参数值向默认环境表中进行覆盖
  102. String filePath = Thread.currentThread().getContextClassLoader().getResource( "MemCachedConfig.xml").getPath().substring( 1);
  103. File file = new File(filePath.replaceAll( "%20", " "));
  104. try{
  105. if(file.exists()){ //如果可以成功加载配置文件
  106. SAXReader sr = new SAXReader();
  107. Document doc = sr.read(file);
  108. Element Root = doc.getRootElement(); //获得根节点
  109. Element Enabled = (Element)Root.selectSingleNode( "Enabled"); //获得是否启用memcached节点
  110. Element Servers = (Element)Root.selectSingleNode( "Servers"); //获得可用的服务器列表父节点
  111. Element Config = (Element)Root.selectSingleNode( "Config"); //获得运行环境参数列表父节点
  112. enUsed = Boolean.parseBoolean(Enabled.getText()); //是否启用memcached缓存服务
  113. List<Element> serverDoms = Servers.elements(); //备用的服务器列表
  114. List<Element> serverUsed = new ArrayList<Element>(); //经检测,实际可用的服务器列表
  115. TelnetClient telnet = new TelnetClient(); //初始化Telnet对象,用来检测服务器是否可以成功连接
  116. telnet.setConnectTimeout( 5000); //连接超时:5秒
  117. for(Element serverTmp : serverDoms){
  118. try{
  119. telnet.connect(serverTmp.attributeValue( "host"), Integer.parseInt(serverTmp.attributeValue( "post"))); //连接到服务器
  120. telnet.disconnect(); //断开连接
  121. serverUsed.add(serverTmp); //连接成功,将服务器添加到实际可用列表
  122. } catch(Exception e){}
  123. }
  124. int serverCount = serverUsed.size(); //经检测,实际可用的服务器个数
  125. if(serverCount == 0){ //没有发现实际可用的服务器,返回
  126. enUsed = false;
  127. return;
  128. }
  129. serverListArr = new String[serverCount]; //初始化服务器地址及端口号数组
  130. weightListArr = new Integer[serverCount]; //初始化服务器负载权重数组
  131. for( int ind= 0; ind < serverCount; ind++){ //向服务器数组进行赋值
  132. serverListArr[ind] = serverUsed.get(ind).attributeValue( "host") + ":" + serverUsed.get(ind).attributeValue( "post");
  133. weightListArr[ind] = Integer.parseInt(serverUsed.get(ind).attributeValue( "weight").toString());
  134. }
  135. Object[] serverConfigArr = serverConfig.keySet().toArray(); //返回服务器运行环境参数列表,用于遍历配置文件
  136. for(Object cfgItem : serverConfigArr){
  137. Node node = Config.selectSingleNode( "//property[@name='" + cfgItem + "']"); //查找指定的参数节点
  138. if(node == null) continue; //如果该参数节点不存在,则继续查找下一个参数,该参数将采用默认值
  139. Element configNode = (Element)node;
  140. serverConfig.put(cfgItem.toString(), configNode.getTextTrim()); //添加配置文件中定义的参数值
  141. }
  142. }
  143. } catch(Exception e){
  144. System.out.println(e.toString());
  145. }
  146. //初始化MemCached服务器运行状态表,对各状态进行中文解释
  147. statsItems = new HashMap<String, String>(){
  148. {
  149. put( "pid", "MemCached服务进程ID");
  150. put( "version", "MemCached服务版本");
  151. put( "pointer_size", "MemCached服务器架构");
  152. put( "time", "服务器当前时间");
  153. put( "uptime", "服务器本次启动以来,总共运行时间");
  154. put( "connection_structures", "服务器分配的连接结构数");
  155. put( "total_connections", "服务器本次启动以来,累计响应连接总次数");
  156. put( "curr_connections", "当前打开的连接数");
  157. put( "limit_maxbytes", "允许服务支配的最大内存容量");
  158. put( "bytes", "当前已使用的内存容量");
  159. put( "bytes_written", "服务器本次启动以来,写入的数据量");
  160. put( "bytes_read", "服务器本次启动以来,读取的数据量");
  161. put( "total_items", "服务器本次启动以来,曾存储的Item总个数");
  162. put( "curr_items", "当前存储的Item个数");
  163. put( "cmd_get", "服务器本次启动以来,执行Get命令总次数");
  164. put( "get_hits", "服务器本次启动以来,Get操作的命中次数");
  165. put( "get_misses", "服务器本次启动以来,Get操作的未命中次数");
  166. put( "cmd_set", "服务器本次启动以来,执行Set命令总次数");
  167. }
  168. };
  169. }
  170. /**
  171. * @category 保护型构造方法,不允许实例化!
  172. */
  173. protected MemCached() {
  174. }
  175. /**
  176. * @category 操作类入口:获取唯一实例.
  177. *
  178. * @return MemCached对象
  179. */
  180. public static MemCached getInstance() {
  181. return memCached;
  182. }
  183. /**
  184. * @category 返回是否已经启用memcached内存服务器
  185. *
  186. * @return boolean
  187. */
  188. public static boolean used(){
  189. return enUsed;
  190. }
  191. /**
  192. * @category 插入新记录.
  193. * @category 前提:记录的Key在缓存中不存在
  194. * @param key 记录的主键
  195. * @param value 记录的内容
  196. * @return boolean 操作结果
  197. */
  198. public boolean add(String key, Object value) {
  199. if(!enUsed){
  200. return false;
  201. } else{
  202. return memClient.add(key, value);
  203. }
  204. }
  205. /**
  206. * @category 插入新记录并设置超时日期
  207. * @category 前提:记录的Key在缓存中不存在
  208. * @param key 记录的主键
  209. * @param value 记录的内容
  210. * @param expiryDate 超时日期
  211. * @return boolean 操作结果
  212. */
  213. public boolean add(String key, Object value, Date expiryDate) {
  214. if(!enUsed){
  215. return false;
  216. } else{
  217. return memClient.add(key, value, expiryDate);
  218. }
  219. }
  220. /**
  221. * @category 插入新记录并设置超时天数
  222. * @category 前提:记录的Key在缓存中不存在
  223. * @param key 记录的主键
  224. * @param value 记录的内容
  225. * @param expiryDays 超时天数
  226. * @return boolean 操作结果
  227. */
  228. public boolean add(String key, Object value, int expiryDays){
  229. if(!enUsed){
  230. return false;
  231. } else{
  232. Calendar calendar = Calendar.getInstance();
  233. calendar.setTime( new Date());
  234. calendar.add(Calendar.DATE,expiryDays); //增加天数
  235. return memClient.add(key, value, calendar.getTime());
  236. }
  237. }
  238. /**
  239. * @category 插入新记录或更新已有记录
  240. * @category 解释:记录的Key在缓存中不存在则插入;否则更新
  241. * @param key 记录的主键
  242. * @param value 记录的内容
  243. * @return boolean 操作结果
  244. */
  245. public boolean set(String key, Object value){
  246. if(!enUsed){
  247. return false;
  248. } else{
  249. return memClient.set(key, value);
  250. }
  251. }
  252. /**
  253. * @category 插入新记录或更新已有记录,并设置超时日期
  254. * @category 解释:记录的Key在缓存中不存在则插入;否则更新
  255. * @param key 记录的主键
  256. * @param value 记录的内容
  257. * @param expiryDate 超时日期
  258. * @return boolean 操作结果
  259. */
  260. public boolean set(String key, Object value, Date expiryDate){
  261. if(!enUsed){
  262. return false;
  263. } else{
  264. return memClient.set(key, value, expiryDate);
  265. }
  266. }
  267. /**
  268. * @category 插入新记录或更新已有记录,并设置超时天数
  269. * @category 解释:记录的Key在缓存中不存在则插入;否则更新
  270. * @param key 记录的主键
  271. * @param value 记录的内容
  272. * @param expiryDate 超时天数
  273. * @return boolean 操作结果
  274. */
  275. public boolean set(String key, Object value, int expiryDays){
  276. if(!enUsed){
  277. return false;
  278. } else{
  279. Calendar calendar = Calendar.getInstance();
  280. calendar.setTime( new Date());
  281. calendar.add(Calendar.DATE,expiryDays); //增加天数
  282. return memClient.set(key, value, calendar.getTime());
  283. }
  284. }
  285. /**
  286. * @category 更新已有记录
  287. * @category 前提:记录的Key在缓存中已经存在
  288. * @param key 记录的主键
  289. * @param value 记录的内容
  290. * @return boolean 操作结果
  291. */
  292. public boolean replace(String key, Object value) {
  293. if(!enUsed){
  294. return false;
  295. } else{
  296. return memClient.replace(key, value);
  297. }
  298. }
  299. /**
  300. * @category 更新已有记录,并设置超时日期
  301. * @category 前提:该值在缓存中已经存在
  302. * @param key 记录的主键
  303. * @param value 记录的内容
  304. * @param expiryDate 超时日期
  305. * @return boolean 操作结果
  306. */
  307. public boolean replace(String key, Object value, Date expiryDate) {
  308. if(!enUsed){
  309. return false;
  310. } else{
  311. return memClient.replace(key, value, expiryDate);
  312. }
  313. }
  314. /**
  315. * @category 更新已有记录,并设置超时天数
  316. * @category 前提:该值在缓存中已经存在
  317. * @param key 记录的主键
  318. * @param value 记录的内容
  319. * @param expiryDays 超时天数
  320. * @return boolean 操作结果
  321. */
  322. public boolean replace(String key, Object value, int expiryDays) {
  323. if(!enUsed){
  324. return false;
  325. } else{
  326. Calendar calendar = Calendar.getInstance();
  327. calendar.setTime( new Date());
  328. calendar.add(Calendar.DATE,expiryDays); //增加天数
  329. return memClient.replace(key, value, calendar.getTime());
  330. }
  331. }
  332. /**
  333. * @category 返回单条记录
  334. *
  335. * @param key 记录的主键
  336. * @return 记录的内容
  337. */
  338. public Object get(String key) {
  339. if(!enUsed){
  340. return null;
  341. } else{
  342. return memClient.get(key);
  343. }
  344. }
  345. /**
  346. * @category 返回多条记录
  347. *
  348. * @param keys 记录的主键数组
  349. * @return Map<String, Object> 多条记录的内容
  350. */
  351. public Map<String, Object> get(String[] keys) {
  352. if(!enUsed){
  353. return null;
  354. } else{
  355. return memClient.getMulti(keys);
  356. }
  357. }
  358. /**
  359. * @category 返回所有key值
  360. *
  361. * @return Arraylist<String> 多条记录的内容
  362. */
  363. public static ArrayList<String> getAllKey() {
  364. if(!enUsed){
  365. return null;
  366. } else{
  367. ArrayList<String> list = new ArrayList<String>();
  368. Map<String, Map<String, String>> items = memClient.statsItems();
  369. for (Iterator<String> itemIt = items.keySet().iterator(); itemIt.hasNext();) {
  370. String itemKey = itemIt.next();
  371. Map<String, String> maps = items.get(itemKey);
  372. for (Iterator<String> mapsIt = maps.keySet().iterator(); mapsIt.hasNext();) {
  373. String mapsKey = mapsIt.next();
  374. String mapsValue = maps.get(mapsKey);
  375. if (mapsKey.endsWith( "number")) { //memcached key 类型 item_str:integer:number_str
  376. String[] arr = mapsKey.split( ":");
  377. int slabNumber = Integer.valueOf(arr[ 1].trim());
  378. int limit = Integer.valueOf(mapsValue.trim());
  379. Map<String, Map<String, String>> dumpMaps = memClient.statsCacheDump(slabNumber, limit);
  380. for (Iterator<String> dumpIt = dumpMaps.keySet().iterator(); dumpIt.hasNext();) {
  381. String dumpKey = dumpIt.next();
  382. Map<String, String> allMap = dumpMaps.get(dumpKey);
  383. for (Iterator<String> allIt = allMap.keySet().iterator(); allIt.hasNext();) {
  384. String allKey = allIt.next();
  385. list.add(allKey.trim());
  386. }
  387. }
  388. }
  389. }
  390. }
  391. return list;
  392. }
  393. }
  394. /**
  395. * 获取存储的key值
  396. * 已存在的prefix:FlightFocusInfo
  397. * 新增加的prefix命名时需确保唯一性,避免取值出问题
  398. */
  399. public static String getKey(String prefix,ArrayList<String> parms) {
  400. StringBuffer generateKey = new StringBuffer( "");
  401. if(!ToolUtil.isNull(parms)){
  402. Iterator<String> itr = parms.iterator();
  403. generateKey=generateKey.append(prefix).append( "_");
  404. while(itr.hasNext()){
  405. generateKey.append(itr.next()).append( "_");
  406. }
  407. }
  408. return generateKey.toString();
  409. }
  410. /**
  411. * 匹配符合条件的key值
  412. */
  413. public static ArrayList<String> matchKey(String prefix,ArrayList<String> parms) {
  414. ArrayList<String> matchKeys = new ArrayList<String>();
  415. if(!ToolUtil.isNull(parms)){
  416. ArrayList<String> keys = new ArrayList<String>();
  417. boolean findFlag = true;
  418. parms.add(prefix);
  419. keys = getAllKey();
  420. Iterator<String> keysItr = keys.iterator();
  421. while(keysItr.hasNext()){
  422. String key = keysItr.next();
  423. String[] k = key.split( "_");
  424. List k_a = Arrays.asList(k);
  425. Iterator<String> parmsItr = parms.iterator();
  426. while(parmsItr.hasNext()){
  427. if(!k_a.contains(parmsItr.next())){
  428. findFlag = false;
  429. }
  430. }
  431. if(findFlag){
  432. matchKeys.add(key);
  433. }
  434. findFlag = true;
  435. }
  436. }
  437. return matchKeys;
  438. }
  439. /**
  440. * @category 删除记录
  441. * @category 执行该方法之后,使用stats的统计结果会同步更新
  442. * @param key 记录的主键
  443. * @return 操作结果
  444. */
  445. public boolean delete(String key){
  446. if(!enUsed){
  447. return false;
  448. } else{
  449. return memClient.delete(key);
  450. }
  451. }
  452. /*
  453. * ****************************************************************************************************************
  454. * 下面的6个方法都是为了对memcached服务器进行监控及管理所用的,可能对服务器造成阻塞,所以除Debug以外,不推荐使用!
  455. */
  456. /**
  457. * @category 清空全部缓存数据。*慎用!!
  458. * @category 执行该方法之后,使用stats的统计结果不会马上发生变化,每get一个不存在的item之后,该item的值才会被动清空
  459. * @return 操作结果
  460. */
  461. public boolean flushAll(){
  462. if(!enUsed){
  463. return false;
  464. } else{
  465. return memClient.flushAll();
  466. }
  467. }
  468. /**
  469. * @category 返回可用的服务器列表
  470. * @return 数组(服务器地址:端口)
  471. */
  472. public String[] servers(){
  473. if(!enUsed) return null;
  474. return serverListArr;
  475. }
  476. /**
  477. * @category 返回所有缓存服务器当前的运行状态
  478. * @return
  479. *
  480. * Map
  481. * |-- Key : ServerName01, Value : LinkedHashMap
  482. * | |-- Key : statName01, Value : statValue
  483. * | |-- ...
  484. * |
  485. * |-- Key : ServerName02, Value : LinkedHashMap
  486. * | |-- Key : statName01, Value : statValue
  487. * | |-- ...
  488. * |
  489. * |-- ...
  490. *
  491. */
  492. public Map<String,LinkedHashMap<String, String>> stats(){
  493. if(!enUsed) return null;
  494. Map<String,LinkedHashMap<String, String>> retMap = new HashMap<String,LinkedHashMap<String, String>>();
  495. for(String server : serverListArr){
  496. LinkedHashMap<String, String> serverStats = this.stats(server);
  497. retMap.put(server, serverStats);
  498. }
  499. return retMap;
  500. }
  501. /**
  502. * @category 返回指定服务器当前的运行状态
  503. * @param server 服务器地址:端口
  504. *
  505. * 优化: 参数名称中文显示
  506. * 优化: 毫秒数转换为小时
  507. * 优化: 字节数转换为MB或KB
  508. * 优化: UNIX时间戳转换为标准时间
  509. * 优化: 参数显示顺序更加直观
  510. *
  511. * @return LinkedHashMap<String, String> 可对Map进行有序遍历
  512. *
  513. */
  514. public LinkedHashMap<String, String> stats(String server){
  515. if(!enUsed) return null;
  516. LinkedHashMap<String, String> retMap = new LinkedHashMap<String, String>();
  517. Map<String, Map<String, String>> statsList = memClient.stats( new String[]{server});
  518. //System.out.println(memClient.stats().toString());
  519. DecimalFormat format = new DecimalFormat( "0.0");
  520. for(Object serverTitle : statsList.keySet().toArray()){
  521. Map<String, String> serverStats = (Map<String, String>)statsList.get(serverTitle);
  522. retMap.put(statsItems.get( "pid"), serverStats.get( "pid").replaceAll( "\\r\\n", ""));
  523. retMap.put(statsItems.get( "version"), serverStats.get( "version").replaceAll( "\\r\\n", ""));
  524. retMap.put(statsItems.get( "pointer_size"), serverStats.get( "pointer_size").replaceAll( "\\r\\n", "") + "位");
  525. retMap.put(statsItems.get( "time"), new java.text.SimpleDateFormat( "yyyy-MM-dd HH:mm:ss").format( new Date(Long.parseLong(serverStats.get( "time").replaceAll( "\\r\\n", "")) * 1000)).toString());
  526. retMap.put(statsItems.get( "uptime"), format.format(Double.parseDouble(serverStats.get( "uptime").replaceAll( "\\r\\n", ""))/( 60* 60)) + "小时");
  527. retMap.put(statsItems.get( "connection_structures"), serverStats.get( "connection_structures").replaceAll( "\\r\\n", ""));
  528. retMap.put(statsItems.get( "total_connections"), serverStats.get( "total_connections").replaceAll( "\\r\\n", ""));
  529. retMap.put(statsItems.get( "curr_connections"), serverStats.get( "curr_connections").replaceAll( "\\r\\n", ""));
  530. retMap.put(statsItems.get( "limit_maxbytes"), format.format(Double.parseDouble(serverStats.get( "limit_maxbytes").replaceAll( "\\r\\n", ""))/( 1024* 1024)) + "MB");
  531. retMap.put(statsItems.get( "bytes"), format.format(Double.parseDouble(serverStats.get( "bytes").replaceAll( "\\r\\n", ""))/( 1024* 1024)) + "MB");
  532. retMap.put(statsItems.get( "bytes_written"), format.format(Double.parseDouble(serverStats.get( "bytes_written").replaceAll( "\\r\\n", ""))/( 1024)) + "KB");
  533. retMap.put(statsItems.get( "bytes_read"), format.format(Double.parseDouble(serverStats.get( "bytes_read").replaceAll( "\\r\\n", ""))/( 1024)) + "KB");
  534. retMap.put(statsItems.get( "total_items"), serverStats.get( "total_items").replaceAll( "\\r\\n", ""));
  535. retMap.put(statsItems.get( "curr_items"), serverStats.get( "curr_items").replaceAll( "\\r\\n", ""));
  536. retMap.put(statsItems.get( "cmd_get"), serverStats.get( "cmd_get").replaceAll( "\\r\\n", ""));
  537. retMap.put(statsItems.get( "get_hits"), serverStats.get( "get_hits").replaceAll( "\\r\\n", ""));
  538. retMap.put(statsItems.get( "get_misses"), serverStats.get( "get_misses").replaceAll( "\\r\\n", ""));
  539. retMap.put(statsItems.get( "cmd_set"), serverStats.get( "cmd_set").replaceAll( "\\r\\n", ""));
  540. }
  541. return retMap;
  542. }
  543. /**
  544. * @category 返回指定服务器及Slab中当前使用的item列表
  545. * @param server 服务器地址:端口
  546. * @param slab SlabId
  547. * @param counter 最多显示items条数
  548. * @return
  549. */
  550. public LinkedList<String> items(String server, int slab, int counter){
  551. if(!enUsed) return null;
  552. LinkedList<String> ret = new LinkedList<String>();
  553. Map<String, String> itemsKey = memClient.statsCacheDump( new String[]{server}, slab, counter).get(server);
  554. for(Object key : itemsKey.keySet().toArray()){
  555. ret.add(key.toString());
  556. }
  557. return ret;
  558. }
  559. /**
  560. * @category 返回指定服务器当前使用的SlabsID列表
  561. * @param server 服务器地址:端口
  562. * @return
  563. */
  564. public LinkedList<Integer> slabs(String server){
  565. if(!enUsed) return null;
  566. LinkedList<Integer> slabsId = new LinkedList<Integer>();
  567. Map<String, String> itemsMap = memClient.statsItems( new String[]{server}).get(server);
  568. Object[] itemsArr = itemsMap.keySet().toArray();
  569. for( int i= 0, len=itemsArr.length; i<len; i+= 2){
  570. slabsId.add(Integer.parseInt(itemsArr[i].toString().split( ":")[ 1]));
  571. }
  572. return slabsId;
  573. }
  574. /*
  575. * 上面的6个方法都是为了对memcached服务器进行监控及管理所用的,可能对服务器造成阻塞,所以除Debug以外,不推荐使用!
  576. * ****************************************************************************************************************
  577. */
  578. /**
  579. * 使用示例
  580. */
  581. public static void main(String[] args) {
  582. //初始化memcached操作类对象
  583. MemCached cache = MemCached.getInstance();
  584. //验证memcached服务是否已启用
  585. if(!cache.used()){
  586. System.out.println( "memcached服务未启用!");
  587. return;
  588. }
  589. //插入新记录
  590. System.out.println( "开始插入新记录(add):\r\n===================================");
  591. System.out.println( "keyTest01:" + cache.add( "keyTest01", "keyTest01Content"));
  592. System.out.println( "keyTest02:" + cache.add( "keyTest02", "keyTest02Content"));
  593. System.out.println( "插入新记录操作完成\r\n===================================");
  594. //读取单条记录
  595. System.out.println( "读取单条记录(get):\r\n===================================");
  596. System.out.println( "keyTest01:" + cache.get( "keyTest01"));
  597. System.out.println( "keyTest02:" + cache.get( "keyTest02"));
  598. System.out.println( "读取单条记录操作完成\r\n===================================");
  599. //读取多条记录
  600. System.out.println( "读取多条记录(add):\r\n===================================");
  601. System.out.println( "keyTest01、keyTest02:" + cache.get( new String[]{ "keyTest01", "keyTest02"}));
  602. System.out.println( "读取多条记录操作完成\r\n===================================");
  603. //修改记录值
  604. System.out.println( "修改记录值(replace):\r\n===================================");
  605. System.out.println( "keyTest01:" + cache.get( "keyTest01"));
  606. System.out.println( "keyTest01:" + cache.replace( "keyTest01", "keyTest01ContentReplace!"));
  607. System.out.println( "keyTest01:" + cache.get( "keyTest01"));
  608. System.out.println( "修改记录值操作完成\r\n===================================");
  609. //添加或修改记录
  610. System.out.println( "添加或修改记录(set):\r\n===================================");
  611. System.out.println( "keyTest03:" + cache.set( "keyTest03", "keyTest03Content"));
  612. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  613. System.out.println( "keyTest03:" + cache.set( "keyTest03", "keyTest03ContentReplace!"));
  614. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  615. System.out.println( "添加或修改记录操作完成\r\n===================================");
  616. //删除记录
  617. System.out.println( "删除记录(delete):\r\n===================================");
  618. System.out.println( "keyTest01:" + cache.delete( "keyTest01"));
  619. System.out.println( "keyTest02:" + cache.delete( "keyTest02"));
  620. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  621. System.out.println( "keyTest03:" + cache.delete( "keyTest03"));
  622. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  623. System.out.println( "修改记录值操作完成\r\n===================================");
  624. //打印当前的服务器参数及统计信息
  625. System.out.println( "服务器参数及统计信息(stats):\r\n===================================");
  626. Map statsList = cache.stats();
  627. for(Object server : statsList.keySet().toArray()){
  628. System.out.println( "-------------------------\r\n服务器:" + server + " : \r\n-------------------------");
  629. LinkedHashMap serverStats = (LinkedHashMap)statsList.get(server);
  630. for(Object statKey : serverStats.keySet().toArray()){
  631. System.out.println(statKey + " : " + serverStats.get(statKey));
  632. }
  633. }
  634. }
  635. }


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BobChao0730/article/details/51062697

一、windows下安装

环境:win7专业版+memcached_win32_1.4.5

步骤:

1、cmd切换到指定解压目录
2、memcached -d install安装
3、输入memcached –h,出现下图窗口说明已经安装成功

memcached的使用_服务器

4、telnet测试是否正常运行 telnet 127.0.0.1 11211 如下图:

memcached的使用_sed_02

memcached的使用_sed_03

5、stats命令查看运行状态如下图:

memcached的使用_服务器_04

二、linux下安装

环境:redhat5+memcached-1.4.25
所需安装包:
步骤:
1、解压libevent
tar -zxvf libevent-2.0.21-stable.tar.gz  
2、安装libevent
./configure --prefix /etc/libevent/  
make clean  
make  
make install 
3、解压memcached
tar -zxvf memcached-1.4.21.tar.gz
4、安装memcached
./configure --prefix /etc/memcached/ --with-libevent=/etc/libevent/  
make clean  
make  
make install
5.启动memcached
cd /etc/memcached/bin  
./memcached -d -u root
6.telnet看memcached是否启动成功,stat查看运行状态
 
7.查看memcached运行的进程
8.关闭memcached
三、使用memcached
http://www.cnblogs.com/netWild/archive/2013/05/14/memcached.html
3.1 所需jar包
3.2 MemCachedConfig.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. ***** memcached数据库配置文件 *****
  4. ***********************************
  5. -->
  6. <MemCachedConfig>
  7. <!--
  8. Enabled : 是否启用memcached内存数据库选项
  9. 可选值 : true - 启用; false - 停用
  10. -->
  11. <Enabled>true </Enabled>
  12. <!--
  13. Servers : 可用的memcached服务器列表,各服务器根据weight(负载权重值)实现分布式任务均衡
  14. 注意 : 各memcached服务器负载权重值的最大公约数最好为1,可在一定程度上简化其内部的负载均衡算法
  15. 规则 : <Server host="memcached服务器IP或域名" post="memcached服务端口(默认11211)" weight="负载权重值" />
  16. -->
  17. <Servers>
  18. <!--
  19. <Server host="192.168.1.10" post="11211" weight="2" />
  20. <Server host="192.168.1.11" post="11211" weight="1" />
  21. <Server host="192.168.1.12" post="11211" weight="1" />
  22. -->
  23. <Server host="192.168.78.128" post="11211" weight="1" />
  24. </Servers>
  25. <!--
  26. Config : memcached数据库配置选项
  27. initConn : 初始连接数
  28. minConn : 最小连接数
  29. maxConn : 最大连接数
  30. maxIdle : 连接最大空闲时间(毫秒)
  31. maintSleep : 主线程的维护周期(每隔多少秒维护一次连接池,0表示不启用主线程)
  32. socketTO : 读取操作的超时限制(毫秒)
  33. socketConnTO : 连接操作的超时限制(毫秒,0表示不限制)
  34. compressEnable : 是否启用自动压缩(该参数从java_memcached-release_2.6.1开始不再支持)
  35. compressThreshold : 超过指定大小(bytes)的数据都会被压缩(该参数从java_memcached-release_2.6.1开始不再支持)
  36. -->
  37. <Config>
  38. <property name="initConn">5 </property>
  39. <property name="minConn">5 </property>
  40. <property name="maxConn">250 </property>
  41. <property name="maxIdle">21600000 </property>
  42. <property name="maintSleep">30 </property>
  43. <property name="socketTO">10000 </property>
  44. <property name="socketConnTO">0 </property>
  45. <property name="compressEnable">true </property>
  46. <property name="compressThreshold">65536 </property>
  47. </Config>
  48. </MemCachedConfig>
3.3 MemCached.java
  1. package com.kysis.util;
  2. import java.io.File;
  3. import java.text.DecimalFormat;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.Calendar;
  7. import java.util.Iterator;
  8. import java.util.LinkedList;
  9. import java.util.List;
  10. import java.util.Date;
  11. import java.util.HashMap;
  12. import java.util.LinkedHashMap;
  13. import java.util.Map;
  14. import org.apache.commons.net.telnet.TelnetClient;
  15. import org.dom4j.Document;
  16. import org.dom4j.Element;
  17. import org.dom4j.Node;
  18. import org.dom4j.io.SAXReader;
  19. import com.danga.MemCached.MemCachedClient;
  20. import com.danga.MemCached.SockIOPool;
  21. /**
  22. * @category memcached内存数据库操作类
  23. * @version 1.0
  24. */
  25. public class MemCached {
  26. //是否启用MemCached内存数据库
  27. protected static boolean enUsed = true;
  28. //创建全局唯一的可实例化对象
  29. protected static MemCached memCached = new MemCached();
  30. //初始化MemCached客户端对象
  31. protected static MemCachedClient memClient = new MemCachedClient();
  32. //定义MemCached服务器运行环境配置文件名称
  33. private static final String MemCachedConfigFile_NAME = "MemCachedConfig.xml";
  34. //定义可用的MemCached服务器列表,用于分布式存储
  35. private static String[] serverListArr = new String[ 1];
  36. //定义各MemCached服务器的负载权重列表,与服务器列表按先后顺序对应
  37. private static Integer[] weightListArr = new Integer[ 1];;
  38. //定义MemCached服务器运行环境表,配置文件中关于参数相关数据将保存到该表
  39. private static Map<String, String> serverConfig;
  40. //定义MemCached服务器运行状态表,用于保存各状态的中文解释
  41. protected static HashMap<String, String> statsItems;
  42. //设置全局静态参数,以下代码在整个服务器运行周期内仅运行一次!
  43. static {
  44. //初始化MemCached运行环境配置
  45. //首先初始化各参数默认值,然后加载配置文件,遍历其中的参数值并进行覆盖。
  46. initConfig();
  47. if(enUsed){ //如果已启用memcached缓存服务
  48. //获取socke连接池的实例对象
  49. SockIOPool pool = SockIOPool.getInstance();
  50. //设置可用的MemCached服务器信息,实现分布式存储
  51. pool.setServers(serverListArr);
  52. //设置各MemCached服务器的负载权重,根据可支配内存实现负载均衡
  53. pool.setWeights(weightListArr);
  54. //设置初始连接数
  55. pool.setInitConn(Integer.parseInt(serverConfig.get( "initConn").toString()));
  56. //设置最小连接数
  57. pool.setMinConn(Integer.parseInt(serverConfig.get( "minConn").toString()));
  58. //设置最大连接数
  59. pool.setMaxConn(Integer.parseInt(serverConfig.get( "maxConn").toString()));
  60. //设置连接最大空闲时间
  61. pool.setMaxIdle(Long.parseLong(serverConfig.get( "maxIdle").toString()));
  62. //设置主线程的睡眠时间,每隔该时间维护一次各连接线程状态
  63. pool.setMaintSleep(Long.parseLong(serverConfig.get( "maintSleep").toString()));
  64. //关闭nagle算法
  65. pool.setNagle( false);
  66. //读取操作的超时限制
  67. pool.setSocketTO(Integer.parseInt(serverConfig.get( "socketTO").toString()));
  68. //连接操作的超时限制,0为不限制
  69. pool.setSocketConnectTO(Integer.parseInt(serverConfig.get( "socketConnTO").toString()));
  70. //初始化连接池
  71. pool.initialize();
  72. //压缩设置,超过指定大小的数据都会被压缩
  73. //从java_memcached-release_2.6.1开始已经不再支持内置的数据压缩功能
  74. //memClient.setCompressEnable(Boolean.parseBoolean(serverConfig.get("compressEnable").toString()));
  75. //memClient.setCompressThreshold(Long.parseLong(serverConfig.get("compressThreshold").toString()));
  76. }
  77. }
  78. /**
  79. * @category 初始化MemCached运行环境配置
  80. * @category 注:该方法在整个服务器周期内仅运行一次
  81. */
  82. protected static void initConfig(){
  83. //初始化可用的MemCached服务器列表默认值(本机)
  84. serverListArr[ 0] = "127.0.0.1:11211";
  85. weightListArr[ 0] = 1;
  86. //初始化MemCached服务器运行环境表(默认值),当某参数未在配置文件中进行定义时,将使用该默认值
  87. serverConfig = new HashMap<String, String>(){
  88. private static final long serialVersionUID = 1L;
  89. {
  90. put( "initConn", "5"); //设置初始连接数
  91. put( "minConn", "5"); //设置最小连接数
  92. put( "maxConn", "250"); //设置最大连接数
  93. put( "maxIdle", "21600000"); //设置连接最大空闲时间(6小时)
  94. put( "maintSleep", "30"); //设置主线程的睡眠时间(30秒)
  95. put( "socketTO", "10000"); //读取操作的超时限制(10秒)
  96. put( "socketConnTO", "0"); //连接操作的超时限制(不限制)
  97. put( "compressEnable", "true"); //是否启用自动压缩(启用)
  98. put( "compressThreshold", "65536"); //超过指定大小的数据都会被压缩(64K)
  99. }
  100. };
  101. //开始读取配置文件,并将其中的参数值向默认环境表中进行覆盖
  102. String filePath = Thread.currentThread().getContextClassLoader().getResource( "MemCachedConfig.xml").getPath().substring( 1);
  103. File file = new File(filePath.replaceAll( "%20", " "));
  104. try{
  105. if(file.exists()){ //如果可以成功加载配置文件
  106. SAXReader sr = new SAXReader();
  107. Document doc = sr.read(file);
  108. Element Root = doc.getRootElement(); //获得根节点
  109. Element Enabled = (Element)Root.selectSingleNode( "Enabled"); //获得是否启用memcached节点
  110. Element Servers = (Element)Root.selectSingleNode( "Servers"); //获得可用的服务器列表父节点
  111. Element Config = (Element)Root.selectSingleNode( "Config"); //获得运行环境参数列表父节点
  112. enUsed = Boolean.parseBoolean(Enabled.getText()); //是否启用memcached缓存服务
  113. List<Element> serverDoms = Servers.elements(); //备用的服务器列表
  114. List<Element> serverUsed = new ArrayList<Element>(); //经检测,实际可用的服务器列表
  115. TelnetClient telnet = new TelnetClient(); //初始化Telnet对象,用来检测服务器是否可以成功连接
  116. telnet.setConnectTimeout( 5000); //连接超时:5秒
  117. for(Element serverTmp : serverDoms){
  118. try{
  119. telnet.connect(serverTmp.attributeValue( "host"), Integer.parseInt(serverTmp.attributeValue( "post"))); //连接到服务器
  120. telnet.disconnect(); //断开连接
  121. serverUsed.add(serverTmp); //连接成功,将服务器添加到实际可用列表
  122. } catch(Exception e){}
  123. }
  124. int serverCount = serverUsed.size(); //经检测,实际可用的服务器个数
  125. if(serverCount == 0){ //没有发现实际可用的服务器,返回
  126. enUsed = false;
  127. return;
  128. }
  129. serverListArr = new String[serverCount]; //初始化服务器地址及端口号数组
  130. weightListArr = new Integer[serverCount]; //初始化服务器负载权重数组
  131. for( int ind= 0; ind < serverCount; ind++){ //向服务器数组进行赋值
  132. serverListArr[ind] = serverUsed.get(ind).attributeValue( "host") + ":" + serverUsed.get(ind).attributeValue( "post");
  133. weightListArr[ind] = Integer.parseInt(serverUsed.get(ind).attributeValue( "weight").toString());
  134. }
  135. Object[] serverConfigArr = serverConfig.keySet().toArray(); //返回服务器运行环境参数列表,用于遍历配置文件
  136. for(Object cfgItem : serverConfigArr){
  137. Node node = Config.selectSingleNode( "//property[@name='" + cfgItem + "']"); //查找指定的参数节点
  138. if(node == null) continue; //如果该参数节点不存在,则继续查找下一个参数,该参数将采用默认值
  139. Element configNode = (Element)node;
  140. serverConfig.put(cfgItem.toString(), configNode.getTextTrim()); //添加配置文件中定义的参数值
  141. }
  142. }
  143. } catch(Exception e){
  144. System.out.println(e.toString());
  145. }
  146. //初始化MemCached服务器运行状态表,对各状态进行中文解释
  147. statsItems = new HashMap<String, String>(){
  148. {
  149. put( "pid", "MemCached服务进程ID");
  150. put( "version", "MemCached服务版本");
  151. put( "pointer_size", "MemCached服务器架构");
  152. put( "time", "服务器当前时间");
  153. put( "uptime", "服务器本次启动以来,总共运行时间");
  154. put( "connection_structures", "服务器分配的连接结构数");
  155. put( "total_connections", "服务器本次启动以来,累计响应连接总次数");
  156. put( "curr_connections", "当前打开的连接数");
  157. put( "limit_maxbytes", "允许服务支配的最大内存容量");
  158. put( "bytes", "当前已使用的内存容量");
  159. put( "bytes_written", "服务器本次启动以来,写入的数据量");
  160. put( "bytes_read", "服务器本次启动以来,读取的数据量");
  161. put( "total_items", "服务器本次启动以来,曾存储的Item总个数");
  162. put( "curr_items", "当前存储的Item个数");
  163. put( "cmd_get", "服务器本次启动以来,执行Get命令总次数");
  164. put( "get_hits", "服务器本次启动以来,Get操作的命中次数");
  165. put( "get_misses", "服务器本次启动以来,Get操作的未命中次数");
  166. put( "cmd_set", "服务器本次启动以来,执行Set命令总次数");
  167. }
  168. };
  169. }
  170. /**
  171. * @category 保护型构造方法,不允许实例化!
  172. */
  173. protected MemCached() {
  174. }
  175. /**
  176. * @category 操作类入口:获取唯一实例.
  177. *
  178. * @return MemCached对象
  179. */
  180. public static MemCached getInstance() {
  181. return memCached;
  182. }
  183. /**
  184. * @category 返回是否已经启用memcached内存服务器
  185. *
  186. * @return boolean
  187. */
  188. public static boolean used(){
  189. return enUsed;
  190. }
  191. /**
  192. * @category 插入新记录.
  193. * @category 前提:记录的Key在缓存中不存在
  194. * @param key 记录的主键
  195. * @param value 记录的内容
  196. * @return boolean 操作结果
  197. */
  198. public boolean add(String key, Object value) {
  199. if(!enUsed){
  200. return false;
  201. } else{
  202. return memClient.add(key, value);
  203. }
  204. }
  205. /**
  206. * @category 插入新记录并设置超时日期
  207. * @category 前提:记录的Key在缓存中不存在
  208. * @param key 记录的主键
  209. * @param value 记录的内容
  210. * @param expiryDate 超时日期
  211. * @return boolean 操作结果
  212. */
  213. public boolean add(String key, Object value, Date expiryDate) {
  214. if(!enUsed){
  215. return false;
  216. } else{
  217. return memClient.add(key, value, expiryDate);
  218. }
  219. }
  220. /**
  221. * @category 插入新记录并设置超时天数
  222. * @category 前提:记录的Key在缓存中不存在
  223. * @param key 记录的主键
  224. * @param value 记录的内容
  225. * @param expiryDays 超时天数
  226. * @return boolean 操作结果
  227. */
  228. public boolean add(String key, Object value, int expiryDays){
  229. if(!enUsed){
  230. return false;
  231. } else{
  232. Calendar calendar = Calendar.getInstance();
  233. calendar.setTime( new Date());
  234. calendar.add(Calendar.DATE,expiryDays); //增加天数
  235. return memClient.add(key, value, calendar.getTime());
  236. }
  237. }
  238. /**
  239. * @category 插入新记录或更新已有记录
  240. * @category 解释:记录的Key在缓存中不存在则插入;否则更新
  241. * @param key 记录的主键
  242. * @param value 记录的内容
  243. * @return boolean 操作结果
  244. */
  245. public boolean set(String key, Object value){
  246. if(!enUsed){
  247. return false;
  248. } else{
  249. return memClient.set(key, value);
  250. }
  251. }
  252. /**
  253. * @category 插入新记录或更新已有记录,并设置超时日期
  254. * @category 解释:记录的Key在缓存中不存在则插入;否则更新
  255. * @param key 记录的主键
  256. * @param value 记录的内容
  257. * @param expiryDate 超时日期
  258. * @return boolean 操作结果
  259. */
  260. public boolean set(String key, Object value, Date expiryDate){
  261. if(!enUsed){
  262. return false;
  263. } else{
  264. return memClient.set(key, value, expiryDate);
  265. }
  266. }
  267. /**
  268. * @category 插入新记录或更新已有记录,并设置超时天数
  269. * @category 解释:记录的Key在缓存中不存在则插入;否则更新
  270. * @param key 记录的主键
  271. * @param value 记录的内容
  272. * @param expiryDate 超时天数
  273. * @return boolean 操作结果
  274. */
  275. public boolean set(String key, Object value, int expiryDays){
  276. if(!enUsed){
  277. return false;
  278. } else{
  279. Calendar calendar = Calendar.getInstance();
  280. calendar.setTime( new Date());
  281. calendar.add(Calendar.DATE,expiryDays); //增加天数
  282. return memClient.set(key, value, calendar.getTime());
  283. }
  284. }
  285. /**
  286. * @category 更新已有记录
  287. * @category 前提:记录的Key在缓存中已经存在
  288. * @param key 记录的主键
  289. * @param value 记录的内容
  290. * @return boolean 操作结果
  291. */
  292. public boolean replace(String key, Object value) {
  293. if(!enUsed){
  294. return false;
  295. } else{
  296. return memClient.replace(key, value);
  297. }
  298. }
  299. /**
  300. * @category 更新已有记录,并设置超时日期
  301. * @category 前提:该值在缓存中已经存在
  302. * @param key 记录的主键
  303. * @param value 记录的内容
  304. * @param expiryDate 超时日期
  305. * @return boolean 操作结果
  306. */
  307. public boolean replace(String key, Object value, Date expiryDate) {
  308. if(!enUsed){
  309. return false;
  310. } else{
  311. return memClient.replace(key, value, expiryDate);
  312. }
  313. }
  314. /**
  315. * @category 更新已有记录,并设置超时天数
  316. * @category 前提:该值在缓存中已经存在
  317. * @param key 记录的主键
  318. * @param value 记录的内容
  319. * @param expiryDays 超时天数
  320. * @return boolean 操作结果
  321. */
  322. public boolean replace(String key, Object value, int expiryDays) {
  323. if(!enUsed){
  324. return false;
  325. } else{
  326. Calendar calendar = Calendar.getInstance();
  327. calendar.setTime( new Date());
  328. calendar.add(Calendar.DATE,expiryDays); //增加天数
  329. return memClient.replace(key, value, calendar.getTime());
  330. }
  331. }
  332. /**
  333. * @category 返回单条记录
  334. *
  335. * @param key 记录的主键
  336. * @return 记录的内容
  337. */
  338. public Object get(String key) {
  339. if(!enUsed){
  340. return null;
  341. } else{
  342. return memClient.get(key);
  343. }
  344. }
  345. /**
  346. * @category 返回多条记录
  347. *
  348. * @param keys 记录的主键数组
  349. * @return Map<String, Object> 多条记录的内容
  350. */
  351. public Map<String, Object> get(String[] keys) {
  352. if(!enUsed){
  353. return null;
  354. } else{
  355. return memClient.getMulti(keys);
  356. }
  357. }
  358. /**
  359. * @category 返回所有key值
  360. *
  361. * @return Arraylist<String> 多条记录的内容
  362. */
  363. public static ArrayList<String> getAllKey() {
  364. if(!enUsed){
  365. return null;
  366. } else{
  367. ArrayList<String> list = new ArrayList<String>();
  368. Map<String, Map<String, String>> items = memClient.statsItems();
  369. for (Iterator<String> itemIt = items.keySet().iterator(); itemIt.hasNext();) {
  370. String itemKey = itemIt.next();
  371. Map<String, String> maps = items.get(itemKey);
  372. for (Iterator<String> mapsIt = maps.keySet().iterator(); mapsIt.hasNext();) {
  373. String mapsKey = mapsIt.next();
  374. String mapsValue = maps.get(mapsKey);
  375. if (mapsKey.endsWith( "number")) { //memcached key 类型 item_str:integer:number_str
  376. String[] arr = mapsKey.split( ":");
  377. int slabNumber = Integer.valueOf(arr[ 1].trim());
  378. int limit = Integer.valueOf(mapsValue.trim());
  379. Map<String, Map<String, String>> dumpMaps = memClient.statsCacheDump(slabNumber, limit);
  380. for (Iterator<String> dumpIt = dumpMaps.keySet().iterator(); dumpIt.hasNext();) {
  381. String dumpKey = dumpIt.next();
  382. Map<String, String> allMap = dumpMaps.get(dumpKey);
  383. for (Iterator<String> allIt = allMap.keySet().iterator(); allIt.hasNext();) {
  384. String allKey = allIt.next();
  385. list.add(allKey.trim());
  386. }
  387. }
  388. }
  389. }
  390. }
  391. return list;
  392. }
  393. }
  394. /**
  395. * 获取存储的key值
  396. * 已存在的prefix:FlightFocusInfo
  397. * 新增加的prefix命名时需确保唯一性,避免取值出问题
  398. */
  399. public static String getKey(String prefix,ArrayList<String> parms) {
  400. StringBuffer generateKey = new StringBuffer( "");
  401. if(!ToolUtil.isNull(parms)){
  402. Iterator<String> itr = parms.iterator();
  403. generateKey=generateKey.append(prefix).append( "_");
  404. while(itr.hasNext()){
  405. generateKey.append(itr.next()).append( "_");
  406. }
  407. }
  408. return generateKey.toString();
  409. }
  410. /**
  411. * 匹配符合条件的key值
  412. */
  413. public static ArrayList<String> matchKey(String prefix,ArrayList<String> parms) {
  414. ArrayList<String> matchKeys = new ArrayList<String>();
  415. if(!ToolUtil.isNull(parms)){
  416. ArrayList<String> keys = new ArrayList<String>();
  417. boolean findFlag = true;
  418. parms.add(prefix);
  419. keys = getAllKey();
  420. Iterator<String> keysItr = keys.iterator();
  421. while(keysItr.hasNext()){
  422. String key = keysItr.next();
  423. String[] k = key.split( "_");
  424. List k_a = Arrays.asList(k);
  425. Iterator<String> parmsItr = parms.iterator();
  426. while(parmsItr.hasNext()){
  427. if(!k_a.contains(parmsItr.next())){
  428. findFlag = false;
  429. }
  430. }
  431. if(findFlag){
  432. matchKeys.add(key);
  433. }
  434. findFlag = true;
  435. }
  436. }
  437. return matchKeys;
  438. }
  439. /**
  440. * @category 删除记录
  441. * @category 执行该方法之后,使用stats的统计结果会同步更新
  442. * @param key 记录的主键
  443. * @return 操作结果
  444. */
  445. public boolean delete(String key){
  446. if(!enUsed){
  447. return false;
  448. } else{
  449. return memClient.delete(key);
  450. }
  451. }
  452. /*
  453. * ****************************************************************************************************************
  454. * 下面的6个方法都是为了对memcached服务器进行监控及管理所用的,可能对服务器造成阻塞,所以除Debug以外,不推荐使用!
  455. */
  456. /**
  457. * @category 清空全部缓存数据。*慎用!!
  458. * @category 执行该方法之后,使用stats的统计结果不会马上发生变化,每get一个不存在的item之后,该item的值才会被动清空
  459. * @return 操作结果
  460. */
  461. public boolean flushAll(){
  462. if(!enUsed){
  463. return false;
  464. } else{
  465. return memClient.flushAll();
  466. }
  467. }
  468. /**
  469. * @category 返回可用的服务器列表
  470. * @return 数组(服务器地址:端口)
  471. */
  472. public String[] servers(){
  473. if(!enUsed) return null;
  474. return serverListArr;
  475. }
  476. /**
  477. * @category 返回所有缓存服务器当前的运行状态
  478. * @return
  479. *
  480. * Map
  481. * |-- Key : ServerName01, Value : LinkedHashMap
  482. * | |-- Key : statName01, Value : statValue
  483. * | |-- ...
  484. * |
  485. * |-- Key : ServerName02, Value : LinkedHashMap
  486. * | |-- Key : statName01, Value : statValue
  487. * | |-- ...
  488. * |
  489. * |-- ...
  490. *
  491. */
  492. public Map<String,LinkedHashMap<String, String>> stats(){
  493. if(!enUsed) return null;
  494. Map<String,LinkedHashMap<String, String>> retMap = new HashMap<String,LinkedHashMap<String, String>>();
  495. for(String server : serverListArr){
  496. LinkedHashMap<String, String> serverStats = this.stats(server);
  497. retMap.put(server, serverStats);
  498. }
  499. return retMap;
  500. }
  501. /**
  502. * @category 返回指定服务器当前的运行状态
  503. * @param server 服务器地址:端口
  504. *
  505. * 优化: 参数名称中文显示
  506. * 优化: 毫秒数转换为小时
  507. * 优化: 字节数转换为MB或KB
  508. * 优化: UNIX时间戳转换为标准时间
  509. * 优化: 参数显示顺序更加直观
  510. *
  511. * @return LinkedHashMap<String, String> 可对Map进行有序遍历
  512. *
  513. */
  514. public LinkedHashMap<String, String> stats(String server){
  515. if(!enUsed) return null;
  516. LinkedHashMap<String, String> retMap = new LinkedHashMap<String, String>();
  517. Map<String, Map<String, String>> statsList = memClient.stats( new String[]{server});
  518. //System.out.println(memClient.stats().toString());
  519. DecimalFormat format = new DecimalFormat( "0.0");
  520. for(Object serverTitle : statsList.keySet().toArray()){
  521. Map<String, String> serverStats = (Map<String, String>)statsList.get(serverTitle);
  522. retMap.put(statsItems.get( "pid"), serverStats.get( "pid").replaceAll( "\\r\\n", ""));
  523. retMap.put(statsItems.get( "version"), serverStats.get( "version").replaceAll( "\\r\\n", ""));
  524. retMap.put(statsItems.get( "pointer_size"), serverStats.get( "pointer_size").replaceAll( "\\r\\n", "") + "位");
  525. retMap.put(statsItems.get( "time"), new java.text.SimpleDateFormat( "yyyy-MM-dd HH:mm:ss").format( new Date(Long.parseLong(serverStats.get( "time").replaceAll( "\\r\\n", "")) * 1000)).toString());
  526. retMap.put(statsItems.get( "uptime"), format.format(Double.parseDouble(serverStats.get( "uptime").replaceAll( "\\r\\n", ""))/( 60* 60)) + "小时");
  527. retMap.put(statsItems.get( "connection_structures"), serverStats.get( "connection_structures").replaceAll( "\\r\\n", ""));
  528. retMap.put(statsItems.get( "total_connections"), serverStats.get( "total_connections").replaceAll( "\\r\\n", ""));
  529. retMap.put(statsItems.get( "curr_connections"), serverStats.get( "curr_connections").replaceAll( "\\r\\n", ""));
  530. retMap.put(statsItems.get( "limit_maxbytes"), format.format(Double.parseDouble(serverStats.get( "limit_maxbytes").replaceAll( "\\r\\n", ""))/( 1024* 1024)) + "MB");
  531. retMap.put(statsItems.get( "bytes"), format.format(Double.parseDouble(serverStats.get( "bytes").replaceAll( "\\r\\n", ""))/( 1024* 1024)) + "MB");
  532. retMap.put(statsItems.get( "bytes_written"), format.format(Double.parseDouble(serverStats.get( "bytes_written").replaceAll( "\\r\\n", ""))/( 1024)) + "KB");
  533. retMap.put(statsItems.get( "bytes_read"), format.format(Double.parseDouble(serverStats.get( "bytes_read").replaceAll( "\\r\\n", ""))/( 1024)) + "KB");
  534. retMap.put(statsItems.get( "total_items"), serverStats.get( "total_items").replaceAll( "\\r\\n", ""));
  535. retMap.put(statsItems.get( "curr_items"), serverStats.get( "curr_items").replaceAll( "\\r\\n", ""));
  536. retMap.put(statsItems.get( "cmd_get"), serverStats.get( "cmd_get").replaceAll( "\\r\\n", ""));
  537. retMap.put(statsItems.get( "get_hits"), serverStats.get( "get_hits").replaceAll( "\\r\\n", ""));
  538. retMap.put(statsItems.get( "get_misses"), serverStats.get( "get_misses").replaceAll( "\\r\\n", ""));
  539. retMap.put(statsItems.get( "cmd_set"), serverStats.get( "cmd_set").replaceAll( "\\r\\n", ""));
  540. }
  541. return retMap;
  542. }
  543. /**
  544. * @category 返回指定服务器及Slab中当前使用的item列表
  545. * @param server 服务器地址:端口
  546. * @param slab SlabId
  547. * @param counter 最多显示items条数
  548. * @return
  549. */
  550. public LinkedList<String> items(String server, int slab, int counter){
  551. if(!enUsed) return null;
  552. LinkedList<String> ret = new LinkedList<String>();
  553. Map<String, String> itemsKey = memClient.statsCacheDump( new String[]{server}, slab, counter).get(server);
  554. for(Object key : itemsKey.keySet().toArray()){
  555. ret.add(key.toString());
  556. }
  557. return ret;
  558. }
  559. /**
  560. * @category 返回指定服务器当前使用的SlabsID列表
  561. * @param server 服务器地址:端口
  562. * @return
  563. */
  564. public LinkedList<Integer> slabs(String server){
  565. if(!enUsed) return null;
  566. LinkedList<Integer> slabsId = new LinkedList<Integer>();
  567. Map<String, String> itemsMap = memClient.statsItems( new String[]{server}).get(server);
  568. Object[] itemsArr = itemsMap.keySet().toArray();
  569. for( int i= 0, len=itemsArr.length; i<len; i+= 2){
  570. slabsId.add(Integer.parseInt(itemsArr[i].toString().split( ":")[ 1]));
  571. }
  572. return slabsId;
  573. }
  574. /*
  575. * 上面的6个方法都是为了对memcached服务器进行监控及管理所用的,可能对服务器造成阻塞,所以除Debug以外,不推荐使用!
  576. * ****************************************************************************************************************
  577. */
  578. /**
  579. * 使用示例
  580. */
  581. public static void main(String[] args) {
  582. //初始化memcached操作类对象
  583. MemCached cache = MemCached.getInstance();
  584. //验证memcached服务是否已启用
  585. if(!cache.used()){
  586. System.out.println( "memcached服务未启用!");
  587. return;
  588. }
  589. //插入新记录
  590. System.out.println( "开始插入新记录(add):\r\n===================================");
  591. System.out.println( "keyTest01:" + cache.add( "keyTest01", "keyTest01Content"));
  592. System.out.println( "keyTest02:" + cache.add( "keyTest02", "keyTest02Content"));
  593. System.out.println( "插入新记录操作完成\r\n===================================");
  594. //读取单条记录
  595. System.out.println( "读取单条记录(get):\r\n===================================");
  596. System.out.println( "keyTest01:" + cache.get( "keyTest01"));
  597. System.out.println( "keyTest02:" + cache.get( "keyTest02"));
  598. System.out.println( "读取单条记录操作完成\r\n===================================");
  599. //读取多条记录
  600. System.out.println( "读取多条记录(add):\r\n===================================");
  601. System.out.println( "keyTest01、keyTest02:" + cache.get( new String[]{ "keyTest01", "keyTest02"}));
  602. System.out.println( "读取多条记录操作完成\r\n===================================");
  603. //修改记录值
  604. System.out.println( "修改记录值(replace):\r\n===================================");
  605. System.out.println( "keyTest01:" + cache.get( "keyTest01"));
  606. System.out.println( "keyTest01:" + cache.replace( "keyTest01", "keyTest01ContentReplace!"));
  607. System.out.println( "keyTest01:" + cache.get( "keyTest01"));
  608. System.out.println( "修改记录值操作完成\r\n===================================");
  609. //添加或修改记录
  610. System.out.println( "添加或修改记录(set):\r\n===================================");
  611. System.out.println( "keyTest03:" + cache.set( "keyTest03", "keyTest03Content"));
  612. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  613. System.out.println( "keyTest03:" + cache.set( "keyTest03", "keyTest03ContentReplace!"));
  614. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  615. System.out.println( "添加或修改记录操作完成\r\n===================================");
  616. //删除记录
  617. System.out.println( "删除记录(delete):\r\n===================================");
  618. System.out.println( "keyTest01:" + cache.delete( "keyTest01"));
  619. System.out.println( "keyTest02:" + cache.delete( "keyTest02"));
  620. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  621. System.out.println( "keyTest03:" + cache.delete( "keyTest03"));
  622. System.out.println( "keyTest03:" + cache.get( "keyTest03"));
  623. System.out.println( "修改记录值操作完成\r\n===================================");
  624. //打印当前的服务器参数及统计信息
  625. System.out.println( "服务器参数及统计信息(stats):\r\n===================================");
  626. Map statsList = cache.stats();
  627. for(Object server : statsList.keySet().toArray()){
  628. System.out.println( "-------------------------\r\n服务器:" + server + " : \r\n-------------------------");
  629. LinkedHashMap serverStats = (LinkedHashMap)statsList.get(server);
  630. for(Object statKey : serverStats.keySet().toArray()){
  631. System.out.println(statKey + " : " + serverStats.get(statKey));
  632. }
  633. }
  634. }
  635. }