Spring Boot 整合 Redis詳解從基礎(chǔ)操作到實戰(zhàn)應(yīng)用
在現(xiàn)代應(yīng)用中,緩存 幾乎是性能優(yōu)化的必備手段。Redis 作為高性能的內(nèi)存數(shù)據(jù)庫,不僅支持鍵值對緩存,還支持豐富的數(shù)據(jù)結(jié)構(gòu)(如 List、Set、Hash、ZSet 等),被廣泛用于緩存、分布式鎖、消息隊列、計數(shù)器等場景。
Spring Boot 提供了開箱即用的 Redis 集成支持,開發(fā)者可以非常方便地在項目中使用 Redis。
一、為什么選擇 Redis?
在現(xiàn)代應(yīng)用開發(fā)中,??Redis?? 已成為高性能緩存和分布式數(shù)據(jù)存儲的首選方案。作為內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲系統(tǒng),Redis 提供:
- ??亞毫秒級響應(yīng)速度??(10萬+ QPS)
- ??豐富的數(shù)據(jù)結(jié)構(gòu)支持??
- ??持久化選項??(RDB/AOF)
- ??高可用架構(gòu)??(主從復(fù)制、哨兵、集群)
Spring Boot 通過 ??Spring Data Redis?? 模塊提供了與 Redis 的無縫集成,極大簡化了開發(fā)流程。
二、Spring Boot 整合 Redis 步驟
1. 添加依賴
在 pom.xml 中添加:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <!-- 推薦使用 Jedis 客戶端 -->
</dependency>2. 配置 Redis 連接
在 application.yml 中配置:
spring:
redis:
host: localhost
port: 6379
password: your-password # 如果有密碼
database: 0 # 默認(rèn)數(shù)據(jù)庫索引
jedis:
pool:
max-active: 8 # 連接池最大連接數(shù)
max-idle: 8 # 連接池最大空閑連接
min-idle: 2 # 連接池最小空閑連接3. 配置 RedisTemplate
創(chuàng)建配置類:
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用Jackson序列化器
Jackson2JsonRedisSerializer<Object> serializer =
new Jackson2JsonRedisSerializer<>(Object.class);
// 解決查詢緩存轉(zhuǎn)換異常的問題
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.activateDefaultTyping(
om.getPolymorphicTypeValidator(),
ObjectMapper.DefaultTyping.NON_FINAL
);
serializer.setObjectMapper(om);
// 設(shè)置序列化
template.setKeySerializer(new StringRedisSerializer());
template.setValueSerializer(serializer);
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}三、Redis 五大核心數(shù)據(jù)類型
1. String(字符串)
??特點??:最基本的數(shù)據(jù)類型,最大能存儲 512MB
??常用場景??:
- 緩存簡單值
- 計數(shù)器
- 分布式鎖
??操作示例??:
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 設(shè)置值
redisTemplate.opsForValue().set("user:1001:name", "Alice");
// 獲取值
String name = (String) redisTemplate.opsForValue().get("user:1001:name");
// 自增計數(shù)器
redisTemplate.opsForValue().increment("article:1001:views");
// 設(shè)置帶過期時間(30分鐘)
redisTemplate.opsForValue().set("temp:session", "data", 30, TimeUnit.MINUTES);2. Hash(哈希)
??特點??:鍵值對集合,適合存儲對象
??常用場景??:
- 存儲用戶資料
- 商品屬性
- 配置信息
??操作示例??:
// 存儲用戶對象
Map<String, String> userMap = new HashMap<>();
userMap.put("name", "Bob");
userMap.put("age", "30");
userMap.put("email", "bob@example.com");
redisTemplate.opsForHash().putAll("user:1002", userMap);
// 獲取單個字段
String email = (String) redisTemplate.opsForHash().get("user:1002", "email");
// 更新單個字段
redisTemplate.opsForHash().put("user:1002", "age", "31");
// 獲取所有字段
Map<Object, Object> userData = redisTemplate.opsForHash().entries("user:1002");3. List(列表)
??特點??:有序、可重復(fù)的字符串集合
??常用場景??:
- 消息隊列
- 最新消息排行
- 記錄日志
??操作示例??:
// 從左側(cè)插入
redisTemplate.opsForList().leftPush("news:latest", "Article 1");
redisTemplate.opsForList().leftPush("news:latest", "Article 2");
// 從右側(cè)插入
redisTemplate.opsForList().rightPush("news:latest", "Article 3");
// 獲取范圍數(shù)據(jù)(0到10)
List<Object> latestNews = redisTemplate.opsForList().range("news:latest", 0, 10);
// 列表長度
Long size = redisTemplate.opsForList().size("news:latest");
// 模擬隊列消費
Object article = redisTemplate.opsForList().rightPop("news:queue", 10, TimeUnit.SECONDS);4. Set(集合)
??特點??:無序、不可重復(fù)的元素集合
??常用場景??:
- 標(biāo)簽系統(tǒng)
- 共同好友
- 唯一訪客統(tǒng)計
??操作示例??:
// 添加元素
redisTemplate.opsForSet().add("article:1001:tags", "tech", "java", "spring");
// 獲取所有元素
Set<Object> tags = redisTemplate.opsForSet().members("article:1001:tags");
// 檢查元素是否存在
boolean containsJava = redisTemplate.opsForSet().isMember("article:1001:tags", "java");
// 集合運算(交集)
Set<Object> commonTags = redisTemplate.opsForSet().intersect(
"article:1001:tags",
"article:1002:tags"
);
// 唯一訪客統(tǒng)計
redisTemplate.opsForSet().add("article:1001:visitors", "192.168.1.1");
Long visitors = redisTemplate.opsForSet().size("article:1001:visitors");5. Sorted Set(有序集合)
??特點??:帶分?jǐn)?shù)排序的Set
??常用場景??:
- 排行榜
- 帶權(quán)重的隊列
- 范圍查詢
??操作示例??:
// 添加帶分?jǐn)?shù)的元素
redisTemplate.opsForZSet().add("leaderboard", "player1", 2500);
redisTemplate.opsForZSet().add("leaderboard", "player2", 1800);
redisTemplate.opsForZSet().add("leaderboard", "player3", 3000);
// 獲取前3名玩家
Set<ZSetOperations.TypedTuple<Object>> topPlayers =
redisTemplate.opsForZSet().reverseRangeWithScores("leaderboard", 0, 2);
// 更新分?jǐn)?shù)
redisTemplate.opsForZSet().incrementScore("leaderboard", "player1", 100);
// 獲取玩家排名(從高到低)
Long rank = redisTemplate.opsForZSet().reverseRank("leaderboard", "player2");
// 獲取分?jǐn)?shù)段玩家(2000-3000分)
Set<Object> players = redisTemplate.opsForZSet().rangeByScore("leaderboard", 2000, 3000);四、高級功能實戰(zhàn)
1. 分布式鎖實現(xiàn)
public boolean tryLock(String lockKey, String requestId, long expireTime) {
return Boolean.TRUE.equals(redisTemplate.execute((RedisCallback<Boolean>) connection -> {
// 使用SET命令的NX(不存在才設(shè)置)和PX(毫秒過期)選項
String result = connection.set(
lockKey.getBytes(),
requestId.getBytes(),
Expiration.milliseconds(expireTime),
RedisStringCommands.SetOption.SET_IF_ABSENT
);
return "OK".equals(result);
}));
}
public boolean releaseLock(String lockKey, String requestId) {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) " +
"else return 0 end";
return Boolean.TRUE.equals(redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList(lockKey),
requestId
));
}2. 緩存注解使用
@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
// 數(shù)據(jù)庫查詢邏輯
return userRepository.findById(id).orElse(null);
}
@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
// 更新數(shù)據(jù)庫
return userRepository.save(user);
}
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
userRepository.deleteById(id);
}3. 發(fā)布/訂閱模式
// 配置消息監(jiān)聽容器
@Bean
public RedisMessageListenerContainer container(
RedisConnectionFactory factory,
MessageListenerAdapter listenerAdapter) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
container.addMessageListener(listenerAdapter, new PatternTopic("news.*"));
return container;
}
// 消息處理器
@Component
public class RedisMessageListener {
@Autowired
private SimpMessagingTemplate messagingTemplate;
public void handleMessage(String message, String channel) {
// 處理消息并轉(zhuǎn)發(fā)到WebSocket
messagingTemplate.convertAndSend("/topic/" + channel, message);
}
}
// 發(fā)布消息
public void publish(String channel, String message) {
redisTemplate.convertAndSend(channel, message);
}五、最佳實踐與注意事項
- ??鍵命名規(guī)范??
- 使用冒號分隔層級:
業(yè)務(wù):類型:ID - 示例:
user:session:1001,product:info:2005
- 使用冒號分隔層級:
- ??內(nèi)存優(yōu)化??
- 控制單個Value大小(<100KB)
- 使用Hash壓縮存儲小對象
- 設(shè)置合理的TTL
- ??性能調(diào)優(yōu)??
spring:
redis:
jedis:
pool:
max-active: 50 # 根據(jù)負(fù)載調(diào)整
max-wait: 200ms- ??高可用方案??
- 開發(fā)環(huán)境:單節(jié)點
- 生產(chǎn)環(huán)境:Redis Sentinel 或 Cluster
- ??監(jiān)控指標(biāo)
// 獲取Redis指標(biāo)
@Autowired
private RedisConnectionFactory factory;
public void monitor() {
RedisConnection connection = factory.getConnection();
Properties info = connection.info();
System.out.println("內(nèi)存使用: " + info.getProperty("used_memory_human"));
System.out.println("連接數(shù): " + info.getProperty("connected_clients"));
}六、總結(jié)
Spring Boot 與 Redis 的結(jié)合為開發(fā)者提供了強大的數(shù)據(jù)緩存和處理能力。通過掌握:
- ??五大核心數(shù)據(jù)類型??的適用場景和操作方法
- ??RedisTemplate?? 的高級用法
- ??分布式鎖??、??發(fā)布訂閱??等高級功能
- ??生產(chǎn)環(huán)境最佳實踐
到此這篇關(guān)于Spring Boot 整合 Redis詳解從基礎(chǔ)操作到實戰(zhàn)應(yīng)用的文章就介紹到這了,更多相關(guān)Spring Boot 整合 Redis內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot整合Redis實現(xiàn)序列化的7種策略詳解
- SpringBoot + Mybatis Plus 整合 Redis的詳細(xì)步驟
- SpringBoot整合Redis的哨兵模式的實現(xiàn)
- SpringBoot整合Redis并且用Redis實現(xiàn)限流的方法 附Redis解壓包
- SpringBoot整合Redisson的兩種方式
- springBoot整合redis做緩存具體操作步驟
- springboot整合redis配置詳細(xì)示例代碼
- SpringBoot整合SpringSecurity和JWT和Redis實現(xiàn)統(tǒng)一鑒權(quán)認(rèn)證
相關(guān)文章
MyBatisPlus+Lombok實現(xiàn)分頁功能的方法詳解
Lombok是一個Java類庫,提供了一組注解,簡化POJO實體類開發(fā)。本文將為大家介紹一下Lombok的使用以及如何利用MyBatisPlus+Lombok實現(xiàn)分頁功能,感興趣的可以動手嘗試一下2022-07-07
idea與eclipse項目相互導(dǎo)入的過程(圖文教程)
這篇文章主要介紹了idea與eclipse項目相互導(dǎo)入的過程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
Java連接Redis報錯:NoSuchElementException: Unable to&nb
這篇文章主要介紹了Java連接Redis報錯:NoSuchElementException: Unable to validate object的解決辦法,文中通過圖文講解的非常詳細(xì),具有一定的參考價值,需要的朋友可以參考下2024-12-12

