Redis cluster

introduction:

The master-slave architecture solves the problem of redis read and write efficiency
The sentinel solved the problem of a single point of failure. When the master goes down, our sentinel will re-elect a new master
Existing problem: Our master node can read and write data, while our slave node can only read data. The data of the slave node is synchronized from the master node. With a large number of additions, deletions and changes to a project, our master node may not be able to solve the current problem.

Redis cluster

In addition to ensuring the basic functions of master-slave plus sentinel, Redis cluster can also improve Redis's ability to store data through the cluster's hash slot.

Features:

  1. The Redis cluster is non-centralized.
  2. The Redis cluster has a ping-pang mechanism.
  3. For voting mechanism, the number of Redis cluster nodes must be 2n+1.
  4. 16384 hash slots are allocated by default in the Resis cluster. When storing data, the key will be processed by the crc16 algorithm, and the remainder of 16384 will be taken. According to the final result, the key-value will be stored in the executing Redis node, and each Redis clusters are maintaining corresponding hash slots.
  5. In order to ensure data security, each cluster node must be followed by at least one slave node.
  6. Separately build a master-slave for a certain node in the Redis cluster.
  7. When more than half of the nodes in the Redis cluster are down, the Redis cluster is paralyzed.
Hash slot: You can understand it as a table. When using a single node redis, there is only one table, and all keys are placed in this table; after switching to Redis Cluster, 16384 tables will be automatically generated for you, and when you insert data, you will According to the algorithm to determine which table your key should be stored in, there are a lot of data in each table
The advantage of using hash slots is that nodes can be easily added or removed.
When you need to add nodes, you only need to move some of the hash slots of other nodes to the new node;
When you need to remove a node, you only need to move the hash slot on the removed node to another node;
At this point, we don't need to stop all redis services when adding or removing nodes in the future.
Create a docker_redis_cluster directory in the opt directory, edit the docker-compose.yml file, the content is as follows
# docker-compose.ymlversion: "3.1"services:  redis1:    image: daocloud.io/library/redis:5.0.7    restart: always    container_name: redis1    environment:      - TZ=Asia/Shanghai    ports:      - 8001:8001      - 18001:18001    volumes:      - ./conf/redis1.conf:/usr/local/redis/redis.conf    command: ["redis-server","/usr/local/redis/redis.conf"]  redis2:    image: daocloud.io/library/redis:5.0.7    restart: always    container_name: redis2    environment:      - TZ=Asia/Shanghai    ports:      - 8002:8002      - 18002:18002    volumes:      - ./conf/redis2.conf:/usr/local/redis/redis.conf    command: ["redis-server","/usr/local/redis/redis.conf"]    redis3:    image: daocloud.io/library/redis:5.0.7    restart: always    container_name: redis3    environment:      - TZ=Asia/Shanghai    ports:      - 8003:8003      - 18003:18003    volumes:      - ./conf/redis3.conf:/usr/local/redis/redis.conf    command: ["redis-server","/usr/local/redis/redis.conf"]    redis4:    image: daocloud.io/library/redis:5.0.7    restart: always    container_name: redis4    environment:      - TZ=Asia/Shanghai    ports:      - 8004:8004      - 18004:18004    volumes:      - ./conf/redis4.conf:/usr/local/redis/redis.conf    command: ["redis-server","/usr/local/redis/redis.conf"]    redis5:    image: daocloud.io/library/redis:5.0.7    restart: always    container_name: redis5    environment:      - TZ=Asia/Shanghai    ports:      - 8005:8005      - 18005:18005    volumes:      - ./conf/redis5.conf:/usr/local/redis/redis.conf    command: ["redis-server","/usr/local/redis/redis.conf"]    redis6:    image: daocloud.io/library/redis:5.0.7    restart: always    container_name: redis6    environment:      - TZ=Asia/Shanghai    ports:      - 8006:8006      - 18006:18006    volumes:      - ./conf/redis6.conf:/usr/local/redis/redis.conf    command: ["redis-server","/usr/local/redis/redis.conf"]  

Create a conf folder in the docker_redis_cluster directory, and put the redis1.conf...redis6.conf file, pay attention to all the port numbers in the file to be changed

# redis1.conf# 指定redis的端口号port 8001# 开启Redis集群cluster-enabled yes# 每个群集节点都有一个群集配置文件,确保在同一系统上运行的实例没有重叠的集群配置文件名cluster-config-file nodes-8001.conf# 集群对外提供访问的ip地址cluster-announce-ip 192.168.247.128# 集群节点对外端口cluster-announce-port 8001# 集群中实例相互通信的内部总线端口,bus的端口一般是节点端口加上10000cluster-announce-bus-port 18001
# redis2.conf# 指定redis的端口号port 8002# 开启Redis集群cluster-enabled yes# 每个群集节点都有一个群集配置文件,确保在同一系统上运行的实例没有重叠的集群配置文件名cluster-config-file nodes-8002.conf# 集群对外提供访问的ip地址cluster-announce-ip 192.168.247.128# 集群节点对外端口cluster-announce-port 8002# 集群中实例相互通信的内部总线端口,bus的端口一般是节点端口加上10000cluster-announce-bus-port 18002

Started 6 Redis nodes. Note: In the /opt/docker_redis_cluster directory

  • docker-compose up -d

When building, there may be a small episode, our port may be occupied,    click here to    solve.

Just jump into a container and use redis-cli to manage the cluster

redis-cli --cluster create 192.168.247.128:8001 192.168.247.128:8002 192.168.247.128:8003 192.168.247.128:8004 192.168.247.128:8005 192.168.247.128:8006 --cluster-replicas 1

The result of the master-slave configuration is shown in the figure

Store and retrieve data in the redis cluster

The Redis cluster has been set up!

Java connect to Redis cluster

Use the JedisCluster object to connect to the Redis cluster

 @Test    public void test(){        // 创建Set<HostAndPort> nodes        Set<HostAndPort> nodes = new HashSet<HostAndPort>();        nodes.add(new HostAndPort("192.168.247.128",8001));        nodes.add(new HostAndPort("192.168.247.128",8002));        nodes.add(new HostAndPort("192.168.247.128",8003));        nodes.add(new HostAndPort("192.168.247.128",8004));        nodes.add(new HostAndPort("192.168.247.128",8005));        nodes.add(new HostAndPort("192.168.247.128",8006));         // 创建JedisCluster对象        JedisCluster jedisCluster = new JedisCluster(nodes);         // 操作        String value = jedisCluster.get("a");        System.out.println(value);    }