Java使用Lettuce客戶端在Redis在主從復制模式下命令執(zhí)行的操作
1 redis主從復制的概念
多機環(huán)境下,一個redis服務接收寫命令,當自身數(shù)據(jù)與狀態(tài)發(fā)生變化,將其復制到一個或多個redis。這種模式稱為主從復制。在redis中通過命令salveof命令讓執(zhí)行該命令的redis復制另一個redis數(shù)據(jù)與狀態(tài)。我們將主服務器稱為master,從服務器稱為slave。
主從復制保證了網(wǎng)絡異常正常時,網(wǎng)絡斷開重的情況下將數(shù)據(jù)復制。網(wǎng)絡正常時master會通過發(fā)送命令保持對slave更新,更新包括客戶端的寫入,key的過期或被逐出等網(wǎng)絡異常,master與slave連接斷開一段時間,slave重連上master后會嘗試部分重同步,重新獲取連接斷開期間丟失的命令。當無法進行部分重同步,則會執(zhí)行全量重同步。
2 為什么需要主從復制
為了保證數(shù)據(jù)不丟失,有時會用到持久化功能。但這樣會增加磁盤IO操作。通過使用主從復制,可以替代持久化并減少IO操作,降低延遲提高性能。
主從模式下,master負責處理寫,slave負責讀。雖然主從同步會導致在數(shù)據(jù)存在不一致窗口,但可以增加讀操作的吞吐量。主從模式避免了redis單點風險。通過副本提高系統(tǒng)可用性。當master掛掉,從slave中選舉新的機器作為master保證系統(tǒng)可用。
3 主從復制配置及原理
主從復制可以分為三個階段:初始化、同步、命令傳播。
初始化:從服務器執(zhí)行完 slaveof 命令后,slave與master建立socket連接。連接建立完畢后通過ping進行心跳檢測,若master正常,則返回響應。如果出現(xiàn)故障收不到響應,那么slave會重新嘗試連接master。如果master設置了認證信息,則會再檢查認證數(shù)據(jù)是否正確。如果認證失敗,則會報錯。
同步:當初始化完畢,master收到slave的數(shù)據(jù)同步命令后,需要判斷是否執(zhí)行全量同步還是部分同步。
命令傳播:同步完成后,master與slave通過心跳檢測判斷對方是否在線。slave同時向master發(fā)送自己復制緩沖區(qū)的偏移量。master根據(jù)這些請求,判斷是否向slave同步新產(chǎn)生的命令。slave收到同步的命令后執(zhí)行,最終與master保持同步。
4 使用Lettuce在主從模式下執(zhí)行命令
常用的Java Redis客戶端有Jedis、Redission、Lettuce。這里將通過Lettuce來演示主從模式下的讀寫分離命令執(zhí)行。
<dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>5.1.8.RELEASE</version> </dependency>
下面通過
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)
開發(fā)環(huán)境:使用Intellij IDEA + Maven + Spring Boot 2.x + JDK 8
Spring Boot 從 2.0版本開始,將默認的Redis客戶端Jedis替換問Lettuce,下面描述Lettuce的配置使用。
1.在項目的pom.xml文件下,引入Redis在Spring Boot 下的相關Jar包依賴
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的配置參數(shù)
#Redis配置 spring: redis: database: 6 #Redis索引0~15,默認為0 host: 127.0.0.1 port: 6379 password: #密碼(默認為空) lettuce: # 這里標明使用lettuce配置 pool: max-active: 8 #連接池最大連接數(shù)(使用負值表示沒有限制) max-wait: -1ms #連接池最大阻塞等待時間(使用負值表示沒有限制) max-idle: 5 #連接池中的最大空閑連接 min-idle: 0 #連接池中的最小空閑連接 timeout: 10000ms #連接超時時間(毫秒)
3.添加Redisson的配置參數(shù)讀取類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.構建Spring Boot的啟動類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.編寫測試類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("hash1", "name1", "lms1"); redisTemplate.opsForHash().put("hash1", "name2", "lms2"); redisTemplate.opsForHash().put("hash1", "name3", "lms3"); System.out.println(redisTemplate.opsForValue().get("test:set")); System.out.println(redisTemplate.opsForHash().get("hash1", "name1")); } }
6.在Redis上查看運行結果
從上圖可以看到,Lettuce配置操作數(shù)據(jù)庫成功!
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關文章
JAVA實戰(zhàn)練習之圖書管理系統(tǒng)實現(xiàn)流程
隨著網(wǎng)絡技術的高速發(fā)展,計算機應用的普及,利用計算機對圖書館的日常工作進行管理勢在必行,本篇文章手把手帶你用Java實現(xiàn)一個圖書管理系統(tǒng),大家可以在過程中查缺補漏,提升水平2021-10-10Java數(shù)據(jù)結構篇之實現(xiàn)二叉搜索樹的核心方法
二叉搜索樹是一種常用的數(shù)據(jù)結構,它是一棵二叉樹,且每個節(jié)點的值都大于其左子樹中任何節(jié)點的值,而小于其右子樹中任何節(jié)點的值,這篇文章主要給大家介紹了關于Java數(shù)據(jù)結構篇之實現(xiàn)二叉搜索樹的核心方法,需要的朋友可以參考下2023-12-12java獲取系統(tǒng)路徑字體、得到某個目錄下的所有文件名、獲取當前路徑
這篇文章主要介紹了java獲取系統(tǒng)路徑字體、得到某個目錄下的所有文件名、獲取當前路徑,需要的朋友可以參考下2014-04-04java中的FileReader和FileWriter讀寫流
這篇文章主要介紹了java中的FileReader和FileWriter讀寫流,在java中對數(shù)據(jù)輸入輸出的操作陳作為流我們對不同的文件進行操作,或者對操作文件進行輸入和輸出時所用的流都是不同的,因此在java.io的包下存在很多流的類或者接口提供給我們對應的操作,需要的朋友可以參考下2023-10-10使用httpclient實現(xiàn)免費的google翻譯api
這篇文章主要介紹了使用httpclient實現(xiàn)免費的google翻譯api的方法,大家參考使用吧2014-01-01springboot 接收List 入?yún)⒌膸追N方法
本文主要介紹了springboot 接收List 入?yún)⒌膸追N方法,本文主要介紹了7種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-03-03JAVA基于Redis實現(xiàn)計數(shù)器限流的使用示例
計數(shù)器法是限流算法里最簡單也是最容易實現(xiàn)的一種算法,本文主要介紹了JAVA基于Redis實現(xiàn)計數(shù)器限流的使用示例,具有一定的參考價值,感興趣的可以了解一下2023-09-09