Write smart proxy Step by step 2 (single-node forwarding)

Source: Internet
Author: User
Tags benchmark
This is a creation in Article, where the information may have evolved or changed.



Hu

Write in front

According to the first theory, this paper implements the most streamlined single-machine forwarding version based on Redis Client Protocol. Does not include connection pooling, network timeouts, command detection, clustering, performance statistics, and service registration functions.

Archer

The version of the Proxy named Archer, meaning archer, familiar with the War3 old players must know, three bow hand is very powerful. Follow-up development is also based on this version, the code is interesting to download by themselves.

Https://github.com/dongzerun/archer

Data

For simple Strings The first byte of the reply is "+"

For Errors the first byte of the reply is "-"

For integers the first byte of the reply is ":"

For Bulk Strings The first byte of the reply is "$"

For Arrays the first byte of the reply is "*"

Redis protocol is relatively simple, with 5 types, to achieve a common interface

Type Resp Interface {

Encode () []byte//Generate binary data that satisfies the Client protocol

String () string//returns string data for Debug

Type () string//Tag type: Simpleresp, Errorresp, Intresp, Bulkresp, Arrayresp

}

Five types of Simpleresp, Errorresp, Intresp, Bulkresp, and Arrayresp are combined by BASERESP.

Type Baseresp struct {

Rtype string//RESP type

Args [][]byte//For commands, General Args[0] is the command name, Args[1] is key

}

Network protocol message sending and receiving

In terms of service, stable and efficient network protocol messaging is particularly important. But Redis is simple enough to read data from the Socket, according to the first letter to determine the type, follow-up and send and receive fixed-length data. But there are two points to note:

1. Redis supports direct sending of ping\r\n or quit\r\n, which means that the first byte, in addition to the +-$:*, may be p or Q

2. Binary security, because may carry \ r \ n, collect data cannot use Readbytes (\ n), but to read in length, and then read fixed-length fixed-length data

The function (Parser.go:ReadProtocol) is relatively simple, with the comment blank line less than 100.

Pipeline Design

What is Pipeline? is to send and receive asynchronously. The client sends commands in bulk, and then batches the packets, or two threads, one for sending commands, one for reading commands, and for programs with high latency requirements, consider using Pipeline.

Single-Machine Redis has no controversy, but in the cluster mode, the back-end node processing commands are different, the order of Pipeline send and receive commands can not be chaotic, the design requirements are high. The simplest way to think of it is to increase the Sequence Id and rearrange the Proxy before returning the data.

Type Session struct {//Session.go omit unnecessary struct member

RESPs Chan Resp//Response Buffer Channel

Cmds Chan *arrayresp//Command Buffer Channel

}

Client each connection is assigned a Session, open three Goroutine:writeloop, Dispatch, Readloop, respectively corresponding write response, distribution command, read command. This is implemented in the Proxy layer Pipeline, buffer size default 4096, can be set at startup, due to the session level, should not be set too large.

Pressure measurement performance

Commands are the same, 100 concurrent single 1000000 requests

Redis-benchmark-h localhost-n 1000000-c 100-r 20-q-P 6379

Single-Machine pressure test Redis

ping_inline:80153.90 Requests per second

ping_bulk:81327.27 Requests per second

set:42105.26 Requests per second

get:42147.86 Requests per second

incr:73163.59 Requests per second

lpush:81752.77 Requests per second

lpop:82196.28 Requests per second

sadd:80925.79 Requests per second

spop:81866.55 Requests per second

Lpush (needed to benchmark Lrange): 44499.82 Requests per second

LRANGE_100 (first elements): 27935.30 requests per second

lrange_300 (first elements): 17784.42 requests per second

lrange_500 (first elements): 11870.28 requests per second

lrange_600 (first elements): 10386.80 requests per second

MSET (keys): 33320.01 Requests per second

Proxy Tcp_nodelay=true

ping_inline:83542.19 Requests per second

ping_bulk:82973.78 Requests per second

set:37010.99 Requests per second

get:41614.65 Requests per second

incr:64412.24 Requests per second

lpush:55081.24 Requests per second

lpop:67272.12 Requests per second

sadd:56821.41 Requests per second

spop:40950.04 Requests per second

Lpush (needed to benchmark Lrange): 40146.13 Requests per second

LRANGE_100 (first elements): 23648.49 requests per second

lrange_300 (first elements): 9001.06 requests per second

lrange_500 (first elements): 6696.13 requests per second

lrange_600 (first elements): 5235.33 requests per second

MSET (keys): 31629.55 Requests per second

Proxy Tcp_nodelay=false

ping_inline:83187.76 Requests per second

ping_bulk:80749.35 Requests per second

set:40062.50 Requests per second

get:49862.88 Requests per second

incr:73099.41 Requests per second

lpush:71942.45 Requests per second

lpop:69309.67 Requests per second

sadd:60150.38 Requests per second

spop:39624.36 Requests per second

Lpush (needed to benchmark Lrange): 42016.81 Requests per second

LRANGE_100 (first elements): 26281.21 requests per second

lrange_300 (first elements): 9603.38 requests per second

lrange_500 (first elements): 6552.95 requests per second

lrange_600 (first elements): 4945.60 requests per second

MSET (keys): 29850.75 Requests per second

This performance is quite satisfactory, the Go network connection default Tcp_nodelay = True, after closing found that in the packet throughput has improved, for the large package is not obvious, or even low.


Pprof

Turn on Pprof View and the final overhead will fall to net. Conn read-write system call. The students in the group give the method: the merge request, the principle is to reduce the number of system calls, but the current scene may not be suitable. This can be done offline or insensitive to latency requirements.

About Tcp_nodelay

Nagle's algorithm is to solve the problem of the network packet overhead, if the sending side to send a packet containing a small number of characters (in general, after the uniform length is smaller than the MSS packet for the packet, in contrast, the length is equal to the MSS packet for the large package, for some contrast, There is a package, that is, longer than the packet length, but less than one MSS of the package, the sender will first send the packet out, and the subsequent arrival of a small number of character data are cached and not immediately sent, until the receiving end of the previous packet message segment ACK confirmation, or the current character belongs to emergency data, or accumulate a certain amount of data (such as the cached character data has reached the maximum length of the packet segment), and so on, and so on a large number of data packets sent out.

By default, MSS 536 bytes, for Redis service, the response packet has a minimum of 5 bytes ($-1\r\n), and the MySQL Ok_header package is less than 11 bytes. The database belongs to the OLTP scene, the request time delay is very small, from this aspect to see does not have the righteousness close tcp_nodelay, certainly will encounter the unexpected BUG.

In addition, for the delay requirements are not high, offline and long connection push service, personal feeling can be closed.

The following articles are worth reference

1. Mysterious 40 millisecond delay with Tcp_nodelay

2. Nginx about Tcp_nodelay settings

3. Nagle Network Congestion Control algorithm

4. Kingshard Performance Optimization Network Chapter

5. MSS

Conclusion

This is the most streamlined version, the skeleton is there, the next thing to do on the Dispatch, to handle the routing and ask MOVE requests, and the dynamic perception after Failover.

Previous time by the Langya list Brush screen, recommended Hu an old song "Carefree Sigh." At that time he was not in a car accident, then he was Li Carefree, love his Zhaoling son.

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.