Redis Cluster cluster master-slave scheme

This article introduces a high-availability solution to realize Redis cluster (master-slave) through Jedis and Cluster. This solution requires Jedis2.8.0 (recommended), Redis3.0 and above (mandatory).

Attachment:
Redis Cluster cluster master-slave solution: http://www.cnblogs.com/soul-wonder/p/8891256.html
Redis Sentinel master-slave high availability solution: http://www.cnblogs.com/soul-wonder/ p/8891217.html

1. Introduction to Redis Cluster

  • Redis Cluster is an assembly that provides data sharing among multiple Redis nodes.
  • Redis Cluster does not support commands that handle multiple keys, because this requires moving data between different nodes, which does not achieve Redis-like performance and may cause unpredictable errors under high load.
  • Redis Cluster provides a certain degree of availability through partitioning, and continues to process commands in the actual environment when a node is down or unreachable.
  • The Redis cluster has 16384 hash slots. After each key is checked by CRC16, the modulo of 16384 is used to determine which slot to place. Each node of the cluster is responsible for a part of the hash slot. For example, if the current cluster has 3 nodes, then : Node A contains hash slots 0 to 5500. Node B contains hash slots 5501 to 11000. Node C contains hash slots 11001 to 16384.

Second, the advantages of Redis Cluster cluster:

  • Automatically split data into different nodes.
  • The entire cluster can continue to process commands in the event that some nodes in the entire cluster fail or become unreachable.
  • The client is directly connected to the redis node, and no intermediate proxy layer is required. The client does not need to connect to all nodes in the cluster, just connect to any available node in the cluster.
  • Master-slave replication model is supported. (slave->master election, cluster fault tolerance)

3. Master-slave replication model of Redis Cluster cluster:

In order to make the cluster still available when some nodes fail or most nodes cannot communicate, the cluster uses a master-slave replication model. If there is a cluster of three nodes A, B, and C, in the absence of a replication model, if If node B fails, the entire cluster will think that the slot in the range of 5501-11000 is unavailable.
However, if we add a slave node A1, B1, and C1 to each node when the cluster is created, then the entire cluster will have three It consists of one master node and three slave nodes, so that after node B fails, the cluster will elect B1 as the new master node to continue serving, and the entire cluster will not be unavailable because the slot cannot be found.

4. Redis Cluster model diagram

Five, Redis installation and cluster configuration

Download the latest redis installation package
wget http://download.redis.io/releases/redis-3.0.7.tar.gz
Unzip
the tar xzf redis-3.0.7.tar.gz 
install the support package tcl
yum install tcl  compile the original file
make
creates cluster related files (convenient for management)
mkdir cluster 
cd cluster
mkdir 6379 6380 6381 6382 6383 6384 
A redis.conf file is created in each directory under cluster. Pay attention to modify the port number in the file:

port 6379
cluster-enabled yes
cluster-config-file nodes_6379.conf
cluster-node-timeout 5000
appendonly yes

Copy the executable file of redis-server to each directory under the cluster, then open 6 shell terminals, enter each directory, and start each instance. The command is as follows: 
./redis-server redis.conf

Check if all 6 services are started

Build a
cluster./redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384

--replicas 1 indicates that we want to create a slave node for each master node in the cluster.
At this time, an error was reported, and it was found that the corresponding ruby ​​environment was missing. Install the corresponding environment as follows:
yum install ruby
​​yum install rubygems
gem install redis

After installing the environment, build the cluster
again./redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 

Detect cluster node related information./redis-trib.rb 
check 127.0.0.1:6379 

 

It can be found that the system uses the first three services as the master node, and the last three services as the slave nodes, and they are corresponding.

Enter a node to
verify./redis-cli -c -h 127.0.0.1 -p 6379

 

It can be found that the program modulo 16384 according to the key value is 3488, and jumps to the corresponding node according to the distribution of hash slots. It can be seen that the cluster environment is running normally

Six, Jedis Cluster tutorial

Xml code:
copy code
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- Jedis link pool configuration, note: Jedis version is recommended to upgrade to the latest -->
    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="100" />
        <property name="maxIdle" value="20" />
        <property name="minIdle" value="10" />
        <property name="blockWhenExhausted" value="true"></property>
        <property name="maxWaitMillis" value="3000" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <property name="testWhileIdle" value="true" />
        <property name="minEvictableIdleTimeMillis" value="60000" />
        <property name="timeBetweenEvictionRunsMillis" value="30000" />
        <property name="numTestsPerEvictionRun" value="-1" />
    </bean>

    <!-- JedisCluster -->
    <bean id="jedisCluster" class="redis.clients.jedis.JedisCluster">
        <constructor-arg index="0">
            <set>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.1.111" />
                    <constructor-arg index="1" value="7111" type="int" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.1.112" />
                    <constructor-arg index="1" value="7112" type="int" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.1.113" />
                    <constructor-arg index="1" value="7113" type="int" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.1.114" />
                    <constructor-arg index="1" value="7114" type="int" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.1.115" />
                    <constructor-arg index="1" value="7115" type="int" />
                </bean>
                <bean class="redis.clients.jedis.HostAndPort">
                    <constructor-arg index="0" value="192.168.1.116" />
                    <constructor-arg index="1" value="7116" type="int" />
                </bean>
            </set>
        </constructor-arg>
        <constructor-arg index="1" value="2000" type="int"></constructor-arg>
        <constructor-arg index="2" value="100" type="int"></constructor-arg>
        <constructor-arg index="3" ref="jedisPoolConfig"></constructor-arg>
    </bean>

</beans>
copy code
 
Java code: 
copy code
package wusc.edu.demo.redis;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import redis.clients.jedis.JedisCluster;


public class RedisClusterSpringTest {
    private static final Log log = LogFactory.getLog(RedisClusterSpringTest.class);

    public static void main(String[] args) {
        try {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml");
            context.start();
            
            JedisCluster jedisCluster = (JedisCluster) context.getBean("jedisCluster");
            int num = 1000;
            String key = "yingjun";
            String value = "";
            for (int i=1; i <= num; i++){
                // save data
                //jedisCluster.set(key+i, "yingjun"+i);
                //jedisCluster.setex(key+i, 60, "yingjun"+i);
                
                // get data
                value = jedisCluster.get(key+i);
                log.info(key+i + "=" + value);
                
                // delete data
                //jedisCluster.del(key+i);
                //value = jedisCluster.get(key+i);
                //log.info(key+i + "=" + value);
            }

            context.stop();
        } catch (Exception e) {
            log.error("==>RedisSpringTest context start error:", e);
            System.exit(0);
        } finally {
            log.info("===>System.exit");
            System.exit(0);
        }
    }
}
copy code

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324940488&siteId=291194637