Redis的五種基本類型和業(yè)務(wù)場(chǎng)景和使用方式
Redis是什么?
Redis是非關(guān)系性數(shù)據(jù)庫(kù),Redis 是一個(gè)開(kāi)源的高性能鍵值數(shù)據(jù)庫(kù),主要用于數(shù)據(jù)存儲(chǔ)和緩存。
它支持多種數(shù)據(jù)結(jié)構(gòu),如字符串、哈希、列表、集合和有序集合等。
Redis的特點(diǎn)
- 豐富的數(shù)據(jù)類型:Redis不僅支持字符串類型的鍵值對(duì),還支持列表、哈希、集合和有序集合等多種數(shù)據(jù)結(jié)構(gòu),這使得Redis能夠處理更復(fù)雜的數(shù)據(jù)操作23。
- 高性能:由于數(shù)據(jù)存儲(chǔ)在內(nèi)存中,Redis能夠提供極高的讀寫速度,適用于需要高速響應(yīng)的場(chǎng)景12。
- 持久化功能:Redis支持將內(nèi)存中的數(shù)據(jù)周期性地寫入磁盤,確保數(shù)據(jù)的安全性,同時(shí)也支持將修改操作寫入追加的記錄文件,實(shí)現(xiàn)主從同步14。
- 可擴(kuò)展性:Redis提供了豐富的API和腳本功能,支持通過(guò)Lua腳本批量執(zhí)行命令,同時(shí)也支持水平擴(kuò)展,類似于分庫(kù)分表
依賴
<!-- SpringBoot Boot Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!-- Spring Boot Starter Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>配置
spring:
redis:
host: 你的ip
port: 6379redis的配置類(用于格式轉(zhuǎn)換,處理亂碼)
package com.bwie.common.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new
Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
}String(字符串)
特點(diǎn)
- 最基本的數(shù)據(jù)類型,可以包含任何類型的數(shù)據(jù),比如整數(shù)、浮點(diǎn)數(shù)或者字符串。
- 最大存儲(chǔ)容量為 512MB。
業(yè)務(wù)場(chǎng)景
- 緩存: 存儲(chǔ)臨時(shí)數(shù)據(jù),如用戶會(huì)話信息或頁(yè)面緩存。
- 計(jì)數(shù)器: 可以用來(lái)實(shí)現(xiàn)訪問(wèn)計(jì)數(shù)器、點(diǎn)贊數(shù)等自增功能。
- 配置存儲(chǔ): 存儲(chǔ)應(yīng)用程序的配置參數(shù)。
代碼使用案例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
public class StringExampleTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testString() {
// 設(shè)置字符串值
redisTemplate.opsForValue().set("myStringKey", "Hello Redis!");
// 獲取并驗(yàn)證字符串值
String value = (String) redisTemplate.opsForValue().get("myStringKey");
assertEquals("Hello Redis!", value); // 驗(yàn)證值是否正確
// 更新字符串值
redisTemplate.opsForValue().set("myStringKey", "Updated Value");
assertEquals("Updated Value", redisTemplate.opsForValue().get("myStringKey")); // 驗(yàn)證更新后的值
// 增加計(jì)數(shù)器值
redisTemplate.opsForValue().increment("myCounter", 1);
assertEquals(1, redisTemplate.opsForValue().get("myCounter")); // 驗(yàn)證計(jì)數(shù)器值
// 設(shè)置帶有過(guò)期時(shí)間的字符串
redisTemplate.opsForValue().set("tempKey", "I will expire soon", 10);
// 驗(yàn)證過(guò)期時(shí)間是否小于10秒(實(shí)際過(guò)期時(shí)間可能略小于10秒)
assertEquals(true, redisTemplate.getExpire("tempKey") < 10L);
}
}注意:
- 如果說(shuō)注入的時(shí)候泛型和配置類不一樣的話,可能會(huì)導(dǎo)致使用不了配置類的相關(guān)配置,就會(huì)采用redisTemplate原有的配置,然后存儲(chǔ)到的redis的數(shù)據(jù)就是一些亂碼。
- 一定要保證注入的泛型和配置類一樣,這樣存儲(chǔ)到redis中的數(shù)據(jù)格式就是正確的
List(列表)
特點(diǎn)
- 是一個(gè)鏈表結(jié)構(gòu),可以包含多個(gè)字符串值(元素)。
- 可以在列表的兩端進(jìn)行插入(Push)和刪除(Pop)操作,支持對(duì)列表進(jìn)行修剪(Trim)以保留指定范圍的元素。
業(yè)務(wù)場(chǎng)景
- 消息隊(duì)列:通過(guò)列表實(shí)現(xiàn)生產(chǎn)者/消費(fèi)者模式。
- 時(shí)間線:存儲(chǔ)用戶的活動(dòng)日志或社交媒體的時(shí)間線。
- 任務(wù)調(diào)度:存儲(chǔ)待處理任務(wù)的隊(duì)列。
代碼使用案例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
public class ListExampleTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testList() {
// 向列表中添加元素
redisTemplate.opsForList().leftPush("myListKey", "item1");
redisTemplate.opsForList().leftPush("myListKey", "item2");
// 獲取并驗(yàn)證列表中的所有元素
List<Object> list = redisTemplate.opsForList().range("myListKey", 0, -1);
assertEquals(true, list.contains("item2")); // 驗(yàn)證列表包含 item2
assertEquals(true, list.contains("item1")); // 驗(yàn)證列表包含 item1
// 從列表中彈出元素
Object poppedItem = redisTemplate.opsForList().rightPop("myListKey");
assertEquals("item1", poppedItem); // 驗(yàn)證彈出的元素是 item1
// 獲取列表長(zhǎng)度
Long size = redisTemplate.opsForList().size("myListKey");
assertEquals(1L, size); // 驗(yàn)證列表長(zhǎng)度為 1
// 在列表開(kāi)頭插入新元素
redisTemplate.opsForList().insert("myListKey", 0, "item0");
List<Object> updatedList = redisTemplate.opsForList().range("myListKey", 0, -1);
assertEquals(true, updatedList.contains("item0")); // 驗(yàn)證列表包含 item0
assertEquals(true, updatedList.contains("item2")); // 驗(yàn)證列表仍包含 item2
}
}注意:
- 如果說(shuō)注入的時(shí)候泛型和配置類不一樣的話,可能會(huì)導(dǎo)致使用不了配置類的相關(guān)配置,就會(huì)采用redisTemplate原有的配置,然后存儲(chǔ)到的redis的數(shù)據(jù)就是一些亂碼。
- 一定要保證注入的泛型和配置類一樣,這樣存儲(chǔ)到redis中的數(shù)據(jù)格式就是正確的
Set(集合)
特點(diǎn)
- 是字符串的無(wú)序集合,集合中的元素都是獨(dú)一無(wú)二的,即不允許重復(fù)。
- 支持集合間的交集、并集、差集等操作,可以用于處理多個(gè)用戶的共同好友、標(biāo)簽等數(shù)據(jù)。
業(yè)務(wù)場(chǎng)景
- 標(biāo)簽系統(tǒng):存儲(chǔ)用戶的興趣標(biāo)簽或文章的標(biāo)簽。
- 好友關(guān)系:存儲(chǔ)用戶的好友列表,快速查找共同好友。
- 去重:用于去重操作,例如統(tǒng)計(jì)獨(dú)立訪客數(shù)。
代碼使用案例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@SpringBootTest
public class SetExampleTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testSet() {
// 向集合中添加元素
redisTemplate.opsForSet().add("mySetKey", "member1", "member2", "member3");
// 獲取并驗(yàn)證集合中的所有成員
Set<Object> members = redisTemplate.opsForSet().members("mySetKey");
assertEquals(true, members.contains("member1")); // 驗(yàn)證集合包含 member1
assertEquals(true, members.contains("member2")); // 驗(yàn)證集合包含 member2
assertEquals(true, members.contains("member3")); // 驗(yàn)證集合包含 member3
// 從集合中刪除某個(gè)成員
redisTemplate.opsForSet().remove("mySetKey", "member2");
assertFalse(redisTemplate.opsForSet().members("mySetKey").contains("member2")); // 驗(yàn)證 member2 已被刪除
// 檢查某個(gè)成員是否在集合中
Boolean isMember = redisTemplate.opsForSet().isMember("mySetKey", "member1");
assertEquals(true, isMember); // 驗(yàn)證 member1 仍在集合中
}
}注意:
- 如果說(shuō)注入的時(shí)候泛型和配置類不一樣的話,可能會(huì)導(dǎo)致使用不了配置類的相關(guān)配置,就會(huì)采用redisTemplate原有的配置,然后存儲(chǔ)到的redis的數(shù)據(jù)就是一些亂碼。
- 一定要保證注入的泛型和配置類一樣,這樣存儲(chǔ)到redis中的數(shù)據(jù)格式就是正確的
Hash(哈希表)
特點(diǎn)
- 是一個(gè)鍵值對(duì)集合,適合用于存儲(chǔ)對(duì)象。
- 每個(gè) Hash 可以存儲(chǔ)多達(dá) 2^32 - 1 鍵值對(duì)(40多億)。
- 適合存儲(chǔ)和讀取整個(gè)對(duì)象,如用戶信息、商品信息等。
業(yè)務(wù)場(chǎng)景
- 用戶信息: 存儲(chǔ)用戶的基本信息,例如用戶名、郵箱和其他屬性。
- 商品屬性: 存儲(chǔ)商品的詳細(xì)信息,如價(jià)格、描述、庫(kù)存等。
- 狀態(tài)信息: 用于存儲(chǔ)狀態(tài)信息,比如會(huì)話或任務(wù)的當(dāng)前狀態(tài)。
代碼使用案例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@SpringBootTest
public class HashExampleTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testHash() {
// 創(chuàng)建 HashMap 并存儲(chǔ)到 Redis 中
Map<String, Object> myHash = new HashMap<>();
myHash.put("field1", "value1");
myHash.put("field2", "value2");
redisTemplate.opsForHash().putAll("myHashKey", myHash);
// 獲取并驗(yàn)證哈希字段值
String fieldValue = (String) redisTemplate.opsForHash().get("myHashKey", "field1");
assertEquals("value1", fieldValue); // 驗(yàn)證字段值
// 更新哈希字段
redisTemplate.opsForHash().put("myHashKey", "field1", "newValue");
assertEquals("newValue", redisTemplate.opsForHash().get("myHashKey", "field1")); // 驗(yàn)證更新后的值
// 刪除哈希字段
redisTemplate.opsForHash().delete("myHashKey", "field2");
assertFalse(redisTemplate.opsForHash().hasKey("myHashKey", "field2")); // 驗(yàn)證字段是否已刪除
// 獲取所有字段及其值
Map<Object, Object> entries = redisTemplate.opsForHash().entries("myHashKey");
assertEquals(true, entries.containsKey("field1")); // 驗(yàn)證字段存在
assertEquals("newValue", entries.get("field1")); // 驗(yàn)證字段值
}
}注意:
- 如果說(shuō)注入的時(shí)候泛型和配置類不一樣的話,可能會(huì)導(dǎo)致使用不了配置類的相關(guān)配置,就會(huì)采用redisTemplate原有的配置,然后存儲(chǔ)到的redis的數(shù)據(jù)就是一些亂碼。
- 一定要保證注入的泛型和配置類一樣,這樣存儲(chǔ)到redis中的數(shù)據(jù)格式就是正確的
Sorted Set(有序集合)
特點(diǎn)
- 類似于集合,每個(gè)成員都是唯一的,但每個(gè)成員都會(huì)關(guān)聯(lián)一個(gè)浮點(diǎn)數(shù)值,稱為分?jǐn)?shù)(score)。
- 成員按分?jǐn)?shù)排序,可以根據(jù)分?jǐn)?shù)范圍獲取成員,也可以按分?jǐn)?shù)獲取排名。
- 適合需要根據(jù)分?jǐn)?shù)進(jìn)行排序和范圍查詢的場(chǎng)景,如排行榜、時(shí)間線等
業(yè)務(wù)場(chǎng)景
- 排行榜: 存儲(chǔ)用戶積分、排名等,可以快速查詢前 N 名用戶。
- 時(shí)間戳排序: 根據(jù)時(shí)間戳的排序存儲(chǔ)事件日志。
- 優(yōu)先級(jí)隊(duì)列: 實(shí)現(xiàn)任務(wù)調(diào)度,按照優(yōu)先級(jí)處理任務(wù)。
代碼使用案例
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@SpringBootTest
public class ZSetExampleTest {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Test
public void testZSet() {
// 向有序集合中添加元素
redisTemplate.opsForZSet().add("myZSetKey", "member1", 1);
redisTemplate.opsForZSet().add("myZSetKey", "member2", 2);
// 獲取并驗(yàn)證有序集合中的所有成員
Set<Object> zSetMembers = redisTemplate.opsForZSet().range("myZSetKey", 0, -1);
assertEquals(true, zSetMembers.contains("member1")); // 驗(yàn)證 member1 存在
assertEquals(true, zSetMembers.contains("member2")); // 驗(yàn)證 member2 存在
// 更新元素的分?jǐn)?shù)
redisTemplate.opsForZSet().incrementScore("myZSetKey", "member1", 3);
Double score = redisTemplate.opsForZSet().score("myZSetKey", "member1");
assertEquals(4.0, score); // 驗(yàn)證 member1 的分?jǐn)?shù)更新為 4.0
// 獲取指定分?jǐn)?shù)范圍內(nèi)的成員
Set<Object> rangeByScore = redisTemplate.opsForZSet().rangeByScore("myZSetKey", 1, 2);
assertEquals(true, rangeByScore.contains("member2")); // 驗(yàn)證 member2 在分?jǐn)?shù)范圍內(nèi)
// 從有序集合中刪除某個(gè)成員
redisTemplate.opsForZSet().remove("myZSetKey", "member2");
assertFalse(redisTemplate.opsForZSet().range("myZSetKey", 0, -1).contains("member2")); // 驗(yàn)證 member2 已被刪除
}
}注意:
- 如果說(shuō)注入的時(shí)候泛型和配置類不一樣的話,可能會(huì)導(dǎo)致使用不了配置類的相關(guān)配置,就會(huì)采用redisTemplate原有的配置,然后存儲(chǔ)到的redis的數(shù)據(jù)就是一些亂碼。
- 一定要保證注入的泛型和配置類一樣,這樣存儲(chǔ)到redis中的數(shù)據(jù)格式就是正確的
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis哨兵主備切換的數(shù)據(jù)丟失問(wèn)題及解決
主備切換過(guò)程中可能會(huì)導(dǎo)致數(shù)據(jù)丟失,異步復(fù)制和腦裂是兩種主要原因,異步復(fù)制可能導(dǎo)致部分?jǐn)?shù)據(jù)未復(fù)制到slave而master宕機(jī),腦裂則可能導(dǎo)致多個(gè)master存在,舊master恢復(fù)后數(shù)據(jù)被清空,從而丟失數(shù)據(jù)2024-12-12
CentOS系統(tǒng)下Redis安裝和自啟動(dòng)配置的步驟
相信大家都知道Redis是一個(gè)C實(shí)現(xiàn)的基于內(nèi)存、可持久化的鍵值對(duì)數(shù)據(jù)庫(kù),在分布式服務(wù)中常作為緩存服務(wù)。所以這篇文章將詳細(xì)介紹在CentOS系統(tǒng)下如何從零開(kāi)始安裝到配置啟動(dòng)服務(wù)。有需要的可以參考借鑒。2016-09-09
YII2框架手動(dòng)安裝Redis擴(kuò)展的過(guò)程
這篇文章主要介紹了YII2框架手動(dòng)安裝Redis擴(kuò)展的過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06
redis集群主從節(jié)點(diǎn)自動(dòng)切換方式
這篇文章主要介紹了redis集群主從節(jié)點(diǎn)自動(dòng)切換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01
通過(guò) Redis 實(shí)現(xiàn) RPC 遠(yuǎn)程方法調(diào)用(支持多種編程語(yǔ)言)
這篇文章主要介紹了通過(guò) Redis 實(shí)現(xiàn) RPC 遠(yuǎn)程方法調(diào)用,支持多種編程語(yǔ)言,本文就以Ruby和Python為例,給出了實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-09-09
Redis消息隊(duì)列實(shí)現(xiàn)異步秒殺功能
在高并發(fā)場(chǎng)景下,為了提高秒殺業(yè)務(wù)的性能,可將部分工作交給 Redis 處理,并通過(guò)異步方式執(zhí)行,Redis 提供了多種數(shù)據(jù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)消息隊(duì)列,總結(jié)三種,本文詳細(xì)介紹Redis消息隊(duì)列實(shí)現(xiàn)異步秒殺功能,感興趣的朋友一起看看吧2025-04-04
Redis的五種基本類型和業(yè)務(wù)場(chǎng)景和使用方式
Redis是一種高性能的鍵值存儲(chǔ)數(shù)據(jù)庫(kù),支持多種數(shù)據(jù)結(jié)構(gòu)如字符串、列表、集合、哈希表和有序集合等,它提供豐富的API和持久化功能,適用于緩存、消息隊(duì)列、排行榜等多種場(chǎng)景,Redis能夠?qū)崿F(xiàn)高速讀寫操作,尤其適合需要快速響應(yīng)的應(yīng)用2024-10-10

