Redis protocol (redis通信协议)

1.Redis网络通信协议

Redis底层网络通信协议其实是通过TCP来完成的。

2.Redis通信协议

Redis的通信协议首先是以行来划分,每行以\r\n行结束。每一行都有一个消息头,消息头共分为5种分别如下:
(+) 表示一个正确的状态信息,具体信息是当前行+后面的字符。
(-) 表示一个错误信息,具体信息是当前行-后面的字符。
(*) 表示消息体总共有多少行,不包括当前行,*后面是具体的行数。
()表示下一行数据长度,不包括换行符长度\r\n,)表示下一行数据长度,不包括换行符长度\r\n,后面则是对应的长度的数据。
( : ) 表示返回一个数值,:后面是相应的数字节符。
举个例子:

set demo 123456

1*3\r\n #消息一共有三行 2$3\r\n #第一行有字节数为3 3set\r\n #第一行的消息 4$4\r\n #第二行字节数为4 5demo\r\n #第二行的消息 6$6\r\n #第三行字节数为6 7123456\r\n #第三行的消息 8+OK\r\n #操作成功 9 10

3.Redis通信协议实现

set

1public static void main(String[] args) throws Exception { 2 // socket 3 Socket socket = new Socket("140.143.135.210", 6379); 4 5 // oi流 6 OutputStream os = socket.getOutputStream(); 7 InputStream is = socket.getInputStream(); 8 9 // 向redis服务器写 10 os.write("set demo 123456\r\n".getBytes()); 11 12 //从redis服务器读,到bytes中 13 byte[] bytes = new byte[1024]; 14 int len = is.read(bytes); 15 16 // to string 输出一下 17 System.out.println(new String(bytes,0,len)); 18} 19 20

get

1public static void main(String[] args) throws Exception { 2 // socket 3 Socket socket = new Socket("140.143.135.310", 6379); 4 5 // oi流 6 OutputStream os = socket.getOutputStream(); 7 InputStream is = socket.getInputStream(); 8 9 // 向redis服务器写 10 os.write("get demo\r\n".getBytes()); 11 12 //从redis服务器读,到bytes中 13 byte[] bytes = new byte[1024]; 14 int len = is.read(bytes); 15 16 // to string 输出一下 17 System.out.println(new String(bytes,0,len)); 18 } 19 20

刚才客户端向服务端发送的 “get demo” , 这种只是"内联命令", 而不是Redis真正的通信协议.

  • 问: 什么意思呢? 答: 就是说你可以像之前那样给服务端发, 服务器端接受到后, 会遍历一遍你发送的内容, 最后根据空格来分析你所发的内容的含义.

  • 问: 这样有什么不好的吗? 答: 如果这样的话, 你就把解析的工作交给了服务器来做, 会加大服务器的工作量.

  • 问: 那怎么样才是符合规范的呢? 符合协议的话真的会提高服务器的效率? 答: 首先看一下符合协议的客户端和服务端之间的交互把

例: set java python ,抓到包之后是这样的:

红色是客户端发送的内容, 蓝色是服务器端返回的内容.

咱们一起解析一下:

*3表示 , 客户端即将发送3段内容

哪三段呢? 第一段:$3 SET 第二段: $4 java' 第三段: $6 python

更严格地说: 第一段:$3\r\nSET\r\n 第二段:$4\r\njava\r\n 第三段:$6\r\npython\r\n

$符号的意思在上一小节就已经提到过了, 表示下文的内容的长度, 方便服务器进行读取.

例如: $6就已经把python的长度给汇报出来了, 服务器只需要截取区间[index, index+6]就好了, 不需要去找空格在什么地方(找空格的时间复杂度是O(n), 而$6这种写法是O(1) )

4 Jedis呢

其实Jedis做的工作大体就是把SET key value 这样的格式转化为下面这种格式, 然后发到Redis服务端:

1*3\r\n 2$3\r\n 3SET\r\n 4$3\r\n 5key\r\n 6$5\r\n 7value\r\n 8 9

代码交流 2021