Redis Cluster (Cluster) Demo-Super detailed demonstration steps + Spring Boot walkthrough

Insert picture description here
The Redis used in this article is 5.0.8, so the difference from the old version 4.0.X lies in the change of the way of creating a cluster

System used: Centos7.7 64-bit

The unified password set in this article is: shunleite

Spring Boot 2.0+

First, the principle of the cluster

In a Redis cluster, all Redis nodes are interconnected with each other, and the binary protocol used inside the nodes optimizes the transmission speed and bandwidth.

After a node hangs up, only when more than half of the nodes in the cluster persist to fail, it is considered that the node has failed. Any in the Redis cluster

The nodes are connected to the Java client. Hash slot is used for data distribution on Redis cluster, built in Redis cluster

There are 16384 hash slots. When there is data to be stored, Redis will first use the CRC16 algorithm to calculate the Key and obtain the calculation.

The result is the remainder of 16384, so that each key corresponds to a hash slot with a value between 0 and 16383. Redis is based on this

The remainder stores this data on the corresponding Redis node, and the programmers can adjust each Redis according to the performance of each Redis instance

Distribution range of hash slots on the instance

Second, distributed cluster planning

Need to understand some concepts:
a master (master) can have multiple slaves (slave), and a slave (slave) can only have one master (master)
In addition, each official requires at least three masters in each cluster to run
this The case takes each port corresponding to each server to distinguish each different Redis server

主节点:111.67.194.61:6661,111.67.194.60:6662,111.67.194.63:6663

从节点:111.67.194.64:6664,111.67.194.65:6665,111.67.202.207:6666

两个用来测试添加主从数据库的节点: 111.67.194.70:6667(主),111.67.194.108:6668(从)

3. Redis cluster configuration

1. Install the cluster management tool (the cluster big brother server 111.67.194.61 is used to configure the Ruby environment, which is only on this one)

Because the Redis cluster tool depends on the Ruby environment, you first need to install the Ruby environment, and because
the default Ruby version in the centos7 yum library is too low, so a convenient RVM tool (the following steps are to download and configure the rvm public key)

gpg2 --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
#上面个木有成功就下面那个
gpg2 --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
curl -L get.rvm.io | bash -s stable
source /usr/local/rvm/scripts/rvm

See if RVM is installed successfully

rvm list known

If the green appears as shown in the picture, it will succeed.
Insert picture description here
Choose a more stable version (the time of the tutorial is 2020/4/5)
Insert picture description here

rvm install 2.6.5

Insert picture description here
Finally install Redia dependencies

gem install redis

2. Install Redis:

①Download Redis

wget http://download.redis.io/releases/redis-5.0.8.tar.gz

If there is no wget command, you need to install it, and then execute the above command

yum install wget

② To install Redis,
first create a redisCluster folder, move the downloaded file over and then install

mkdir redisCluster
cp -f ./redis-5.0.8.tar.gz ./redisCluster
cd redisCluster
tar -zxvf redis-5.0.8.tar.gz
cd redis-5.0.8
make MALLOC=libc
make install

③Each of the other devices must perform the second step (this operation is required for each server)

RedisCluster then created under each server (including Big Brother server 111.67.194.61) of a folder (to add in a single stage in the production of the back)
were folder 6661 6662 6,663,666,466,656,666 (consistent with the previous planning portion)
Further Under each folder, you need to copy the redis.conf file under the redis-5.0.8 directory in the upper directory to this directory

cp -f ../redis-5.0.8/redis.conf ./

Next, modify the configuration of redis.conf in the 666x folder of each server. The modified configuration is as follows (modified or not added)

port 6661
#bind 127.0.0.1
cluster-enabled yes
cluster-config-file nodes-6661.conf
protected no
daemonize yes
requirepass shunleite
masterrauth shunleite

Insert picture description here
Insert picture description here
Insert picture description here
Mention: If you use vi, then you need to slowly find / modify the string mode

    第一为该节点端口与文件夹名一一对应

    第二行是将bind部分注释掉,因为默认是本地乱接,注释掉就可以外网连接Redis了

    第三行表示开启集群

    第四行表示该集群节点的配置文件(注意nodes-666x.conf格式配置方便管理)

    第五行就是关闭保护毕竟你第七行用了密码

    第六行表示允许Redis后台运行

    第七行就是设置密码了

    第八行因为第七行设置了密码所以他就需要个密码认证

④Open Redis instance

redis-server /root/redisCluster/6661/redis.conf
redis-server /root/redisCluster/6662/redis.conf
redis-server /root/redisCluster/6663/redis.conf
redis-server /root/redisCluster/6664/redis.conf
redis-server /root/redisCluster/6665/redis.conf
redis-server /root/redisCluster/6666/redis.conf

⑤ In order to be able to connect to Redis remotely, you also need to close the firewall (or open the corresponding port)

systemctl stop firewalld.service
systemctl disable firewalld.service

Insert picture description here
Go back to the big brother server (111.67.194.61) and switch to the redisCluster directory

3. Create a cluster (this step runs on the big brother server)

    提一下:因为设置了密码,一般来说,Redis5.0.x以下的版本是需要将redis-trib.rb文件复制到redisCluster目录下的

    然而我们用的不是(嘻嘻)如果是就需要移

    而且还需修改复制后的redis-trib.rb文件,将@r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60)这行

    修改成@r = Redis.new(:host => @info[:host], :port => @info[:port], :timeout => 60, :password=>"shunleite")

    然后操作就把后面的redis-cli -a shunleite --cluster的部分改成./redis-trib.rb(在你redisCluster目录下)即可(虽然有些细微的不一样比如删除啥

    子,但大多一样,毕竟官方只是进行移植集成操作)

Create a cluster

redis-cli -a shunleite --cluster create 111.67.194.61:6661 111.67.194.60:6662 111.67.194.63:6663 111.67.194.64:6664 111.67.194.65:6665 111.67.202.207:6666 --cluster-replicas 1

replicas represents the number of salves for each master node. During the creation of the cluster, a unique id will be assigned and a slot will be assigned. The
successful results are as follows: M code master node, S code slave node, slots are the allocated slot segments, and the Id behind the replicates represents the corresponding master node Id
Insert picture description here
Insert picture description here

-h 表示实例主机地址 -p表示登陆的集群的端口,-a表示要登陆的集群的密码,-c则便是以集群的方式登陆,登陆成功后随便登陆一个节点

使用cluster nodes命令查询集群节点的信息,cluster info命令查询集群状态信息,此时你会发现已经自动配置好了slot
redis-cli -h 111.67.194.61 -p 6661 -a shunleite -c
cluster info
cluster nodes

Insert picture description here

4. Addition and deletion of master and slave nodes in Redis cluster

1. The master node increases

In the case of business growth, we cannot avoid adding the master node. Adding the master node is to build an instance of the master node.
① Press the second step ② and ③, ④, ⑤ of the second step in the Redis cluster configuration link. The small step model is 111.67.194.70 Create a folder 6667 on the node (configuration

The same as the above steps, I will not demonstrate here)
② The same model as Redis: redis-server /root/redisCluster/6667/redis.conf ③Then
log in to the big brother server (111.67.194.61) to perform the add node operation, add- node is the operation of adding a node, the parameter in the middle is the Redis to be added

Instance address, the last parameter is the instance address in the cluster

redis-cli -a shunleite --cluster add-node  111.67.194.70:6667 111.67.194.61:6661

Insert picture description here
Log in to an instance in any cluster and execute cluster nodes to find that the instance address has been added successfully, but the slot is not allocated. Pay attention to the node ID of 6667 of the node.

    此新节点的ID为:d35877f5646c96fdfce71bdf66f588e8c90fd520

Insert picture description here
④Reallocate the next slot (in this case, allocate 1,000 slots to the new master node)

Because the previous operation has allocated the slot, there is no slot allocated to the new node, that is, the book new node does not have the opportunity to store data, so we can
take part of the other three master nodes and allocate it to the new node instance. A total of 1000 slots are allocated to new nodes

If you are assigning n slots to whom, enter the ID of the Redis instance that receives the n slots. You can see this ID when you add it, or you can also see it by
using the clustern nodes command after logging in to the cluster controller. . For example, take n slots from the instance with port 6661 and assign it to the instance with 6667, then enter the id of 6661, press
Enter, and type done to press the return key.

Log in to the big brother server (111.67.194.61) and execute the following code redistribution, all means to share the original instance

redis-cli -a shunleite --cluster reshard 111.67.194.61:6661
#接着填入1000
#在填写节点的ID
#填入all

Insert picture description here
After the flat:
Insert picture description here

2. Increase from the node

It's much easier to increase the number of nodes

① Still follow the second step ② and ③, ④, ⑤ of the second step in the Redis cluster configuration link to create a folder 6668 on the node 111.67.194.108 and then

Start it

② Log in to the big brother server (111.67.194.61) and add the slave node. You need to specify the master id of the answer. The parameters behind –cluster-master-id indicate in order:

The id of the slave node master (here is 6667 as an example), the address of the slave node, and the address of any instance in the cluster. code show as below:

redis-cli -a shunleite --cluster add-node --cluster-slave --cluster-master-id d35877f5646c96fdfce71bdf66f588e8c90fd520 111.67.194.108:6668 111.67.194.61:6661

After logging in to the cluster controller and entering cluster nodes, you can see that the
Insert picture description here
new version of Redis below 5.0.x adds new slave nodes. You need to use the following command to add child nodes in the redisCluster directory (the command meaning is basically the same as above):

./redis-trib.rb add-node --slave --master-id d35877f5646c96fdfce71bdf66f588e8c90fd520 111.67.194.108:6668 111.67.194.61:6661

3. Node deletion

Delete the node and log in to the big brother server (111.67.194.61). Use the following command to delete the model:

del-node stands for delete node. The following parameter is the node to be deleted. If the deleted node occupies the slot, the deletion will fail, then you follow the fourth step

Add and delete the master node and slave node of the Redis cluster. In step 1, step ④, allocate all the slots of the node to be deleted, and then execute this command. The slave node

Delete this command directly

redis-cli -a shunleite --cluster del-node 111.67.194.61:6661

Five, Spring Boot case demonstration

Unlike single instance Redis, Redis cluster integration Spring Boot requires manual configuration by programmers

1. Configuration dependencies

The jedis connection pool is implemented based on apache.commons-pool2. When Hou builds the connection pool object, you need to provide the configuration object of the connection pool object, that is, JedisPoolConfig,

JedisPoolConfig inherits from GenericObjectPoolConfig, we can use this configuration object to configure related parameters of the connection pool (such as the maximum number of connections,

Maximum idle number, etc.)

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
</dependency>

2. Configure cluster information (application.yml)

At this time, it is much more convenient to use application.yml, so just delete the original application.properties and create it.

Because there are many hosts used, it is enough to create two one-to-one corresponding arrays, which is also convenient for subsequent operations of adding and deleting nodes in production

max-total represents the maximum number of connections in the connection pool, max-idle represents the maximum number of idle connections in the connection pool, max-wait-millis represents the maximum blocking wait time, the default is -1

Indicates no limit, min-idle indicates the minimum number of connections in the connection pool

spring:
  redis:
    cluster:
      ports:
        - 6661
        - 6662
        - 6663
        - 6664
        - 6665
        - 6666
        - 6667
        - 6668
      hosts:
        - 111.67.194.61
        - 111.67.194.60
        - 111.67.194.63
        - 111.67.194.64
        - 111.67.194.65
        - 111.67.202.207
        - 111.67.194.70
        - 111.67.194.108
      poolConfig:
        max-total: 8
        max-idle: 8
        max-wait-millis: -1
        min-idle: 0

3. Configure Redis to create RedisConfig

Let's analyze

RedisAutoConfiguration is provided in SpringBoot's automatic configuration class for Redis configuration. The source code is as follows:
** Bold style **
this source code can be seen, the configuration information in the default application.properties will be injected into RedisProperties, if no RedisTemplate or

StringRedisTemplate instance, then Spring Boot will provide these two examples by default, RedisTemplate and StringRedisTemplate both provide Redis

Basic operation
Insert picture description here
As this case uses Jedis, plus JedisConnectionFactory inherits from RedisConnection

So we need to manually configure and provide Redis cluster configuration, JedisConnectionFactory, RedisTemplate, StringRedisTemplate.

@Configuration
//通过ConfigurationProperties注解声明配置文件前缀,配置文件中定义的ports,hosts数组及连接配置信息都将被注入port、host、poolConfig三个属性中
@ConfigurationProperties("spring.redis.cluster")
public class RedisConfig {
    List<Integer> ports;
    List<String> hosts;
    JedisPoolConfig poolConfig;
    //配置RedisClusterConfiguration实例,设置Redis登陆密码以及Redis节点信息
    @Bean
    RedisClusterConfiguration redisClusterConfiguration(){
        RedisClusterConfiguration configuration = new RedisClusterConfiguration();
        List<RedisNode> nodes = new ArrayList<>();
        for(int i = 0;i<ports.size();i++){
            nodes.add(new RedisNode(hosts.get(i),ports.get(i)));
        }
        //配置RedisClusterConfiguration实例,摄制Redis登陆密码以及Redis节点信息
        configuration.setPassword(RedisPassword.of("shunleite"));
        configuration.setClusterNodes(nodes);
        return configuration;
    }
    //根据RedisClusterConfiguration实例以及连接池配置信息Jedis连接工厂JedisConnectionFactory
    @Bean
    JedisConnectionFactory jedisConnectionFactory(){
        JedisConnectionFactory factory = new JedisConnectionFactory(redisClusterConfiguration(),poolConfig);
        return factory;
    }
    //根据RedisConnectionFactory创建RedisTemplate和StringRedisTemplate,同时配置key和value的系列化方式。
    // 有了RedisTemplate和StringRedisTemplate,剩下的用法就和单一使用Redis用法一致
    @Bean
    RedisTemplate redisTemplate(){
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        return redisTemplate;
    }
    @Bean
    StringRedisTemplate stringRedisTemplate(){
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(jedisConnectionFactory());
        stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
        stringRedisTemplate.setValueSerializer(new StringRedisSerializer());
        return stringRedisTemplate;
    }
 
    @Override
    public String toString() {
        return "RedisConfig{" +
                "ports=" + ports +
                ", hosts=" + hosts +
                ", poolConfig=" + poolConfig +
                '}';
    }
 
    public List<Integer> getPorts() {
        return ports;
    }
 
    public void setPorts(List<Integer> ports) {
        this.ports = ports;
    }
 
    public List<String> getHosts() {
        return hosts;
    }
 
    public void setHosts(List<String> hosts) {
        this.hosts = hosts;
    }
 
    public JedisPoolConfig getPoolConfig() {
        return poolConfig;
    }
 
    public void setPoolConfig(JedisPoolConfig poolConfig) {
        this.poolConfig = poolConfig;
    }
}

4. Create an entity class

public class Customer implements Serializable {
    private String name;
    private String email;
 
    @Override
    public String toString() {
        return "Customer{" +
                "name='" + name + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getEmail() {
        return email;
    }
 
    public void setEmail(String email) {
        this.email = email;
    }
}

5. Create Controller (direct test, just demonstrate how to use)

StringRedisTemplate is a subclass of RedisTemplate. The key and value in StringRedisTemplate are strings, which are used

The serialization scheme is StringRedisSerializer, and RedisTemplate can be used to manipulate objects. The serialization adopted by RedisTemplate

The solution is JdkSerializationRedisSerializer. Whether it is StringRedisTemplate or RedisTemplater, the method of operating Redis is the same

Both StringRedisTemplate and RedisTemplate first obtain an operation object through methods such as opsForValue, opsForZSet or opsForSet,

Then use the operation object to complete the reading and writing of data

@RestController
public class CustomerController {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @GetMapping("/test1")
    public void test1(){
        ValueOperations ops = redisTemplate.opsForValue();
        Customer customer = new Customer();
        customer.setName("shunzi");
        customer.setEmail("[email protected]");
        ops.set("customer",customer);
        System.out.println("customer = " + ops.get("customer"));
        ValueOperations<String,String> ops2 = stringRedisTemplate.opsForValue();
        ops2.set("ceshi","数据正确");
        System.out.println("ceshi = " + ops2.get("ceshi"));
    }
}

6. Enter 127.0.0.1:8080/test1 to test

Insert picture description here

7. Log in to any Redis server instance and query the data to see the query results

get customer
get ceshi

Insert picture description here
RedisCluster will be responsible for redirecting the query request to the corresponding instance.

The tutorial is very long and has a lot of details, so practice it again after reading it patiently.

Almost forgot, the case source code is provided below

Baidu SkyDrive: https://pan.baidu.com/s/17pNKWjfu_Fb70_x12m5ckQ (snet)

Ordinary download: http://t.cn/A6Z1r6tG

Lan Zuoyun: https://lanzous.com/ib1ip9e

Published an original article · Liked 0 · Visits 7

Guess you like

Origin blog.csdn.net/shunleite/article/details/105669237