• 【Redis】Redis序列化协议(RESP)


      Redis的通信协议是什么。就是客户端与服务端按照双方约定的规则来进行的编码方式,客户端将要发送的命令进行编码,然后服务端收到后,使用同样的协议进行解码,服务端处理完成后,再次编码返回给客户端,客户端解码拿到返回结果,这样就完成了一次通信。

      官网文档:https://redis.io/topics/protocol

    一、Redis协议规范

      Redis客户端使用称为RESP(Redis序列化协议)的协议与Redis服务器进行通信虽然该协议是专为Redis设计的,但它可以用于其他客户端-服务器软件项目。

      RESP是以下方面的折衷方案:

    • 易于实现。
    • 快速解析。
    • 可读性强。

      RESP可以序列化不同的数据类型,例如整数,字符串,数组。还有一种特定的错误类型。请求以字符串数组的形式从客户端发送到Redis服务器,这些字符串表示要执行的命令的参数。Redis使用特定于命令的数据类型进行回复。

      RESP是二进制安全的,并且不需要处理从一个进程传输到另一个进程的批量数据,因为它使用前缀长度来传输批量数据。

      注意:此处概述的协议仅用于客户端-服务器通信。Redis Cluster使用不同的二进制协议以在节点之间交换消息。

    二、网络层

    客户端连接到Redis服务器,以创建与端口6379的TCP连接。

    尽管RESP在技术上不是特定于TCP的,但在Redis的上下文中,该协议仅与TCP连接(或等效的面向流的连接,如Unix套接字)一起使用。

    三、请求-响应模型

    Redis接受由不同参数组成的命令。收到命令后,将对其进行处理并将答复发送回客户端。

    这是最简单的模型,但是有两个例外:

    • Redis支持流水线化(在本文档的后面部分有介绍)。因此,客户端可以一次发送多个命令,并在以后等待答复。
    • 当Redis客户端订阅Pub / Sub通道时,该协议会更改语义并成为推送协议,也就是说,客户端不再需要发送命令,因为服务器将自动向客户端发送新消息(对于客户端的通道被订阅)。

    除了上述两个例外,Redis协议是一种简单的请求-响应协议。

    四、RESP协议说明

    RESP协议是在Redis 1.2中引入的,但是它成为Redis 2.0中与Redis服务器通信的标准方法。这是您应该在Redis客户端中实现的协议。

    RESP实际上是一种序列化协议,支持以下数据类型:简单字符串,错误,整数,批量字符串和数组。

    在Redis中将RESP用作请求-响应协议的方式如下:

    • 客户端将命令作为RESP大容量字符串数组发送到Redis服务器。
    • 服务器根据命令实现以RESP类型之一进行回复。

    在RESP中,某些数据的类型取决于第一个字节:

    • 对于简单字符串,回复的第一个字节为“ +”
    • 对于错误,回复的第一个字节为“-”
    • 对于整数,回复的第一个字节为“:”
    • 对于散装字符串,回复的第一个字节为“ $”
    • 对于数组,回复的第一个字节为“ *

    另外,RESP能够使用Bulk Strings或Array的特殊变体来表示Null值,如稍后指定。

    在RESP中,协议的不同部分始终以“ r n”(CRLF)终止。

    五、RESP验证

      Redis客户端与server端通信,本身就是基于tcp的一个Request/Response模式。并且jedis与redis底层通信基于socket(可以查看jedis的set方法源码可知),是遵循resp通信协议。

      实验:通过ServerSocket模拟redis服务端,使用jedis向ServerSocket发送数据 

      代码需要引入jedis依赖 

    •  ServerSocket模拟redis服务端代码
      1 @Test
      2 public void server() throws IOException {
      3     ServerSocket serverSocket = new ServerSocket(6379);
      4     Socket socket = serverSocket.accept();
      5     byte[] bytes = new byte[1024];
      6     int len = socket.getInputStream().read(bytes);
      7     System.out.println(new String(bytes, 0, len));
      8 }
    • jedis向ServerSocket发送数据代码

      1 @Test
      2 public void client() {
      3     Jedis jedis = new Jedis("127.0.0.1", 6379);
      4     String ret = jedis.set("aaa", "11");
      5 }
    • 服务端接收数据如下:

       

  • 相关阅读:
    poj3321(dfs序+线段树)
    poj3321(dfs序+线段树)
    Codeforces Global Round 3 B
    Codeforces Global Round 3 B
    2019河北省大学生程序设计竞赛 L .smart robot
    P2617 Dynamic Rankings(动态区间主席树)
    Linux从入门到精通——linux的系统排错
    Linux从入门到精通——Linux的系统延时任务及定时任务
    Linux从入门到精通——linux中的软件管理
    Linux从入门到精通——lvm逻辑券
  • 原文地址:https://www.cnblogs.com/h--d/p/14772261.html
Copyright © 2020-2023  润新知