18 What Are the Request and Response Patterns Available in the Redis Protocol

18 What are the Request and Response Patterns Available in the Redis Protocol #

Hello, I am your cache class teacher, Chen Bo. Welcome to Lesson 18, “Redis Protocol Analysis”. In this lesson, we will mainly learn about the design principles of Redis, the three response modes, and the two request formats and five response formats.

Redis Protocol #

Redis supports 8 core data structures, each of which has a series of operation commands. In addition to these, Redis also has a series of related commands for transactions, clustering, pub/sub messaging, and scripts. In order to facilitate the design and use of these commands in a unified style and principle, Redis has designed RESP, which stands for Redis Serialization Protocol. RESP is a binary-safe protocol that can be used by Redis or any other client-server application. Within Redis, RESP is further extended with more details.

Design Principles #

There are three design principles for the Redis serialization protocol:

  1. The first principle is simplicity.
  2. The second principle is fast parsing.
  3. The third principle is ease of reading.

Redis protocol has three types of request-response models, with the exception of two special modes, most of them follow the ping-pong model, which means the client sends a request and the server replies with a response in a question-and-answer access mode.

Two special modes are:

  • Pipeline mode: In this mode, the client sends multiple requests continuously and then waits for the server to respond. After processing the requests, the server returns the responses to the client.
  • Pub/sub mode: In this mode, also known as the publish/subscribe mode, the client subscribes to a channel by using the SUBSCRIBE command. The client then enters a subscription state, waiting silently. When a message is generated, the server continuously and automatically pushes the message to the client without any additional request from the client. While in the subscription state, the client can only accept subscription-related commands such as SUBSCRIBE, PSUBSCRIBE, UNSUBSCRIBE, and PUNSUBSCRIBE. Other commands are not valid.

Redis protocol requests and responses also follow fixed patterns.

For request commands, there are two types of formats.

  1. If you do not have a Redis client but want to interact with Redis directly using a generic tool like telnet, the Redis protocol, although simple and easy to read, is not easy to spell during an interactive session. In this case, you can use the first format, which is the inline command format. In this format, the request command and its arguments are separated by spaces, making it simple and fast. A simple example is mget key1 key2\r\n.
  2. The second format is the array format. The array format is used for both request commands and Redis responses, which will be discussed in detail when introducing the response formats.
Response Formats #

Redis protocol has five response formats, which are:

  1. Simple strings: These start with a + sign, followed by the string, and end with CRLF (\r\n). This type is not binary-safe, and the string cannot contain \r or \n characters. For example, many responses start with OK to indicate a successful operation. The protocol content would be +OK\r\n.

  2. Redis treats errors as a separate type, which has the same format as simple strings but starts with a - (minus sign) instead. The difference is that after the minus sign, it is usually followed by either ERR or WRONGTYPE, and then followed by other simple strings. The response ends with CRLF. Here are two examples. Once the client detects a response starting with a minus sign, it knows that it received an error response.

  3. Integer: This type starts with a :, followed by the string representation of a number, and ends with CRLF. Many commands in Redis return integers, but the meaning of the integer depends on the specific command. For example, for the incr command, the number after the : represents the new value after the increment. For the llen command, the number represents the length of the list. For the exists command, the number 1 indicates that the key exists, while 0 indicates that the key does not exist. Here is an example with :1000 followed by CRLF.

  4. Bulk strings: This type consists of a header and the actual string content. The header of a bulk string starts with $, followed by the length of the string represented as a string, and ends with CRLF. After the header, the actual string content follows, and it ends with CRLF. Bulk strings are used to represent binary-safe strings, and the maximum length they can support is 512MB. Here is a regular example: "$6\r\nfoobar\r\n". For an empty string, it can be represented as "$(0)\r\n\r\n", and for a NULL string: "$(0)-1\r\n".

  5. Arrays Arrays are used when a command needs to return multiple pieces of data. Additionally, as mentioned earlier, the client’s request commands also primarily use this format.

Arrays start with a “*” followed by the length of the array, and end with a line break. After that, there are N array elements, where N can be any type in the Redis protocol, except for inline format.

For example, a string array instance:

*2
$3
get
$3
key

An integer array instance:

*3
:1
:2
:3

A mixed array instance:

*3
:1
-Bar
$6
foobar

An empty array:

_0

A NULL array:

_-1
Protocol Categories #

The Redis protocol is mainly divided into 16 types. 8 of those types correspond to the 8 data types mentioned earlier, so you can use the corresponding response commands based on the data type you choose. The remaining 8 protocol categories are as follows:

  1. Pub-sub protocol: Clients can subscribe to channels and continuously wait for the server to push messages.
  2. Transaction protocol: This protocol allows multiple commands to be grouped together using MULTI and EXEC, and executed as a single unit.
  3. Script protocol: The key commands include EVAL, EVALSHA, and SCRIPT, etc.
  4. Connection protocol: Includes commands for authentication, switching databases, closing connections, etc.
  5. Replication protocol: Includes commands like SLAVEOF, ROLE, PSYNC, etc.
  6. Configuration protocol: Commands like CONFIG SET/GET can be used to modify/get configurations online.
  7. Debug and statistics protocol: Includes commands like SLOWLOG, MONITOR, INFO, etc.
  8. Other internal commands: Includes commands like MIGRATE, DUMP, RESTORE, etc.
Usage and Improvement of Redis Clients #

Since Redis is widely used, there are Redis clients available for almost every mainstream programming language. Taking Java as an example, popular clients include Jedis and Redisson.

For Jedis client, its advantages are lightweight, concise, easy to integrate and modify. It supports connection pooling and provides operation at the command level, supporting almost all Redis commands. However, it does not support read-write separation. Redisson is based on Netty, providing non-blocking IO and high performance. It supports asynchronous requests, connection pooling, read-write separation, and read load balancing. It also has built-in support for tomcat session and can be integrated with Spring Session, but the implementation of Redisson is relatively complex.

In a new project, if Redis access is simple, Jedis can be used directly, and it can even be easily encapsulated to implement read-write separation with master-slave nodes. If read-write separation is desired, along with integration of advanced features like Spring Session, Redisson can be used.

When using Redis clients, it is important to make relevant improvements based on business and operational needs. For example, you can add retry strategies for exceptional client access; when accessing a slave node fails, you should retry with other slave nodes. Support for Redis master-slave switch and slave extension can be added, such as using a daemon thread to periodically scan the master and slave domain names, detecting IP changes and switching connections promptly. For multiple slave nodes access, load balancing strategies should be implemented. Finally, Redis clients can also be integrated with configuration centers and Redis cluster management platforms to achieve real-time awareness and coordination of Redis service access.

This concludes the content of this lesson.

In these lessons, you first learned about the features and basic principles of Redis, and gained a preliminary understanding of Redis data types, main process/subprocess, BIO threads, persistence, replication, and clustering. These topics will be further explored in subsequent lessons.

Then, you delved into Redis data types in detail, understanding the functionalities, characteristics, main operation commands, and application scenarios of the 8 core data types: string, list, set, sorted set, hash, bitmap, GEO (geographical locations), and HyperLogLog (cardinality estimation).

Next, you became familiar with the Redis protocol, including its design principles, three response models, two request formats, and five response formats.

Lastly, using Java as an example, you also learned about the comparison, selection, and improvement of Redis clients.

You can refer to this mind map to review and organize these key points.

img