Redis框架在項(xiàng)目中的實(shí)戰(zhàn)
一、Redis 哨兵模式(Redis Sentinel)
Redis Sentinel 是 Redis 官方提供的高可用解決方案,核心作用是監(jiān)控 Redis 主從集群、自動(dòng)完成主從切換、通知客戶端主節(jié)點(diǎn)變更,解決單機(jī) Redis 宕機(jī)后無(wú)法自動(dòng)恢復(fù)的問題。
Lettuce 是一款高性能、異步非阻塞的 Redis 客戶端,基于 Netty 框架開發(fā),也是 Spring Boot 2.x 及以上版本默認(rèn)的 Redis 客戶端客戶端(Lettuce)只需配置哨兵節(jié)點(diǎn)地址和主節(jié)點(diǎn)名稱,無(wú)需知道主從節(jié)點(diǎn)的具體地址,哨兵會(huì)自動(dòng)告知客戶端當(dāng)前的主節(jié)點(diǎn)。
二、Lettuce 和Redission 如何選擇
在實(shí)際項(xiàng)目中,Lettuce 和 Redisson 是互補(bǔ)使用的 ——Lettuce 作為底層高性能 Redis 客戶端負(fù)責(zé)基礎(chǔ)通信,Redisson 基于 Lettuce 封裝了豐富的分布式數(shù)據(jù)結(jié)構(gòu)和服務(wù)(如分布式鎖、分布式 Map),既發(fā)揮 Lettuce 的性能優(yōu)勢(shì),又利用 Redisson 簡(jiǎn)化業(yè)務(wù)開發(fā)。
- 依賴引入(pom.xml)
<!-- Spring Boot 整合 Redis(默認(rèn)內(nèi)置 Lettuce) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Redisson 核心依賴(適配 Spring Boot) -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.0</version> <!-- 選穩(wěn)定版本 -->
</dependency>
- 配置文件:
redis.lettuce.client.enable=true # 啟用Lettuce客戶端 # 連接池配置(核心) redis.lettuce.client.pool.minIdle=6 # 最小空閑連接(?;睿? redis.lettuce.client.pool.maxIdle=21 # 最大空閑連接 redis.lettuce.client.pool.maxTotal=100 # 最大連接數(shù) redis.lettuce.client.pool.maxWaitMillis=4000 # 最大等待時(shí)間 redis.lettuce.client.sentinel.mastername=master # 監(jiān)控的主節(jié)點(diǎn)名稱 redis.lettuce.client.sentinel.password=*** redis.lettuce.client.sentinel.database=0 redis.lettuce.client.sentinel.nodeInfo[0]=10.193.114.0:26379 # 哨兵節(jié)點(diǎn)列表 redis.lettuce.client.sentinel.nodeInfo[0]=10.193.114.2:26379 # 哨兵節(jié)點(diǎn)列表 redis.lettuce.client.sentinel.nodeInfo[0]=10.193.114.3:26379 # 哨兵節(jié)點(diǎn)列表
三、代碼示例
場(chǎng)景 1:用 Lettuce 做基礎(chǔ)緩存讀寫(Spring RedisTemplate)
Spring Data Redis 封裝了 Lettuce,提供 RedisTemplate 簡(jiǎn)化操作,這是項(xiàng)目中最基礎(chǔ)的用法:
@Component
public class CacheService {
// 注入 Spring 封裝的 RedisTemplate(底層是 Lettuce)
@Resource
private RedisTemplate<String, Object> redisTemplate;
// 存儲(chǔ)合約基礎(chǔ)信息(String 類型)
public void setTestInfo(String testKey, Object testInfo) {
// 底層通過 Lettuce 發(fā)送 SET 命令到 Redis 哨兵集群
redisTemplate.opsForValue().set(
testKey,
testInfo,
1, // 過期時(shí)間 1 小時(shí)
TimeUnit.HOURS
);
}
public Object getTestInfo(String testKey) {
// 底層通過 Lettuce 發(fā)送 GET 命令
return redisTemplate.opsForValue().get(testKey);
}
// 異步操作(Lettuce 核心優(yōu)勢(shì),高并發(fā)場(chǎng)景用)
public void setTestInfoAsync(String testKey, Object testInfo) {
// 異步設(shè)置,不阻塞主線程(高并發(fā)場(chǎng)景推薦)
redisTemplate.opsForValue().setAsync(testKey, testInfo);
}
}
場(chǎng)景 2:用 Redisson 操作分布式 Map(對(duì)應(yīng)你的 INFO:TEST_KEY)
Redisson 封裝的 RMap 是分布式 Map,比 Lettuce 的 Hash 更易用,支持自動(dòng)序列化 / 反序列化:
@Component
public class TestMapService {
// 注入 RedissonClient(底層復(fù)用 Lettuce 連接)
@Resource
private RedissonClient redissonClient;
// 批量存儲(chǔ)合約信息到分布式 Map
public void batchSaveTestInfo(List<TestInfoPO> testList) {
// 獲取 Redis 中的分布式 Map(INFO:TEST_KEY)
RMap<String, TestInfoPO> testMap =
redissonClient.getMap("INFO:TEST_KEY");
// 批量存入:INFO:TEST_KEY
testList.forEach(d -> {
String key = ...
testMap.put(key, d); // 原子操作,線程安全
});
}
// 獲取單個(gè)test信息
public TestInfoPO getTestInfo(String testId) {
RMap<String, TestInfoPO> testMap = redissonClient.getMap("INFO:TEST_KEY");
String key = ...;
return testMap.get(key);
}
}
場(chǎng)景 3:用 Redisson 實(shí)現(xiàn)分布式鎖(防并發(fā)修改)
@Component
public class UpdateService {
@Resource
private RedissonClient redissonClient;
// 修改(加分布式鎖)
public void updateTestInfo(String testtId, TestInfoPO newInfo) {
// 1. 定義鎖的唯一標(biāo)識(shí)
String lockKey = "lock:test:update:" + testId;
RLock lock = redissonClient.getLock(lockKey);
try {
// 2. 獲取鎖:最多等5秒,持有鎖10秒(自動(dòng)釋放,防止死鎖)
boolean locked = lock.tryLock(5, 10, TimeUnit.SECONDS);
if (!locked) {
throw new RuntimeException("正在修改中,請(qǐng)稍后重試");
}
// 3. 執(zhí)行業(yè)務(wù)邏輯
// ... 你的更新數(shù)據(jù)庫(kù)/緩存邏輯 ...
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("獲取鎖失敗", e);
} finally {
// 4. 釋放鎖(必須在 finally 中,防止鎖泄露)
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
四、項(xiàng)目中的最佳實(shí)踐
- 分工明確:簡(jiǎn)單的緩存讀寫(String/Hash)用 RedisTemplate(底層 Lettuce);
- 分布式鎖、分布式集合、延遲隊(duì)列等復(fù)雜場(chǎng)景用 Redisson;
- 復(fù)用連接池:讓 Redisson 復(fù)用 Lettuce 的連接池配置,避免重復(fù)創(chuàng)建連接;
- 異步優(yōu)先:高并發(fā)場(chǎng)景(如期貨行情緩存)用 Lettuce 的異步 API(setAsync/getAsync),提升吞吐量;
- 鎖的規(guī)范:分布式鎖必須設(shè)置超時(shí)時(shí)間,且在 finally 中釋放,防止死鎖;
- 序列化配置:統(tǒng)一配置 RedisTemplate 的序列化方式(如 Jackson2JsonRedisSerializer),避免亂碼:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 設(shè)置 JSON 序列化器
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
template.setValueSerializer(serializer);
template.setKeySerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
到此這篇關(guān)于Redis框架在項(xiàng)目中的實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)Redis框架項(xiàng)目應(yīng)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis核心知識(shí)點(diǎn)詳解及解析(附?Java?項(xiàng)目實(shí)踐案例)
Redis是一款高性能的內(nèi)存鍵值數(shù)據(jù)庫(kù),支持多種數(shù)據(jù)結(jié)構(gòu)和持久化機(jī)制,下面這篇文章主要介紹了Redis核心知識(shí)點(diǎn)及解析的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2026-06-06
windows環(huán)境下Redis+Spring緩存實(shí)例講解
這篇文章主要為大家詳細(xì)介紹了windows環(huán)境下Redis+Spring緩存實(shí)例教程,感興趣的小伙伴們可以參考一下2016-04-04
RedisTemplate的使用與注意事項(xiàng)小結(jié)
本文詳細(xì)介紹了RedisTemplate的用途和使用方法,RedisTemplate是Spring提供的一個(gè)工具類,用于操作Redis數(shù)據(jù)庫(kù),其API提供了豐富的方法來(lái)實(shí)現(xiàn)對(duì)Redis各種操作,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以來(lái)了解一下2024-10-10

