Redis sentinel high availability architecture

Posted by Jack Sparrow on Wed, 01 Dec 2021 22:19:28 +0100

Sentinel sentinel is a special redis service. It does not provide read-write services. It is mainly used to monitor redis instance nodes.
Under the sentinel architecture, the client finds the redis master node from the sentinel for the first time, and then directly accesses the redis master node. It does not access the redis master node through the sentinel agent every time. When the redis master node changes, the sentinel will perceive it for the first time and notify the client of the new redis master node (the client side of redis generally implements the subscription function to subscribe to node change messages published by sentinel)
Steps to build redis sentry architecture:

1.Make a copy sentinel.conf file
cp sentinel.conf sentinel‐26379.conf

2.Modify the relevant configuration to the following values:
port 26379
daemonize yes
logfile "26379.log"
dir "/usr/local/redis‐5.0.3/data"
# sentinel monitor <master‐redis‐name> <master‐redis‐ip> <master‐redis‐port> <quorum>
# quorum is a number that indicates how many sentinels consider a master to be invalid (the value is generally: total sentinels / 2 +), and the master is really invalid
sentinel monitor mymaster 192.168.0.60 6379 2 # Take the name mymaster casually and use it when accessing the client

3.start-up sentinel Sentinel instance
src/redis‐sentinel sentinel‐26379.conf

4.see sentinel of info information
src/redis‐cli ‐p 26379
127.0.0.1:26379>info
 Can see Sentinel of info I've identified it in the redis Master-slave

5.You can configure two more sentinel,Ports 26380 and 26381. Note that the corresponding numbers in the above configuration file should be modified

Download address of relevant configuration files: Click here to download
After the sentinel cluster is started, the metadata information of sentinel cluster will be written into all sentinel configuration files (appended at the bottom of the file). Let's check the following configuration file sentinel-26379.conf, as shown below:

sentinel known‐replica mymaster 192.168.159.140 6380 #Slave node information representing the master node
sentinel known‐replica mymaster 192.168.159.140 6381 #Slave node information representing the master node
sentinel known‐sentinel mymaster 192.168.159.140 26380 52d0a5d70c1f90475b4fc03b6ce7c3c569 35760f #Represents other sentinel nodes perceived
sentinel known‐sentinel mymaster 192.168.159.140 26381 e9f530d3882f8043f76ebb8e1686438ba8 bd5ca6 #Represents other sentinel nodes perceived

If the redis master node hangs, the sentinel cluster will re elect a new redis master node and modify the cluster metadata information of all sentinel node configuration files. For example, if the redis of 6379 hangs, assuming that the elected new master node is 6380, the cluster metadata information in the sentinel file will become as follows:

sentinel known‐replica mymaster 192.168.159.140 6379 #Slave node information representing the master node
sentinel known‐replica mymaster 192.168.159.140 6381 #Slave node information representing the master node
sentinel known‐sentinel mymaster 192.168.159.140 26380 52d0a5d70c1f90475b4fc03b6ce7c3c569 35760f #Represents other sentinel nodes perceived
sentinel known‐sentinel mymaster 192.168.159.140 26381 e9f530d3882f8043f76ebb8e1686438ba8 bd5ca6 #Represents other sentinel nodes perceived

At the same time, the port 6379 corresponding to the mymaster previously configured in the sentinel file will be modified to 6380

sentinel monitor mymaster 192.168.159.140 6380 2

When the redis instance of 6379 is started again, the sentinel cluster can add the redis node of port 6379 to the cluster as a slave node according to the cluster metadata information.
Jedis connection code of sentry:

public class JedisSentinelTest {
    public static void main(String[] args) throws IOException {
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(20);
        config.setMaxIdle(10);
        config.setMinIdle(5);

        String masterName = "mymaster";
        Set<String> sentinels = new HashSet<>();
        sentinels.add(new HostAndPort("192.168.159.140",26379).toString());
        sentinels.add(new HostAndPort("192.168.159.140",26380).toString());
        sentinels.add(new HostAndPort("192.168.159.140",26381).toString());

        //JedisSentinelPool is similar to JedisPool in essence. It is a connection pool established with the redis master node
        //JedisSentinelPool does not refer to the connection pool established with sentinel, but finds and establishes a connection with the redis master node through sentinel
        JedisSentinelPool jedisSentinelPool =
                new JedisSentinelPool(masterName, sentinels, config, 3000, null);
        Jedis jedis = null;
        try {
            jedis = jedisSentinelPool.getResource();
            System.out.println(jedis.set("sentinel", "tom"));
            System.out.println(jedis.get("sentinel"));
        } catch (Exception e){
            e.printStackTrace();
        }finally {
            // Note: This is not to close the connection. In JedisPool mode, Jedis will be returned to the resource pool.
            jedis.close();
        }
    }
}

For the Spring Boot integration Redis connection code of sentinel, see the example project: Redis sentinel cluster
Introduce related dependencies

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring‐boot‐starter‐data‐redis</artifactId>
</dependency>

<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons‐pool2</artifactId>
</dependency>

springboot project core configuration:

server:
	port: 8080

 spring:
 	redis:
 	database: 0
 	timeout: 3000
 	sentinel: #Sentinel mode
 	master: mymaster #Cluster name of the primary server
 		nodes: 192.168.159.140:26379,192.168.159.140:26380,192.168.159.140:26381
 		lettuce:
 		pool:
 		max‐idle: 50
 		min‐idle: 10
 		max‐active: 100
 		max‐wait: 1000

Access code:

 @RestController
 public class IndexController {
 	private static final Logger logger = LoggerFactory.getLogger(IndexController.class);
 	@Autowired
 	private StringRedisTemplate stringRedisTemplate;
	
	/**
	* Test whether the client can dynamically perceive the new master node after the sentinel is hung
	* After the new master is elected, the Sentry will publish the message. In fact, the client implements a message listening mechanism,
	* When the sentinel publishes the news of the new master, the client will immediately perceive the information of the new master, so as to dynamically switch the accessed master IP
	*/
	@RequestMapping("/test_sentinel")
	public void testSentinel() throws InterruptedException {
		int i = 1;
		while (true){
			try{
				stringRedisTemplate.opsForValue().set("tom"+i, i+"");
				System.out.println("set up key: "+ "tom" + i);
				i++;
				Thread.sleep(1000);
			}catch(Exception e){
				logger.error("Error:", e);
			}
		}
 	}
 }

Detailed explanation of StringRedisTemplate and RedisTemplate
spring encapsulates the RedisTemplate object to perform various operations on redis. It supports all redis native APIs. Several common interface methods are provided in RedisTemplate:

private ValueOperations<K, V> valueOps;
private HashOperations<K, V> hashOps;
private ListOperations<K, V> listOps;
private SetOperations<K, V> setOps;
private ZSetOperations<K, V> zSetOps;

RedisTemplate defines operations on five data structures

redisTemplate.opsForValue();//Operation string
redisTemplate.opsForHash();//Operation hash
redisTemplate.opsForList();//Operation list
redisTemplate.opsForSet();//Operation set
redisTemplate.opsForZSet();//Operation order set

StringRedisTemplate inherits from RedisTemplate and also owns the above operations.
By default, StringRedisTemplate adopts the serialization strategy of String, and the saved key s and value s are serialized and saved by this strategy.
RedisTemplate adopts the JDK serialization policy by default, and the saved key s and value s are serialized and saved by this policy.
List of methods in RedisTemplate corresponding to Redis client command:



Topics: Redis