以下是本人学习memcache的随笔,如果写的有问题,欢迎指正。
1、memcache存储对象的过程
memcache常用于存储对象,以byte[]存储,示例如下:
(tips:这种奇怪的格式是将对象序列化成byte[],然后将byte[]构建成String的样子,这种二进制格式让我联想到class字节码文件,我觉得这二者都是字节码文件,只是调用者、用途不一样)
get SHC_CRM_UCA_12_crm1_UserBySn_13802075076
VALUE SHC_CRM_UCA_12_crm1_UserBySn_13802075076 0 1609
��sr!com.ailk.common.data.impl.DataMapO�
�xrjava.util.HashMap���`�F
loadFactorI thresholdxp?@`�JtDEVELOP_DEPART_IDt00000tCUST_IDt1106011502516645tFIRST_CALL_TIMEptLAST_STOP_TIME├2013-03-03 10:39:05├PRE_DESTROY_TIME⎻├ RSRV_NUM4⎻├
CITY_CODE_A⎻├ RSRV_NUM5⎻├
EPARCHY_CODE├0022├
MPUTE_DATE├2009-10-12 10:39:18├USER_ID├14794501495163├ RSRV_NUM1├32├
USECUST_ID├1106011502516645├OPEN_DEPART_ID⎻├
ASSURE_DATE⎻├ RSRV_NUM2⎻├REMOVE_REASON_CODE⎻├ RSRV_NUM3⎻├CHANGEUSER_DATEptIN_DATEt1998-06-05 00:00:00t
OPEN_STAFF_ID⎻├ CITY_CODE├0006├ DESTROY_TIMEptUPDATE_DEPART_IDt31064tUSER_TYPE_CODE├0├
IN_NET_MODE⎻├
IN_STAFF_ID0 ├
CONTRACT_ID⎻├
EPARCHY_NAME├天津├REMOVE_DEPART_ID⎻├ RSRV_STR5⎻├ RSRV_STR6⎻├ RSRV_STR3⎻├ RSRV_STR4⎻├ RSRV_STR1├691670├ RSRV_STR2⎻├ USER_TYPE├个人├ CITY_NAME⎻├USER_STATE_CODESET├0├REMOVE_CITY_CODE⎻ACCT_TAG├0├
DEVELOP_DATE⎻├
REMOVE_TAG├0├ RSRV_STR9⎻├ RSRV_STR7⎻├ RSRV_STR8⎻├
SERIAL_NUMBER├ PARTITION_ID├5163├
13802075076├
IN_DEPART_ID├00000├USER_DIFF_CODE├00├
DEVELOP_NO⎻├REMARK├NG割接导入├REMOVE_EPARCHY_CODE⎻├
PREPAY_TAG├0├
UPDATE_TIME├2019-08-09 19:56:17├
RSRV_DATE3⎻├
USER_PASSWD├␊N⎻QFU├DEVELOP_STAFF_ID⎻├
RSRV_DATE2⎻├ASSURE_CUST_ID⎻├
NET_TYPE_CODE├00├UPDATE_STAFF_IDTESTTJ16tURE_TYPE_CODE⎻├
RSRV_STR10pt
USER_TAG_SETptMPUTE_MONTH_FEEt1t OPEN_MODEt0t RSRV_TAG2pt OPEN_DATEt1998-06-05 00:00:00t RSRV_TAG3txtDEVELOP_CITY_CODEt0002t RSRV_TAG1px
下面演示将一个对象存储到memcache的demo:
import net.spy.memcached.MemcachedClient;
import org.apache.log4j.Logger;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
public class MemcacheTest {
private static final Logger log = Logger.getLogger(MemcacheTest.class);
public static void main(String[] args) throws Exception {
Map value = new HashMap();
value.put("1","2");
byte[] b = encode(value);
Object o = decode(b);
System.out.println("after encode:" + b);
System.out.println("after decode:" + o);
System.out.println("encode build String:" + new String(b));
try{
// 本地连接 Memcached 服务
MemcachedClient mcc = new MemcachedClient(new InetSocketAddress("10.143.4.122", 11201));
System.out.println("Connection to server sucessful.");
// 存储数据
Future fo = mcc.set("runoob", 900, value);
// 查看存储状态
System.out.println("set status:" + fo.get());
// 输出值
System.out.println("runoob value in cache - " + mcc.get("runoob"));
// 关闭连接
mcc.shutdown();
}catch(Exception ex){
System.out.println( ex.getMessage() );
}
}
public static byte[] encode(Object obj) {
byte[] rtn = null;
ByteArrayOutputStream baos = null;
ObjectOutputStream oos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(obj);
rtn = baos.toByteArray();
} catch (IOException var14) {
var14.printStackTrace();
} finally {
if (null != oos) {
try {
oos.close();
} catch (IOException var13) {
}
}
}
return rtn;
}
public static Object decode(byte[] bytes) {
Object rtn = null;
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try {
bais = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bais);
rtn = ois.readObject();
} catch (IOException var16) {
log.error(var16);
} catch (ClassNotFoundException var17) {
log.error(var17);
} finally {
if (null != ois) {
try {
ois.close();
} catch (IOException var15) {
}
}
}
return rtn;
}
}
控制台输出如下:
after encode:[B@6037fb1e
after decode:{1=2}
encode build String:�� sr java.util.HashMap���`� F
loadFactorI thresholdxp?@ t 1t 2x
2019-08-14 09:49:16.942 INFO net.spy.memcached.MemcachedConnection: Added {QA sa=/10.143.4.122:11201, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
Connection to server sucessful.
2019-08-14 09:49:16.967 WARN net.spy.memcached.MemcachedConnection: Could not redistribute to another node, retrying primary node for runoob.
2019-08-14 09:49:16.980 INFO net.spy.memcached.MemcachedConnection: Connection state changed for sun.nio.ch.SelectionKeyImpl@2b275d39
set status:true
runoob value in cache - {1=2}
2019-08-14 09:49:17.010 INFO net.spy.memcached.MemcachedConnection: Shut down memcached client
上面这个demo使用了spymemcached-2.10.3.jar ,感兴趣的同学下载jar包后可以直接运行上面的代码。
上面代码中,给memcache塞值和取值的逻辑看上去很简单,只需调mcc对象set和get方法,然而这两个方法做的操作并不简单。从一个点可以看出来,cmd连接memcache端口,可以看到代码里塞的runoob值为:
get runoob
VALUE runoob 1 90
��srjava.util.HashMap���`�F
loadFactorI thresholdxp?@
t1t2x
END
可以看出,memcache里面保存的值,等于代码中打印的new String(b)
所以得出结论:jar包里的方法set、get实际上是做了demo代码里encode和decode方法里的操作。