Home  >  Article  >  Database  >  How Java uses Lettuce client to execute commands in Redis master-slave mode

How Java uses Lettuce client to execute commands in Redis master-slave mode

王林
王林forward
2023-05-31 21:05:391333browse

1 The concept of redis master-slave replication

In a multi-machine environment, a redis service receives write commands and copies them to one or more redis when its own data and status change. This mode is called master-slave replication. Through the command slaveof, one Redis server can copy the data and status of another Redis server in Redis. We call the main server master and the slave server slave.

Master-slave replication ensures that data will be replicated when the network is abnormal and the network is disconnected. When the network is normal, the master will keep updating the slave by sending commands. The updates include client writes, key expiration or eviction and other network abnormalities. The master is disconnected from the slave for a period of time. The slave will try to partially reconnect after reconnecting to the master. Synchronize, reacquire commands lost during disconnection. When partial resynchronization cannot be performed, full resynchronization will be performed.

2 Why master-slave replication is needed

In order to ensure that data is not lost, the persistence function is sometimes used. But this will increase disk IO operations. Using master-slave replication technology can replace persistence and reduce IO operations, thereby reducing latency and improving performance.

In the master-slave mode, the master is responsible for writing and the slave is responsible for reading. Although master-slave synchronization may cause data inconsistency, it can improve the throughput of read operations. The master-slave model avoids redis single point risk. Improve system availability through replicas. If the master node fails, the slave node elects a new node as the master node to ensure system availability.

3 Master-slave replication configuration and principle

Master-slave replication can be divided into three stages: initialization, synchronization, and command propagation.

After the server executes the slaveof command, the slave server establishes a socket connection with the master server and completes the initialization. If the main server is normal, after establishing the connection, it will perform heartbeat detection through the ping command and return a response. When a failure occurs and no response is received, the slave node will retry to connect to the master node. If the master sets authentication information, it will then check whether the authentication data is correct. If authentication fails, an error will be reported.

After the initialization is completed, when the master receives the data synchronization instruction from the slave, it needs to determine whether to perform full synchronization or partial synchronization according to the situation.

After the synchronization is completed, the master server and the slave server confirm each other's online status through heartbeat detection for command transmission. The slave also sends the offset of its own copy buffer to the master. Based on these requests, the master will determine whether the newly generated commands need to be synchronized to the slave. The slave executes the synchronization command after receiving it, and finally synchronizes with the master.

4 Use Lettuce to execute commands in master-slave mode

Jedis, Redission and Lettuce are common Java Redis clients. Lettuce will be used to demonstrate the read-write separation command execution in master-slave mode.

        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
            <version>5.1.8.RELEASE</version>
        </dependency>

The following is supplemented by

package redis;
import io.lettuce.core.ReadFrom;
import io.lettuce.core.RedisClient;
import io.lettuce.core.RedisURI;
import io.lettuce.core.api.sync.RedisCommands;
import io.lettuce.core.codec.Utf8StringCodec;
import io.lettuce.core.masterslave.MasterSlave;
import io.lettuce.core.masterslave.StatefulRedisMasterSlaveConnection;
import org.assertj.core.util.Lists;
 class MainLettuce {
    public static void main(String[] args) {
        List<RedisURI> nodes = Lists.newArrayList(
                RedisURI.create("redis://localhost:7000"),
                RedisURI.create("redis://localhost:7001")
        );
        RedisClient redisClient = RedisClient.create();
        StatefulRedisMasterSlaveConnection<String, String> connection = MasterSlave.connect(
                redisClient,
                new Utf8StringCodec(), nodes);
        connection.setReadFrom(ReadFrom.SLAVE);
        RedisCommands<String, String> redisCommand = connection.sync();
        redisCommand.set("master","master write test2");
        String value = redisCommand.get("master");
        System.out.println(value);
        connection.close();
        redisClient.shutdown();
    }
}

: Lettuce configuration and use of Redis client (based on Spring Boot 2.x)

Development environment: using Intellij IDEA Maven Spring Boot 2.x JDK 8

Spring Boot Starting from version 2.0, the default Redis client Jedis will be replaced by Lettuce. The configuration and use of Lettuce is described below.

1. In the pom.xml file of the project, introduce the relevant Jar package dependencies of Redis under Spring Boot

    <properties>
        <redisson.version>3.8.2</redisson.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <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>
    </dependencies>

2. In the resources directory of the project, in the application.yml file Add lettuce configuration parameters

#Redis配置
spring:
  redis:
    database: 6  #Redis索引0~15,默认为0
    host: 127.0.0.1
    port: 6379
    password:  #密码(默认为空)
    lettuce: # 这里标明使用lettuce配置
      pool:
        max-active: 8   #连接池最大连接数(使用负值表示没有限制)
        max-wait: -1ms  #连接池最大阻塞等待时间(使用负值表示没有限制)
        max-idle: 5     #连接池中的最大空闲连接
        min-idle: 0     #连接池中的最小空闲连接
    timeout: 10000ms    #连接超时时间(毫秒)

3. Add Redisson configuration parameter reading class RedisConfig

package com.dbfor.redis.config;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
    /**
     * RedisTemplate配置
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory connectionFactory) {
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());//key序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());//value序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

4. Build Spring Boot startup class RedisApplication

package com.dbfor.redis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RedisApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisApplication.class);
    }
}

5. Write tests Class RedisTest

package com.dbfor.redis;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.test.context.junit4.SpringRunner;
@SpringBootTest
@RunWith(SpringRunner.class)
@Component
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    public void set() {
        redisTemplate.opsForValue().set("test:set1", "testValue1");
        redisTemplate.opsForSet().add("test:set2", "asdf");
        redisTemplate.opsForHash().put("hash2", "name1", "lms1");
        redisTemplate.opsForHash().put("hash2", "name2", "lms2");
        redisTemplate.opsForHash().put("hash2", "name3", "lms3");
        System.out.println(redisTemplate.opsForValue().get("test:set"));
        System.out.println(redisTemplate.opsForHash().get("hash2", "name1"));
    }
}

6. View the running results on Redis

The above is the detailed content of How Java uses Lettuce client to execute commands in Redis master-slave mode. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete