This is a creation in Article, where the information may have evolved or changed.
REMOTE DICTIONARY SERVER
Why write this series?
In the previous period, "July, Redis fan" mentioned, our online Redis Cluster + Smart Proxy mode. I put the code on a personal github, which is interesting to download and use. If you encounter problems, open issue at any time, or call me directly. There are restrictions on the support commands, which are described in detail in the readme.
# Go get github.com/dongzerun/smartproxy
# make &&./cmd/redis_proxy-config_file=example.ini
Why rewrite it for the following reasons:
1. The current implementation requires a string conversion of the input, and you know that in Golang, a large number of byte[] to string performance is not high and the pressure on the GC is large. You can refer to Bitly's official documentation for NSQ optimization.
2. Reusing Go Redis Driver, encapsulating the network layer, resulting in an invalid processing process, can be overridden from the bottom of the optimization.
3. Redis is quite small in the database domain, and developing middleware facilitates understanding of the database.
4. Developed by module, with Go Unit test, deepen the cognition and performance tuning of Go language.
The new Proxy target
The old agent has no problem with the current use, and the performance is sufficient. New to achieve the following functions
1. Support Redis Cluster protocol, masking language differences, this is the core.
2. Command detection, detection of dangerous or unsupported commands in advance.
3. Support Pipeline, this usage scene is still many, the old agent cannot realize.
4. More detailed performance statistics, built-in Http DashBoard for query.
5. Service discovery and registration, support Zookeeper and ETCD.
Redis Client Protocol
Redis protocol is much simpler than MySQL protocol, interested students can view the corresponding driver source code, deepen the understanding of the Protocol. Redis belongs to the text protocol, based on the Request-response model, officially called RESP (Redis serialization Protocol).
Response Protol
The RESP protocol has five types of responses, each ending with CRLF (\\r\\n)
1. Easy Strings: Simple character answer begins with "+", follows the string data, and ends with CRLF
Simple Strings Reply
The returned data in the example is +ok\\r\\n
2. Errors: The error answer begins with "-", follows the string of the reason for the error, and ends with CRLF
Errors Reply
The data returned in the example is-err wrong number of arguments for ' get ' command\\r\\n
3. Integers: Integer answer begins with ":", follows integer value, and ends with CRLF
Integers Reply
The returned data in the example is: 2\\r\\n
4. Bulk Strings: String answer begins with "$" and follows the length and data of the real data
Bulk String Reply
The returned data in the example is $3\\r\\nbar\\r\\n
5. Arrays: Array type answer starts with "*" and follows multiple Bulk strings responses
Array Reply
The data returned in the example is *4\\r\\n$1\\r\\nb\\r\\n$1\\r\\n$a\\r\\n$1\\r\\nd\\r\\n$-1\\r\\n, where the last 1 indicates that the last key in the corresponding command does not exist
Command Protol
For the simplest command SET Foofoo BAR, the data that the client actually sends to the SERVER is
*3\\r\\n$3\\r\\nset\\r\\n$6\\r\\nfoofoo\\r\\n$3\\r\\nbar\\r\\n
Use Telnet to simulate the following
Set Foofoo Bar
The final +ok indicates that the command executed successfully, back to simple string OK, that is, the command behavior is consistent with the Array Reply.
About Redis Cluster
The official website has two articles cluster-spec and cluster-tutorial, detailed explained the Redis cluster realization principle and the construction, Hunan TV provides the Python edition Redis-trib, everybody may use constructs and migrates the cluster data very side Will exactly How to build and Cluster the internal election algorithm here do not explain, need to pay attention to cluster-require-full-coverage This parameter should be set to No
If this was set to Yes, as it was by default, the cluster stops accepting writes if some percentage of the key space was not Covered by any node. If the option is set to No, the cluster would still serve queries even if only requests about a subset of keys can Proce ssed.
In short, Cluster will Key (or according to the hash tag) according to CRC16 processing to get the hash value, the value by 16384 modulo, so that the data will be evenly divided into 16384 slots, is a logical slot, logic slots and Cluste r-nodes.conf determine which physical slave-to-master pair specifically belongs to
Cluster-nodes.conf
Cluster info
Using the Cluster Info command, you can see the current cluster information, cluster_slots_assigned represents the slots number of physical nodes currently allocated, and CLUSTER_SLOTS_OK indicates how many slots normal services are currently available, The fail and pfail indicate the number of slots of the current node who are subjective and objective downtime, cluster_size indicates how many physical master-slave pairs are in the cluster, and refer to the official documentation for more detailed parameters.
With a non-centric design, the client randomly connects to a node and initiates the request. Redis obtains a hash value based on Key, obtains a slot ID, and finds in memory which physical node the slot ID is currently part of. If it is not native, then Redis returns a Errors Reply for the client, and the error content is a MOVE redirect, for example:
127.0.0.1:6494> Get B
(Error) MOVED 3300 10.10.10.178:6494
At this time the client according to MOVED instruction, to connect 10.10.10.178:6494 instance, initiate the same request, get the correct data. Ideally, the Smart client can find the correct node by simply MOVED the jump once.
When a slot is migrated, Redis marks the slot as the migrating state at the source node, while marking the target node as the importing State. When a client initiates a request, all traffic is forwarded to the source node, if the data exists then returns. If the data does not exist, it may have been migrated to the target node. The source node returns a-ask error attaching the target node information, the client connects to the target node, initiates a asking command, and then sends a normal request. If the asking command is not sent first, the target node is considered an illegal request and returns a MOVED redirect.
Smart Proxy Design Ideas
Understand the Redis Cluster principle, then the core design is much simpler. All other functions are embellish. The specific module is divided into the next share, each writing a module, and attached to the detailed Go test and performance test.
1. Obtain the Cluster config configuration information periodically and cache it in Proxy memory.
2. After the request Key is hashed value, the query Slots configuration is sent to the specified backend node.
3. Handle the MOVED and ASK two exceptions.
Conclusion
This article only to talk about some theoretical basis, follow-up specific coding, I hope I can persist in writing ~_~ recommend everyone a song " Compressed Biscuits " from the big ice