1. 缓存
1.1 Redis
1.1.1 Redis服务
下载Redis安装包,切换至下载目录,命令行启动Redis服务;
redis-server redis.windows.conf
1.1.2 Jedis
Java与Redis交互可以使用Jedis,Jedis实现了与Redis通信的协议RESP(REdis Serialization Protocol),封装了与Redis服务器进行交互的细节,提供简单一致的接口;
以Jedis中的get方法为例:
public String get(String key) {
this.checkIsInMultiOrPipeline();
this.client.get(key);
return this.client.getBulkReply();
}
其中Jedis通信协议相关实现主要在protocol类中,Jedis调用sendCommand发送指令,主要是按通信协议进行报文格式的封装;
private static void sendCommand(RedisOutputStream os, byte[] command, byte[]... args) {
try {
os.write((byte)42);
os.writeIntCrLf(args.length + 1);
os.write((byte)36);
os.writeIntCrLf(command.length);
os.write(command);
os.writeCrLf();
byte[][] var3 = args;
int var4 = args.length;
for(int var5 = 0; var5 < var4; ++var5) {
byte[] arg = var3[var5];
os.write((byte)36);
os.writeIntCrLf(arg.length);
os.write(arg);
os.writeCrLf();
}
} catch (IOException var7) {
throw new JedisConnectionException(var7);
}
}
而Redis的解码则在Protocol类的process执行,通过响应的第一个字节来标志报文的类型;
private static Object process(RedisInputStream is) {
byte b = is.readByte();
switch(b) {
case 36:
return processBulkReply(is);
case 42:
return processMultiBulkReply(is);
case 43:
return processStatusCodeReply(is);
case 45:
processError(is);
return null;
case 58:
return processInteger(is);
default:
throw new JedisConnectionException("Unknown reply: " + (char)b);
}
}
get方法调用的processBulkReply函数如下,可以看到返回的是byte[]:
private static byte[] processBulkReply(RedisInputStream is) {
int len = is.readIntCrLf();
if (len == -1) {
return null;
} else {
byte[] read = new byte[len];
int size;
for(int offset = 0; offset < len; offset += size) {
size = is.read(read, offset, len - offset);
if (size == -1) {
throw new JedisConnectionException("It seems like server has closed the connection.");
}
}
is.readByte();
is.readByte();
return read;
}
}
1.1.3 代码示例
可以将字符串存入Redis,也可以将对象序列化之后存入Redis
public class RedisConn {
public static class Dog implements Serializable {
private String kind;
public Dog(String kind){
this.kind = kind;
}
public String toString(){
return "Dog Type:"+kind;
}
}
public static void main(String[] args){
Jedis jedisCli = new Jedis("localhost");
System.out.println("服务正在运行"+jedisCli.ping());
jedisCli.set("myName","Alan");
String name = jedisCli.get("myName");
System.out.println("Dict value:"+name);
jedisCli.set("obj".getBytes(),SerializeUtil.serialize(new RedisConn.Dog("wolf dog")));
RedisConn.Dog dog1 =(Dog)SerializeUtil.deserialize(jedisCli.get("obj".getBytes()));
System.out.println(dog1.toString());
jedisCli.close();
}
}
序列化工具类SerializeUtil
ublic class SerializeUtil {
//序列化
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.close();
}
if (oos != null) {
oos.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
//反序列化
public static Object deserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
ObjectInputStream ois = null;
try {
bais = new ByteArrayInputStream(bytes);
ois = new ObjectInputStream(bais);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bais != null) {
bais.close();
}
if (ois != null) {
ois.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return null;
}
}
输出如下:
服务正在运行PONG
Dict value:Alan
Dog Type:wolf dog
1.1.4 可视化工具
Redis Desktop Manager,对象是以二进制的方式存储在Redis中