Redis protocol (redis通信协议)

「爱情、让人受尽委屈。」 2024-04-17 05:30 199阅读 0赞

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
  3. set\r\n #第一行的消息
  4. $4\r\n #第二行字节数为4
  5. demo\r\n #第二行的消息
  6. $6\r\n #第三行字节数为6
  7. 123456\r\n #第三行的消息
  8. +OK\r\n #操作成功

3.Redis通信协议实现

set

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

get

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

刚才客户端向服务端发送的 “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
  3. SET\r\n
  4. $3\r\n
  5. key\r\n
  6. $5\r\n
  7. value\r\n

发表评论

表情:
评论列表 (有 0 条评论,199人围观)

还没有评论,来说两句吧...

相关阅读

    相关 redis通信协议

    几乎所有的主流编程语言都有Redis的客户端,不考虑redis非常流行的原因,如果站在技术的角度看原因还有两个: 客户端与服务端之间的通信协议是在TCP协议之上构建的,