首頁 > 資料庫 > Redis > Java如何使用Lettuce客戶端在Redis主從模式下執行指令

Java如何使用Lettuce客戶端在Redis主從模式下執行指令

王林
發布: 2023-05-31 21:05:39
轉載
1732 人瀏覽過

1 redis主從複製的概念

在多機環境下,一個redis服務接收寫入命令,並在自身資料和狀態發生變化時將其複製到一個或多個redis。這種模式稱為主從複製。透過指令slaveof,在Redis中可以讓一個Redis伺服器複製另一個Redis伺服器的資料和狀態。我們將主伺服器稱為master,從伺服器稱為slave。

主從複製保證了網路異常正常時,網路斷開重的情況下複製資料。網路正常時master會透過發送指令保持對slave更新,更新包含客戶端的寫入,key的過期或被逐出等網路異常,master與slave連線斷開一段時間,slave重連上master後會嘗試部分重同步,重新取得連線斷開期間遺失的命令。當無法進行部分重同步,則會執行全量重同步。

2 為什麼需要主從複製

為了確保資料不會遺失,有時會用到持久化功能。但這樣會增加磁碟IO操作。使用主從複製技術可以取代持久化,減少IO操作,從而降低延遲並提高效能。

主從模式下,master負責處理寫,slave負責讀取。儘管主從同步可能會導致資料不一致,但它可以提高讀取操作的吞吐量。主從模式避免了redis單點風險。透過副本提高系統可用性。如果主節點掛掉,透過從節點選舉新的節點作為主節點以確保系統可用。

3 主從複製配置及原理

主從複製可以分為三個階段:初始化、同步、命令傳播。

當伺服器執行完slaveof指令後,從伺服器與主伺服器建立套接字連接,完成初始化。如果主伺服器正常,建立連線後會透過ping指令進行心跳偵測並回傳回應。當發生故障並收不到回應時,從節點將會重新嘗試與主節點進行連線。如果master設定了認證訊息,則會再檢查認證資料是否正確。如果認證失敗,則會報錯。

在初始化完成之後,當master接收到slave的資料同步指令時,需要根據情況來決定是執行全量同步還是部分同步。

在同步完成後, 主伺服器和從伺服器透過心跳偵測確認彼此的線上狀態,以進行指令傳輸。 slave同時傳送自己複製緩衝區的偏移量給master。根據這些請求,master會判斷是否需要將新產生的指令同步到slave。 slave收到同步的指令後執行,最後與master保持同步。

4 使用Lettuce在主從模式下執行指令

Jedis、Redission和Lettuce是常見的Java Redis客戶端。這裡將透過Lettuce來示範主從模式下的讀寫分離指令執行。

1

2

3

4

5

<dependency>

    <groupId>io.lettuce</groupId>

    <artifactId>lettuce-core</artifactId>

    <version>5.1.8.RELEASE</version>

</dependency>

登入後複製

下面透過

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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();

    }

}

登入後複製

補充:Redis 用戶端之Lettuce配置使用(基於Spring Boot 2.x)

##開發環境:使用Intellij IDEA Maven Spring Boot 2.x JDK 8

Spring Boot 從2.0版本開始,將預設的Redis客戶端Jedis替換問Lettuce,以下描述Lettuce的設定使用。

1.在專案的pom.xml檔案下,引入Redis在Spring Boot 下的相關Jar套件依賴

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

<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.在專案的resources目錄下,在application.yml檔案裡新增lettuce的設定參數

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#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.新增Redisson的設定參數讀取類別RedisConfig

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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.建構Spring Boot的啟動類別RedisApplication

1

2

3

4

5

6

7

8

9

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.編寫測試類別RedisTest

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

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.在Redis上查看運行結果

以上是Java如何使用Lettuce客戶端在Redis主從模式下執行指令的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板