Chanler

Chanler

"Dark Horse Redis Principles" Three, Communication Protocol

RESP Protocol#

Redis is a software with a CS architecture, and communication generally consists of two steps (excluding pipeline and PubSub):

  1. The client sends a command to the server.
  2. The server parses and executes the command, returning the response result to the client.

Therefore, the format of the command sent by the client and the format of the response result from the server must have a specification, and this specification is the communication protocol.

RESP: Redis Serialization Protocol

Learn about the RESP2 protocol, which was introduced in version 2.0, and upgraded to RESP3 in 6.0, but due to significant changes, RESP2 protocol is still used by default.

RESP Protocol Data Types#

For single-line strings, errors, and data, they are all binary unsafe. If \r\n is interspersed in the content, it may be misinterpreted as an end.

The array type actually looks quite similar to the AOF file.

image.png|500

Simulating Redis Client#

Is the reader not receiving information?

public class Main {  
    static Socket s;  
    static PrintWriter out;  
    static BufferedReader in;  
    public static void main(String[] args) {  
        try {  
            // 1. Establish connection  
            String host = "redis.orb.local";  
            int port = 6379;  
            s = new Socket(host, port);  
            // 2. Get input and output streams  
            out = new PrintWriter(  
                    new OutputStreamWriter(s.getOutputStream(), StandardCharsets.UTF_8));  
            in = new BufferedReader(new InputStreamReader(s.getInputStream()));  
            // 3. Send request and parse  
            // Get authorization auth TheBestWorkLoanapp1            sendRequest("auth", "TheBestWorkLoanapp1");  
            Object obj = handleResponse();  
            System.out.println(obj.toString());  
            // Set key-value pair set name Chanler            sendRequest("set", "name", "Chanler");  
            obj = handleResponse();  
            System.out.println(obj.toString());  
            // Get key-value pair get name            sendRequest("get", "name");  
            obj = handleResponse();  
            System.out.println(obj.toString());  
        } catch (IOException e) {  
            e.printStackTrace();  
        } finally {  
            // 5. Release connection  
            try {  
                if (s != null) {s.close();}  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            try {  
                if (out != null) {out.close();}  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            try {  
                if (in != null) {in.close();}  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
  
    private static Object handleResponse() throws IOException {  
        // Read the first byte to determine data type  
        int prefix = in.read();  
        switch (prefix) {  
            case '+':  
                return in.readLine();  
            case '-':  
                throw new RuntimeException(in.readLine());  
            case ':':  
                return Long.parseLong(in.readLine());  
            case '$':  
                int len = Integer.parseInt(in.readLine());  
                if (len == -1) {  
                    return null;  
                }  
                if (len == 0) {  
                    return "";  
                }  
                // Here should read len bytes, but it has been converted to character stream, so assume no special characters exist  
                return in.readLine();  
            case '*':  
                return readBulkString();  
            default:  
                throw new RuntimeException("Invalid prefix");  
        }  
    }  
  
    private static Object readBulkString() throws IOException {  
        int len = Integer.parseInt(in.readLine());  
        if (len == 0) {  
            return null;  
        }  
        List<Object> list = new ArrayList<>();  
        for (int i=0; i<len; i++) {  
            list.add(handleResponse());  
        }  
        return list;  
    }  
  
    // Send set name Chanler    
    private static void sendRequest(String ... args) {  
        // \r\n is the newline character, here using println directly includes it  
        out.println("*" + args.length);  
        for (String arg : args) {  
            out.println("$" + arg.getBytes(StandardCharsets.UTF_8).length);  
            out.println(arg);  
        }  
        out.flush();  
    }  
}

This article is synchronized and updated to xLog by Mix Space
The original link is https://blog.0xling.cyou/posts/redis/redis-5


Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.