redis通信原理
redis客户端与服务端之间使用tcp进行通信,redis客户端每执行一条命令,都会将命令封装成特定的格式传送到服务端,
如果我们需要实现redis客户端,就需要完成请求的封装。
如果我们打开redis的aof文件,经常会看到类似于下面这样的内容,这实际上就是客户端发送给服务端的数据格式
下面用java实现一个简单的拥有set、get方法的redis客户端,网络编程使用socket,具体代码如下所示:
public class RedisClient {
private InputStream inputStream;
private OutputStream outputStream;
public RedisClient(String host, int port) throws IOException {
Socket socket = new Socket(host, port);
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
}
public String get(String key) throws IOException {
byte[] result = new byte[1024];
//封装数据
StringBuilder data = new StringBuilder();
//命令参数个数
data.append("*2").append("\r\n");
data.append("$3").append("\r\n");
data.append("GET").append("\r\n");
//key字节长度
data.append("$").append(key.getBytes().length).append("\r\n");
data.append(key).append("\r\n");
outputStream.write(data.toString().getBytes());
inputStream.read(result);
String[] values = new String(result).split("\r\n");
//redis无值返回"$-1"
if ("$-1".equals(values[0])) {
return null;
}
return values[1];
}
public void set(String key, String value) throws IOException {
if (key == null || value == null) {
return;
}
//封装数据
StringBuilder data = new StringBuilder();
//命令参数个数
data.append("*3").append("\r\n");
data.append("$3").append("\r\n");
data.append("SET").append("\r\n");
//key 字节长度
data.append("$").append(key.getBytes().length).append("\r\n");
data.append(key).append("\r\n");
//value字节长度
data.append("$").append(value.getBytes().length).append("\r\n");
data.append(value).append("\r\n");
System.out.println(data);
//socket传递数据
outputStream.write(data.toString().getBytes());
//读取返回信息
byte[] response = new byte[10];
inputStream.read(response);
}
public static void main(String[] args) throws IOException {
RedisClient redisClient = new RedisClient("127.0.0.1", 6379);
redisClient.set("hello", "redis-client");
System.out.println(String.format("get data from redis:%s", redisClient.get("hello")));
}
}
可以看到,这个简单的客户端可以正常的工作: