redis的服务端与客户端之间的通信采用了一种名为 RESP(REdis Serialization Protocol) 的协议,主要以下特点:
- 容易实现
- 解析快
- 人类可读
RESP底层采用的是TCP的连接方式,通过tcp进行数据传输,然后根据解析规则解析相应信息,完成交互。
我们可以测试下,首先运行一个serverSocket监听6379,来接收redis客户端的请求信息,实现如下:
public class MyRedisServer {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(6379);
while (true){
Socket socket = serverSocket.accept();
new Thread(() -> {
try(InputStream inputStream = socket.getInputStream()) {
byte[] bytes = new byte[1024];
int len = inputStream.read(bytes);
System.out.println(new String(bytes, 0, len));
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
然后我们使用常用的redis连接工具lettuce5来发送请求,实现如下:
public class LettuceTest {
public static void main(String[] args) throws ExecutionException, InterruptedException {
RedisURI redisURI3 = new RedisURI("127.0.0.1", 6379, Duration.ofMillis(9999));
RedisClient redisClient = RedisClient.create(redisURI3);
StatefulRedisConnection connection = redisClient.connect();
RedisCommands<String, String> commands = connection.sync();
System.out.println(commands.get("name"));
connection.close();
redisClient.shutdown();
}
}
先运行server,在运行客户端,我们可以看到在server的控制台打印了如下格式的信息:
*2
$3
GET
$4
name
通过官网可以查询到RESP的信息规则如下:
- 单行回复:回复的第一个字节是 “+”
- 错误信息:回复的第一个字节是 “-“
- 整形数字:回复的第一个字节是 “:”
- 多行字符串:回复的第一个字节是 “$”
- 数组:回复的第一个字节是 “*”
- 每行信息已\r\n结尾
例如:
#服务端实际回复
+OK\r\n
#redis-cli显示
OK
#服务端实际回复
-ERR unknown command 'xxxxx'\r\n
#redis-cli显示
(error) ERR unknown command 'xxxxx'
由此我们可以分析上面控制台打印的信息:
- *2表示返回了一个数组,长度为2
- $3表示这是一个多行字符串,实际信息字符串长度为3
- GET为$3描述的实际字符串
- 后面两行含义同上
RESP是一个比较容易理解的协议。