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能夠提供極高的讀寫(xiě)速度,適用于需要高速響應(yīng)的場(chǎng)景12。
- 持久化功能:Redis支持將內(nèi)存中的數(shù)據(jù)周期性地寫(xiě)入磁盤,確保數(shù)據(jù)的安全性,同時(shí)也支持將修改操作寫(xiě)入追加的記錄文件,實(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: 6379
redis的配置類(用于格式轉(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-12CentOS系統(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-09YII2框架手動(dòng)安裝Redis擴(kuò)展的過(guò)程
這篇文章主要介紹了YII2框架手動(dòng)安裝Redis擴(kuò)展的過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06redis集群主從節(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-09Redis消息隊(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-04Redis的五種基本類型和業(yè)務(wù)場(chǎng)景和使用方式
Redis是一種高性能的鍵值存儲(chǔ)數(shù)據(jù)庫(kù),支持多種數(shù)據(jù)結(jié)構(gòu)如字符串、列表、集合、哈希表和有序集合等,它提供豐富的API和持久化功能,適用于緩存、消息隊(duì)列、排行榜等多種場(chǎng)景,Redis能夠?qū)崿F(xiàn)高速讀寫(xiě)操作,尤其適合需要快速響應(yīng)的應(yīng)用2024-10-10