深入分析redis通讯协议

83 阅读2分钟

前言

  1. 了解redis通讯协议
  2. 利用redis通讯协议编程

redis协议概述

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

RESP 是以下考虑因素的折衷方案:

  • 实施简单
  • 解析速度快
  • 人类可读

RESP 可以序列化不同的数据类型,包括整数、字符串和数组。它还具有特定于错误的类型。客户端以字符串数组的形式向 Redis 服务器发送请求。该数组的内容是服务器应执行的命令及其参数。服务器的回复类型是特定于命令的。 RESP 是二进制安全的,并使用前缀长度来传输批量数据,因此不需要处理从一个进程传输到另一进程的批量数据。 RESP 是您应该在 Redis 客户端中实现的协议。

image.png

redis协议的格式

*<参数数量> CR LF
$<参数 1 的字节数量> CR LF
<参数 1 的数据> CR LF
$<参数 N 的字节数量> CR LF
<参数 N 的数据> CR LF

比如:set key value 利用上述的协议格式变成

*3 \r\n
$3 \r\n
SET \r\n
$3  \r\n
key \r\n
$5 \r\n
value \r\n

编程验证:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.CharBuffer;

public class Application {

    public static void main(String[] args) {
        //定义redis服务端默认端口
        int port = 6379;
        Socket socket = null;
        BufferedReader in = null;
        PrintWriter out = null;
        try {
            //创建tcp连接
            socket = new Socket("localhost", port);
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new PrintWriter(socket.getOutputStream(), true);
            //传送info命令
            //客户端向Redis服务器发送命令,以RESP整块字符串数组的形式
            //out.println("*1\r\n$4\r\ninfo\r\n");
            out.println("*3\r\n" + "$3\r\n" + "SET\r\n" + "$3\r\n" + "key\r\n" + "$5\r\n" + "value\r\n");
            System.out.println("Redis command wat sent successfully.");
            //接收服务器的回复
            CharBuffer response = CharBuffer.allocate(1024);
            int readedLen = in.read(response);
            String responseBody = response.flip().toString();

            //输出服务器的回复
            System.out.println(responseBody);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //最后关闭相关的流
            if (out != null) {
                out.close();
                out = null;
            }

            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                in = null;
            }

            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                socket = null;
            }
        }
    }
}

总结:

1、通过学习redis通讯协议,了解redis通讯的详细过程和原理

2、对以后自己自定义通讯协议提供帮助