Linux server implements Redis cluster

1, About Redis
Redis is a large-scale cache middleware, which is widely used because of its powerful, efficient and convenient functions.

Redis released 3.0.0 in 2015, and the official supports redis cluster. In the design of redis cluster, decentralization and middleware are considered. In other words, each node in the cluster is equal, and each node keeps its own data and the status of the whole cluster. Each node is connected to all other nodes, and these connections remain active, which ensures that we only need to connect to any node in the cluster to get data from other nodes.

2, Redis cluster introduction
Redis cluster is a facility that can share data among multiple redis nodes. Redis cluster does not support redis commands that need to process multiple keys at the same time, because the execution of these commands requires moving data between multiple nodes, and in the case of high load, these commands will reduce the performance of redis cluster and lead to unpredictable behavior.

Redis cluster provides a certain degree of availability through partition. Even if some nodes in the cluster fail or cannot communicate, the cluster can continue to process command requests.

3, Redis cluster principle
How does Redis match these nodes and data?

Redis does not use the traditional consistent hash to allocate data, but uses another method called hash slot. Redis cluster allocates 16384 slots by default. When we set a key, we will use CRC16 algorithm (cyclic redundancy check code) to obtain the slot to which it belongs, and then divide the key into the node mountain of hash slot interval. Specific algorithm: CRC16 (key)% 16384.

Note: you must be more than three primary nodes to create a cluster, otherwise the cluster assembly fails.

When a Redis cluster is working, one of its primary nodes is down, and there are other master nodes to vote and vote. Only when more than half of the voting results are available can the primary node be down. If more than half of the primary nodes are down, the status of the whole cluster is fail. This is why at least three primary nodes are needed to build a Redis cluster environment.

Benefits of Redis cluster:

1) It has the ability to split data to multiple nodes automatically;
2) When some nodes in the cluster fail or cannot communicate, they still have the ability to continue processing command requests;
3) All rredis nodes are interconnected with each other, and binary protocol is used to optimize the transmission speed and bandwidth; binary protocol: there are message headers and Message Entities in the transmission process. If the header length is fixed. The message entity can be obtained by parsing the message header;
4) The failure of a node is only effective when more than half of the nodes in the cluster detect failure;
5) The client is directly connected to the redis node, and does not need the intermediate proxy layer. The client does not need to connect all the nodes in the cluster, but any available node in the cluster;

The hash slot allocation method used by Redis is good or bad, and the advantage is very clear. For example, I want to add a node D. This method of redis cluster is to take a part of slots from the front of each node to D. It's like this:
Node A covers 1365-5460, node B covers 6827-10922, node C covers 12288-16383, node D covers 013645461-682610923-12287, and the same is true for deleting A node. After the move is completed, the node can be deleted;

So redis cluster is such a shape, as shown in the figure:

4, Redis cluster master-slave mode
Redis cluster adds master-slave mode to ensure high availability of data. A master node corresponds to one or more slave nodes. The master node provides data access, while the slave node obtains data backup from the master node. When the master node goes down, one of the slave nodes will be selected to act as the master node, so as to ensure that the cluster will not hang up.

5, Case implementation
(1) Case environment
Because the cluster environment is implemented with a single server, it is distinguished according to its port!

(2) Case implementation
download Resource bundle
Extraction code 4khu

1) Create six nodes

[root@docker ~]# tar zxf redis-4.0.14.tar.gz -C /usr/local
[root@docker ~]# cd /usr/local/redis-4.0.14/
[root@docker redis-4.0.14]# Make & & make install / / compile and install redis
[root@redis ~]# mkdir -p /usr/local/cluster/700{0..5}
//Since multiple nodes are created in a single platform, this directory is created in advance to store the configuration information of each node
[root@docker ~]# cp /usr/local/redis-4.0.14/redis.conf /usr/local/cluster/7000
//Copy the original redis configuration file
[root@docker ~]# vim /usr/local/cluster/7000/redis.conf / / compile the configuration file of 7000 node
  92 port 7000                             //Modify listening port
 158 pidfile /var/run/redis_7000.pid              //Modify pid file name
 672 appendonly yes                 //Enable aof persistence
 676 appendfilename "appendonly-7000.aof"           //Modify persistent profile name
 814 cluster-enabled yes                   //Enable redis cluster mode
 822 cluster-config-file nodes-7000.conf     //Modify the profile name of the cluster
 828 cluster-node-timeout 5000             //Modify the waiting time of the cluster
[root@docker ~]# cd /usr/local/cluster/7000
[root@docker 7000]# Redis server redis.conf / / you must enter the corresponding directory to start the redis service

However, such an error will occur during startup, as shown in the figure below

[root@redis 7000]# vim /usr/local/cluster/7000/redis.conf / / write the configuration file of 7000 node
 136 daemonize yes                      //Turn on daemons to run in the background
[root@redis 7000]# echo 512 > /proc/sys/net/core/somaxconn 
[root@redis 7000]# echo "vm.overcommit_memory = 1" >> /etc/sysctl.conf
[root@redis 7000]# sysctl -p
vm.overcommit_memory = 1
[root@redis 7000]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
//Simply optimize the redis service according to the warning information just prompted

2) Start each node
[root @ redis 7000] ා redis-server redis.conf / / enter its directory and run the redis service
[root@redis 7000]# cp redis.conf .../7001
[root@redis 7000]# cp redis.conf .../7002
[root@redis 7000]# cp redis.conf .../7003
[root@redis 7000]# cp redis.conf .../7004
[root@redis 7000]# cp redis.conf .../7005
//Because six nodes need to be opened, their configuration files need to be divided into six copies
[root@redis 7000]# sed -i s/7000/7001/g .../7001/redis.conf
[root@redis 7000]# sed -i s/7000/7002/g .../7002/redis.conf
[root@redis 7000]# sed -i s/7000/7003/g .../7003/redis.conf
[root@redis 7000]# sed -i s/7000/7004/g .../7004/redis.conf
[root@redis 7000]# sed -i s/7000/7005/g .../7005/redis.conf
//Because the six nodes are distinguished by port, only the contents named by port number need to be modified in the configuration file
[root@redis 7000]# cd .../7001 && redis-server redis.conf
[root@redis 7001]# cd .../7002 && redis-server redis.conf
[root@redis 7002]# cd .../7003 && redis-server redis.conf
[root@redis 7003]# cd .../7004 && redis-server redis.conf
[root@redis 7004]# cd .../7005 && redis-server redis.conf
//It is to enter its corresponding directory to start the service

[root@redis 7005]# netstat -anpt | grep redis     
tcp        0      0 127.0.0.1:7004          0.0.0.0:*               LISTEN      5615/redis-server 1 
tcp        0      0 127.0.0.1:7005          0.0.0.0:*               LISTEN      5620/redis-server 1 
tcp        0      0 127.0.0.1:17000         0.0.0.0:*               LISTEN      5524/redis-server 1 
tcp        0      0 127.0.0.1:17001         0.0.0.0:*               LISTEN      5592/redis-server 1 
tcp        0      0 127.0.0.1:17002         0.0.0.0:*               LISTEN      5605/redis-server 1 
tcp        0      0 127.0.0.1:17003         0.0.0.0:*               LISTEN      5610/redis-server 1 
tcp        0      0 127.0.0.1:17004         0.0.0.0:*               LISTEN      5615/redis-server 1 
tcp        0      0 127.0.0.1:17005         0.0.0.0:*               LISTEN      5620/redis-server 1 
tcp        0      0 127.0.0.1:7000          0.0.0.0:*               LISTEN      5524/redis-server 1 
tcp        0      0 127.0.0.1:7001          0.0.0.0:*               LISTEN      5592/redis-server 1 
tcp        0      0 127.0.0.1:7002          0.0.0.0:*               LISTEN      5605/redis-server 1 
tcp        0      0 127.0.0.1:7003          0.0.0.0:*               LISTEN      5610/redis-server 1 
//Check that all ports are listening. The remaining 17000 ports are used for communication between clusters

3) Allocate hash slots for each node and join the cluster environment

[root@redis 7005]# Redis cli - P 7000 / / enter the redis terminal by specifying any port
127.0.0.1:7000> CLUSTER INFO                  //View cluster details

cluster_state:fail                          //It's found that it's a fail ed state
........................                       //Omit part of the content
127.0.0.1:7000> CLUSTER NODES           //View cluster nodes
d554512885b2679d432d0d6b011c9ea56ea1ebeb :7000@17000 myself,master - 0 0 0 connected
//Only 7000 nodes were found to join the cluster
127.0.0.1:7000> exit
[root@redis 7005]# redis-cli -h 127.0.0.1 -p 7000 cluster addslots {0..5461}
OK
[root@redis 7005]# redis-cli -h 127.0.0.1 -p 7001 cluster addslots {5462..10922}
OK
[root@redis 7005]# redis-cli -h 127.0.0.1 -p 7002 cluster addslots {10923..16383}
OK
//Assign a hash slot to each cluster stage
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7000
OK
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7001
OK
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7002
OK
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7003
OK
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7004
OK
127.0.0.1:7000> CLUSTER MEET 127.0.0.1 7005
OK
//It is used to connect different Redis nodes that enable cluster support to enter the working cluster
[root@redis 7005]# redis-cli -p 7000
127.0.0.1:7000> CLUSTER INFO
cluster_state:ok                     //Check the cluster status again and find that it is "ok"
........................                   //Omit part of the content
127.0.0.1:7000> CLUSTER NODES                   //View cluster nodes again

As shown in the picture:

The default environment is 7000 as the primary node of 7003, 7001 as the primary node of 7004, and 7002 as the primary node of 7005. The operations are as follows:

[root@redis 7005]# Redis cli - P 7003 / / connect nodes of 7003
127.0.0.1:7003> CLUSTER REPLICATE d554512885b2679d432d0d6b011c9ea56ea1ebeb
OK           //This is the ID number of 7000
127.0.0.1:7003> exit
[root@redis 7005]# Redis cli - P 7004 / / connect nodes of 7004
127.0.0.1:7004> CLUSTER REPLICATE 182a55ee8b38afbf5b48209979f220dc4da7c14a
OK                    //This is the ID number of 7001
127.0.0.1:7004> exit
[root@redis 7005]# Redis cli - P 7005 / / connect nodes of 7005
127.0.0.1:7005> CLUSTER REPLICATE 82b62bda5b31d8ee27aee8d7320663ee86276e9f
OK                   //This is the ID number of 7002
127.0.0.1:7005> CLUSTER NODES           //View cluster node details again

As shown in the picture:

4) Access data for testing

[root@redis 7005]# Redis cli - P 7000 / / enter the node and insert data for testing
127.0.0.1:7000> set name zjz
(error) MOVED 5798 127.0.0.1:7001           
//An error is found, indicating that the node of 7001 should store this data
127.0.0.1:7000> exit
[root@redis 7005]# Redis cli - P 7000 - c / / use the "- c" option to enter the cluster
127.0.0.1:7000> set name zjz                //Reinsert data
-> Redirected to slot [5798] located at 127.0.0.1:7001
OK               //Prompt to store data on node 7001
127.0.0.1:7001> get name               //Get the value corresponding to the key
"zjz"

5) Simulate single node failure

[root@redis 7001]# cd ../7001
[root@redis 7001]# redis-cli -p 7001 shutdown
//Simulate 7001 node failure
[root@redis 7001]# redis-cli -p 7000
127.0.0.1:7000> CLUSTER NODES            //Enter the node to view the status of the cluster node
127.0.0.1:7004> get name
"zjz"

As shown in the picture:

[root@redis 7001]# redis-server redis.conf 
//Enter the directory corresponding to 7001 and start the redis node
[root@redis 7001]# redis-cli -p 7000  
127.0.0.1:7000> CLUSTER NODES               //Enter cluster to view cluster status

As shown in the picture:

6) Install ruby software (the resource package above has)

[root@redis ~]# yum -y install rpm-build openssl openssl-devel
//Dependencies required to install ruby
[root@redis ~]# tar zxf ruby-2.3.1.tar.gz -C /usr/src
cd [root@redis ~]# cd /usr/src/ruby-2.3.1/
[root@redis ruby-2.3.1]# ./configure --prefix=/usr/local/ruby && make && make install
//Compiling and installing ruby may take a long time
[root@redis ~]# ln -s /usr/local/ruby/bin/* /usr/local/bin
//Creating symbolic links for gem commands
[root@redis ~]# ln -s /usr/local/redis-4.0.14/src/* /usr/local/bin
//Creating symbolic links for redis common commands
[root@redis ~]# gem install redis-3.3.0.gem 
//Use gem command to install Redis cluster prerequisite package

7) Add master 7006

[root@redis ~]# redis-trib.rb check 127.0.0.1:7000
//Check cluster node status

[root@redis ~]# mkdir /usr/local/cluster/7006
[root@redis ~]# cd /usr/local/cluster/7006
//Create corresponding directory and enter
[root@redis 7006]# cp ../7000/redis.conf .
[root@redis 7006]# sed -i s/7000/7006/g redis.conf 
//Copy the configuration file and make changes
[root@redis 7006]# redis-server redis.conf 
//Modify the redis service of 7006 node
[root@redis ~]# redis-trib.rb add-node 127.0.0.1:7006 127.0.0.1:7000
//Add 7006 nodes to the 7000 node cluster environment (the default is the master state)
[root@redis ~]# redis-trib.rb check 127.0.0.1:7000
//View cluster status again

As shown in the picture:

It can be found that the 7006 node has no slot point and cannot store data!

[root@redis ~]# redis-trib.rb reshard 127.0.0.1:7000 / / allocate 7000 slot points of this cluster
How many slots do you want to move (from 1 to 16384)? 4096    //How many nodes to operate on
What is the receiving node ID?7add42108b3fc3e9c0af2846fb06ceaf8b172c87  
//For 7006 node, the ID number of 7006 node is entered here
Source node #1:all / / allocation starts from all nodes
[root@redis ~]# redis-trib.rb check 127.0.0.1:7000
//View cluster status again

As shown in the picture:

9) Add slave 7008

[root@redis ~]# mkdir /usr/local/cluster/7008
[root@redis ~]# cd /usr/local/cluster/7008
[root@redis 7008]# cp ../7000/redis.conf .
[root@redis 7008]# sed -i s/7000/7008/g redis.conf 
[root@redis 7008]# redis-server redis.conf 
//Create the corresponding directory and modify the configuration file to start the service
[root@redis ~]# redis-trib.rb add-node --slave --master-id 7add42108b3fc3e9c0af2846fb06ceaf8b172c87 127.0.0.1:7008 127.0.0.1:7000
//Add a node to the cluster, specify it as a salve, and specify the primary node ID number (the ID of the 7006 node)
[root@redis ~]# redis-trib.rb check 127.0.0.1:7000
//View cluster status

As shown in the picture:

10) Delete 7000 nodes

[root@redis ~]# redis-trib.rb reshard 127.0.0.1:7000 / / operate on the cluster node
How many slots do you want to move (from 1 to 16384)? 4096                     //Operate on multiple nodes
What is the receiving node ID? 
7add42108b3fc3e9c0af2846fb06ceaf8b172c87             //Here enter the slot node to be deleted to that node (7006 node)
Source node d554512885b2679d432d0d6b011c9ea56ea1ebeb    //Enter deleted nodes
Source node  done
Do you want to proceed with the proposed reshard plan (yes/no)? yes
//Acknowledgement
[root@redis ~]# redis-trib.rb del-node 127.0.0.1:7000 d554512885b2679d432d0d6b011c9ea56ea1ebeb
//Deleting 7000 nodes in a 7000 cluster
[root@redis ~]# redis-trib.rb check 127.0.0.1:7001 / / check the cluster status

As shown in the picture:

234 original articles published, 212 praised, 40000 visitors+
Private letter follow

Tags: Redis Ruby Docker vim

Posted on Thu, 13 Feb 2020 03:35:50 -0500 by mu-ziq