Use Go to learn about Redis communication protocol

Source: Internet
Author: User
Tags redis version redis server

Use Go to learn about Redis communication protocol

Original address: Fried fish of the fan portal

Go, PHP, Java ... have so many packages to support your use of Redis, have you ever thought about

With the service side, with the client, they are how to communicate, and based on what communication protocol to make the interaction?

Introduced

Based on our purpose, this paper mainly explains and practices the communication protocol of Redis.

The client and server side of Redis is data interaction over a TCP connection, with the default port number of 6379

The commands or data sent by the client and the server are \r\n all terminated (CRLF) (this is a convention)

Agreement

There are requests and replies in Redis, and the request agreement is divided into new and legacy versions, the new unified request Protocol was introduced in Redis 1.2, and eventually became the standard way for Redis server communication in Redis version 2.0.

This article is based on the new version of the Protocol to achieve functionality, not recommended to use the old version (1.2 is old). Here are a few examples of new protocols:

Request Agreement

1. Format example

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

All parameters sent to the Redis server under this Protocol are binary security (binary safe)

2. Printing examples

*3$3SET$5mykey$7myvalue

3. Actual protocol value

"*3\r\n$3\r\nSET\r\n$5\r\nmykey\r\n$7\r\nmyvalue\r\n"

This is the REDIS request protocol specification, according to sample 1 to write the client logic, the final send is example 3, I believe you already have a general concept, Redis protocol is very simple and understandable, this is also a good reason to get started, you can think of the benefits of the definition of the agreement?

Reply

Redis will return many different types of replies depending on the protocol you are requesting (the result of the command being executed is also different). In this reply "protocol", you can check the first byte to determine what type of reply this is, as follows:

    • The first byte of State reply (status reply) is "+"
    • The first byte of the error reply (Reply) is "-"
    • The first byte of an integer reply (integer reply) is ":"
    • The first byte of a bulk reply (bulk Reply) is "$"
    • The first byte of a multiple bulk reply (multi bulk Reply) is "*"

With the head logo of the reply, the end of the CRLF, you can roughly guess the reply to the "agreement" is how, but the practice to come to the truth, Mr. Saito know that you will soon forget

Practice

Interacting with Redis servers

Package Mainimport ("Log" "NET" "OS" "Github.com/eddycjy/redis-protocol-example/protocol") const (Address = "127.0.0.1:6379" network = "tcp") Func Conn (network, address string) (net. Conn, error) {Conn, err: = Net.    Dial (Network, address) if err! = Nil {return nil, err} return conn, Nil}func Main () {//Read into parameter args: = os. Args[1:] If Len (args) <= 0 {log. Fatalf ("Os.args <= 0")}//Get request Agreement reqcommand: = protocol. Getrequest (args)//Connect Redis server Redisconn, err: = Conn (Network, Address) if err! = Nil {log.    Fatalf ("Conn err:%v", err)} defer redisconn.close ()//write Request content _, Err = Redisconn.write (Reqcommand) If err! = Nil {log. Fatalf ("Conn Write err:%v", err)}//Read reply command: = make ([]byte, 1024x768) n, err: = Redisconn.read (com Mand) If err! = Nil {log. Fatalf ("Conn Read err:%v", err)}//Processing reply reply, err: = protocol. GeTreply (Command[:n]) if err! = Nil {log. Fatalf ("protocol. Getreply err:%v ", err)}//After processing the contents of the reply log. Printf ("Reply:%v", Reply)//original reply content log. Printf ("Command:%v", String (Command[:n]))}

Here we complete the process of interaction between the Redis client and the server, respectively, as follows:

1. Read command line parameters: Get the Redis command executed

2. Get Request Protocol Parameters

3. Connect to Redis server, get connection handle

4. Write the request protocol parameters to the connection: command-line arguments to send the request

5. Read the returned data from the connection: read the previously requested reply data

6, according to reply "agreement" content, processing the data set of reply

7, the reply content after the output processing and the original reply content

Request

func GetRequest(args []string) []byte {    req := []string{        "*" + strconv.Itoa(len(args)),    }    for _, arg := range args {        req = append(req, "$"+strconv.Itoa(len(arg)))        req = append(req, arg)    }    str := strings.Join(req, "\r\n")    return []byte(str + "\r\n")}

Through the analysis of Redis request protocol, it can get its law, plus the flag bit, calculate the total number of parameters, then loop the number of bytes of each parameter, the value can be

Reply

Func getreply (Reply []byte) (interface{}, error) {replytype: = reply[0] Switch Replytype {case statusreply:        Return dostatusreply (reply[1:]) case Errorreply:return doerrorreply (reply[1:]) Case integerreply: Return dointegerreply (reply[1:]) case Bulkreply:return dobulkreply (reply[1:]) Case Multibulkreply:r  Eturn domultibulkreply (reply[1:]) Default:return nil, nil}}func dostatusreply (reply []byte) (String, error) {if len (reply) = = 3 && reply[1] = = ' O ' && reply[2] = = ' K ' {return okreply, nil} If Len         (reply) = = 5 && reply[1] = = ' P ' && reply[2] = = ' O ' && reply[3] = = ' N ' && reply[4] = = ' G ' { Return pongreply, nil} return string (Reply), Nil}func doerrorreply (reply []byte) (string, error) {Retur n String (Reply), Nil}func dointegerreply (reply []byte) (int, error) {pos: = Getflagpos (' \ R ', reply) result, err: = StrConv. Atoi (String (reply[:p OS]) if err! = Nil {return 0, err} return result, nil} ... 

Here we have all the response types are distributed, different response flags corresponding to different processing methods, there are several issues to note here, as follows:

1. When the requested value does not exist, a special value of 1 is used as a reply

2. All strings sent by the server are terminated by CRLF

3, many batch reply is can be based on batch reply, should pay attention to understand

4, no content of multiple batch reply is present

Most importantly, the control of the rules for different responses will give you a better understanding of how Redis's requests and responses interact.

Summary

The reason for writing this article is because often when using Redis, you don't know what kind of communication protocol it is based on, so it feels very uncomfortable.

Through this article, I believe you have a general understanding of how the Redis client interacts with the server, but also clear the principles of its use of communication, I hope to be able to help you!

Finally, if you want to see the code in detail, turn right at the project address: Https://github.com/EDDYCJY/re ...

If it helps, you're welcome to a Star.

Reference

    • Communication protocols
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.