Redis是什么?一篇講透它的定位、特點與應用場景

Redis是什么?一篇講透它的定位、特點與應用場景

1. Redis的定義與核心概念

1.1 什么是Redis?

Redis(Remote Dictionary Server) 是一個開源的、基于內存的數據結構存儲系統,可以用作數據庫緩存消息代理。Redis由意大利開發者Salvatore Sanfilippo于2009年開發,目前已成為最受歡迎的NoSQL數據庫之一。

1.2 Redis的核心定位

定位角色描述典型場景
內存數據庫將數據主要存儲在內存中,提供超高性能的讀寫操作實時計算、會話存儲
緩存系統作為傳統數據庫的緩存層,加速數據訪問Web應用緩存、API響應緩存
消息中間件支持發布/訂閱模式,實現消息傳遞實時通知、事件驅動架構

1.3 Redis的數據模型

Redis采用**鍵值對(Key-Value)**的數據模型,但與傳統KV存儲不同的是,Redis的Value支持多種數據結構:

Key -> Value
其中Value可以是:
├── String(字符串)
├── Hash(哈希表)
├── List(列表)
├── Set(集合)
├── Sorted Set(有序集合)
├── Bitmap(位圖)
├── HyperLogLog(基數統計)
└── Stream(流,Redis 5.0+)

2. Redis的關鍵特性深度解析

2.1 內存存儲 + 持久化

內存優先策略

  • Redis將數據主要存儲在內存中,讀寫速度可達10萬-20萬QPS
  • 支持兩種持久化方式:RDB快照AOF日志
  • 可以在性能和數據安全性之間找到平衡

持久化對比表

持久化方式RDB快照AOF日志
存儲內容內存數據快照寫命令日志
文件大小較小較大
恢復速度
數據完整性可能丟失部分數據更完整
CPU開銷定期執行,開銷小持續寫入,開銷大

2.2 豐富的數據結構

Redis不僅僅是簡單的KV存儲,而是一個數據結構服務器

Redis數據結構
String 字符串
Hash 哈希表
List 列表
Set 集合
ZSet 有序集合
特殊結構
計數器
緩存JSON
分布式鎖
對象存儲
用戶信息
消息隊列
最近訪問
標簽去重
好友關系
排行榜
延時隊列
Bitmap位圖
HyperLogLog
Stream流

2.3 單線程模型的高性能

Redis采用單線程事件循環模型,避免了多線程的上下文切換和鎖競爭:

Redis性能優勢來源

  1. 內存操作:避免磁盤I/O瓶頸
  2. 單線程:無鎖設計,避免線程切換開銷
  3. I/O多路復用:使用epoll/kqueue處理并發連接
  4. 高效數據結構:針對不同場景優化的數據結構實現

2.4 原子性操作

Redis的所有操作都是原子性的,這意味著:

  • 單個命令的執行不會被其他命令打斷
  • 可以使用Redis事務(MULTI/EXEC)實現多命令原子性
  • 支持Lua腳本,實現復雜原子性操作

3. Redis與其他數據庫的對比

3.1 Redis vs MySQL

對比維度RedisMySQL
存儲方式內存 + 持久化磁盤存儲
數據模型NoSQL鍵值對關系型表結構
查詢能力簡單查詢復雜SQL查詢
事務支持簡單事務ACID完整事務
擴展性水平擴展容易垂直擴展為主
性能讀寫:10萬+QPS讀寫:幾千QPS
數據一致性最終一致性強一致性
適用場景緩存、會話、計數器業務數據存儲

3.2 Redis vs Memcached

對比維度RedisMemcached
數據結構8種豐富數據結構僅支持字符串
持久化支持RDB和AOF不支持
分布式原生Cluster支持客戶端分片
內存回收多種淘汰策略LRU淘汰
單線程/多線程單線程多線程
網絡模型事件驅動多線程
功能豐富度極其豐富相對簡單

4. Redis的典型應用場景

4.1 緩存系統

場景描述:作為數據庫前端緩存,減少數據庫壓力,提升響應速度。

Java實現示例

@Service
public class UserService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate UserMapper userMapper;/*** 查詢用戶信息(帶緩存)*/public User getUserById(Long userId) {String cacheKey = "user:" + userId;// 1. 先從緩存查詢User user = (User) redisTemplate.opsForValue().get(cacheKey);if (user != null) {return user; // 緩存命中}// 2. 緩存未命中,查詢數據庫user = userMapper.selectById(userId);if (user != null) {// 3. 寫入緩存,設置過期時間redisTemplate.opsForValue().set(cacheKey, user, 30, TimeUnit.MINUTES);}return user;}/*** 更新用戶信息(緩存失效)*/@Transactionalpublic void updateUser(User user) {// 1. 更新數據庫userMapper.updateById(user);// 2. 刪除緩存String cacheKey = "user:" + user.getId();redisTemplate.delete(cacheKey);}
}

4.2 分布式鎖

場景描述:在分布式系統中實現互斥訪問,防止并發問題。

Java實現示例

@Component
public class RedisDistributedLock {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final String LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('del', KEYS[1]) " +"else return 0 end";/*** 獲取分布式鎖*/public boolean tryLock(String lockKey, String requestId, int expireTime) {Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, Duration.ofSeconds(expireTime));return Boolean.TRUE.equals(result);}/*** 釋放分布式鎖*/public boolean releaseLock(String lockKey, String requestId) {DefaultRedisScript<Long> script = new DefaultRedisScript<>();script.setScriptText(LOCK_SCRIPT);script.setResultType(Long.class);Long result = redisTemplate.execute(script, Collections.singletonList(lockKey), requestId);return result != null && result == 1L;}
}

4.3 計數器和限流器

Java實現示例

@Component
public class RedisCounterService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;/*** 增加計數*/public Long increment(String key) {return redisTemplate.opsForValue().increment(key);}/*** 獲取計數*/public Long getCount(String key) {String value = redisTemplate.opsForValue().get(key);return value != null ? Long.parseLong(value) : 0L;}
}@Component
public class RedisRateLimiter {@Autowiredprivate RedisTemplate<String, String> redisTemplate;// 滑動窗口限流Lua腳本private static final String RATE_LIMIT_SCRIPT = "local key = KEYS[1] " +"local window = tonumber(ARGV[1]) " +"local limit = tonumber(ARGV[2]) " +"local current = tonumber(ARGV[3]) " +"redis.call('zremrangebyscore', key, '-inf', current - window) " +"local cnt = redis.call('zcard', key) " +"if cnt < limit then " +"redis.call('zadd', key, current, current) " +"redis.call('expire', key, window + 1) " +"return 1 " +"else " +"return 0 " +"end";/*** 滑動窗口限流*/public boolean isAllowed(String key, int windowSize, int limit) {DefaultRedisScript<Long> script = new DefaultRedisScript<>();script.setScriptText(RATE_LIMIT_SCRIPT);script.setResultType(Long.class);long currentTime = System.currentTimeMillis();Long result = redisTemplate.execute(script, Collections.singletonList(key), String.valueOf(windowSize * 1000), String.valueOf(limit), String.valueOf(currentTime));return result != null && result == 1L;}
}

4.4 排行榜系統

Java實現示例

@Service
public class RankingService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;private static final String RANKING_KEY = "game:ranking";/*** 更新用戶分數*/public void updateScore(String userId, double score) {redisTemplate.opsForZSet().add(RANKING_KEY, userId, score);}/*** 獲取排行榜TOP N*/public List<RankingItem> getTopRanking(int topN) {Set<ZSetOperations.TypedTuple<String>> tuples = redisTemplate.opsForZSet().reverseRangeWithScores(RANKING_KEY, 0, topN - 1);List<RankingItem> rankings = new ArrayList<>();int rank = 1;for (ZSetOperations.TypedTuple<String> tuple : tuples) {RankingItem item = new RankingItem();item.setRank(rank++);item.setUserId(tuple.getValue());item.setScore(tuple.getScore());rankings.add(item);}return rankings;}/*** 獲取用戶排名*/public Long getUserRank(String userId) {Long rank = redisTemplate.opsForZSet().reverseRank(RANKING_KEY, userId);return rank != null ? rank + 1 : null;}
}@Data
public class RankingItem {private Integer rank;private String userId;private Double score;
}

5. Redis的架構模式

5.1 單機模式

適用場景:開發環境、小型應用、非關鍵業務

優點

  • 部署簡單
  • 運維成本低
  • 性能高

缺點

  • 單點故障風險
  • 容量限制
  • 無法水平擴展

5.2 主從復制模式

適用場景:讀寫分離、數據備份、提高可用性

Java配置示例

@Configuration
public class RedisReplicationConfig {@Bean@Primarypublic LettuceConnectionFactory masterConnectionFactory() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setHostName("redis-master");config.setPort(6379);return new LettuceConnectionFactory(config);}@Beanpublic LettuceConnectionFactory slaveConnectionFactory() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setHostName("redis-slave");config.setPort(6379);return new LettuceConnectionFactory(config);}
}

6. Java中的Redis實戰示例

6.1 Spring Boot集成Redis

依賴配置

<dependencies><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>

配置文件

spring:redis:host: localhostport: 6379password: database: 0timeout: 3000mslettuce:pool:max-active: 200max-wait: -1msmax-idle: 50min-idle: 10

6.2 Redis工具類封裝

@Component
public class RedisUtil {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 普通緩存獲取*/public Object get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通緩存放入并設置時間*/public boolean set(String key, Object value, long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);} else {redisTemplate.opsForValue().set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 遞增*/public long incr(String key, long delta) {if (delta < 0) {throw new RuntimeException("遞增因子必須大于0");}return redisTemplate.opsForValue().increment(key, delta);}
}

7. 生產環境最佳實踐

7.1 鍵命名規范

推薦規范

  • 使用冒號分隔命名空間:user:profile:1001
  • 避免過長的鍵名,建議不超過250字符
  • 使用有意義的名稱,避免縮寫

7.2 內存優化策略

  1. 設置合理的過期時間
  2. 選擇合適的數據結構
  3. 避免大key
  4. 配置內存淘汰策略

7.3 安全配置

  1. 設置訪問密碼
  2. 綁定內網IP
  3. 禁用危險命令
  4. 開啟安全模式

8. 總結

Redis作為一個高性能的內存數據庫,具有以下核心優勢:

  1. 極高的性能:基于內存存儲,支持10萬+QPS
  2. 豐富的數據結構:支持8種數據類型,適應多種場景
  3. 高可用性:支持主從復制、哨兵、集群等部署模式
  4. 持久化保障:RDB+AOF雙重保障數據安全
  5. 生態豐富:與各種編程語言和框架完美集成

Redis適用于緩存、會話存儲、計數器、排行榜、分布式鎖等多種場景,是現代互聯網架構中不可或缺的組件。

通過本文的學習,你應該對Redis有了全面的認識。在后續文章中,我們將深入探討Redis的各個特性和實現原理。


下一篇預告:《Redis環境搭建指南:Windows/Linux/Docker多場景安裝與配置》


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/922116.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/922116.shtml
英文地址,請注明出處:http://en.pswp.cn/news/922116.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一款免費開源輕量的漏洞情報系統 | 漏洞情報包含:組件漏洞 + 軟件漏洞 + 系統漏洞

工具介紹 bug_search一款免費開源輕量的漏洞情報系統 基于python3 Amis2.9 開發&#xff0c;僅依賴Flask,requests&#xff0c;無需數據庫&#xff0c;Amis是百度開源的低代碼前端框架漏洞情報包含&#xff1a;組件漏洞 軟件漏洞 系統漏洞 增加郵件發送消息報警功能增加釘釘…

詳解在Windows系統中生成ssl證書,實現nginx配置https的方法

目錄一、下載安裝OpenSSL二、證書生成三、修改nginx配置總結Nginx 是一個高性能的HTTP和反向代理web服務器&#xff0c;在進行web項目開發時&#xff0c;大多都是使用nginx對外提供web服務。HTTPS &#xff08;全稱&#xff1a;Hypertext Transfer Protocol Secure [5]&#xf…

AI視覺算法中的OpenCV API (二)

視頻寫入 (FourCC, VideoWriter)? 1. VideoWriter_fourcc - 視頻編碼器四字符代碼 # OpenCV 3.x, 4.x fourcc cv2.VideoWriter_fourcc(M,J,P,G)fourcc cv2.VideoWriter_fourcc(*H264)fourcc cv2.VideoWriter_fourcc(*MJPG) ?FourCC?&#xff1a; 代表 ?Four ?Charac…

分享| 2025年版AIGC數字人實驗室解決方案教學資源解析

AIGC數字人實驗室解決方案構建了涵蓋基礎層、平臺環境層與資源層的多層次教學架構&#xff0c;依托150平方米的實體空間與60人并行授課的規模化支持&#xff0c;為學生提供了技術實踐與創新的高效平臺。其教學資源體系覆蓋AIGC文本生成、圖像生成、數字人應用與智能體開發四大核…

內存大(巨)頁

一、大&#xff08;巨&#xff09;頁 大&#xff08;巨&#xff09;頁&#xff0c;很好理解&#xff0c;就是的大的頁。說這個大頁前&#xff0c;得先把計算機中內存的管理簡單說明一下&#xff0c;否則可能對于一些新手或者把操作系統中內存管理的方法的開發者不太友好。最早的…

langgraph astream使用詳解

langgraph中graph的astream&#xff08;stream&#xff09;方法分別實現異步&#xff08;同步&#xff09;流式應答&#xff0c;在langgraph-api服務也是核心方法&#xff0c;實現與前端的對接&#xff0c;必須要把這個方法弄明白。該方法中最重要的參數是stream_mode&#xff…

【C++】模板進階:非類型參數、模板特化與分離編譯

目錄 1. 非類型模板參數 2. 模板的特化 3. 分離編譯 1. 非類型模板參數 模板參數分類類型形參與非類型形參。 類型形參即&#xff1a;出現在模板參數列表中&#xff0c;跟在class或者typename之類的參數類型名稱。 非類型形參&#xff0c;就是用一個常量作為類(函數)模板…

棧-1047.刪除字符串中的所有相鄰重復項-力扣(LeetCode)

一、題目解析 1、反復執行重復項刪除操作 2、s僅由小寫英文字母組成 二、算法原理 該題并不難&#xff0c;難的是能不能想到用棧這個數據結構解題 解法&#xff1a;棧模擬 橫著看起來不好理解&#xff0c;我們把它豎起來&#xff0c;是不是和消消樂很類似&#xff0c;兩兩消…

【每日算法】移除元素 LeetCode

雙指針方法是解決數組或鏈表問題中非常高效的技巧之一&#xff0c;尤其適用于原地修改數組或減少時間復雜度的場景。以下是對雙指針方法的詳細講解。1. 雙指針方法的核心思想雙指針方法通常使用兩個指針&#xff08;或索引&#xff09;在數組或鏈表中協同工作&#xff0c;通過一…

Android 項目:畫圖白板APP開發(六)——分頁展示

本篇將介紹如何為我們的畫板應用添加分頁展示功能&#xff0c;讓用戶可以創建多個畫布并在它們之間輕松切換。這章沒有啥知識點的講解&#xff0c;主要介紹一下每頁保存的數據結構是什么樣的。 一、ListView 多頁數據的管理我們使用ListView。之前有文章講過ListView這里就不多…

智能眼鏡產品成熟度分析框架與評估

引言 當前(2025年9月12日),智能眼鏡(Smart Glasses)市場正處于快速演進階段,從早期的新奇設備向主流消費電子轉型。AI整合、AR顯示和多模態交互的進步推動了這一轉變。根據最新數據,2025年AI眼鏡發貨量預計達686萬臺,同比增長265%,全球市場規模從2024年的約19.3億美元…

(網絡編程)網絡編程套接字 UDP的socket API 代碼解析

網絡編程基礎 為什么需要網絡編程?--豐富的網絡資源 用戶在瀏覽器中,打開在線視頻網站,如優酷看視頻,實質是通過網絡,獲取到網絡上的一個視頻資源。與本地打開視頻文件類似,只是視頻文件這個資源的來源是網絡。 相比本地資源來說,網絡提供了更為豐富的網絡資源:所謂的網絡資源…

【STM32】狀態機(State Machine)

這篇博客介紹 狀態機&#xff08;State Machine&#xff09;&#xff0c;適合用于嵌入式開發、驅動開發、協議解析、按鍵識別等多種場景。 一、什么是狀態機&#xff08;State Machine&#xff09;&#xff1f; 狀態機&#xff08;State Machine&#xff09;是一種用于描述系統…

深度學習在離崗檢測中的應用

離崗檢測技術正逐步成為現代企業精細化管理和安全生產的重要工具。這項基于計算機視覺和人工智能的應用&#xff0c;通過自動化、實時化的監測方式&#xff0c;有效提升了工作紀律性和運營效率&#xff0c;為項目管理者和企業提供了創新的監管解決方案。在許多工作場景中&#…

Spring緩存(二):解決緩存雪崩、擊穿、穿透問題

1. 緩存穿透問題與解決方案 1.1 什么是緩存穿透 緩存穿透是指查詢一個不存在的數據&#xff0c;由于緩存中沒有這個數據&#xff0c;每次請求都會直接打到數據庫。 如果有惡意用戶不斷請求不存在的數據&#xff0c;就會給數據庫帶來巨大壓力。 這種情況下&#xff0c;緩存失去了…

PHP 與 WebAssembly 的 “天然隔閡”

WebAssembly&#xff08;簡稱 WASM&#xff09;是一種低級二進制指令格式&#xff0c;旨在為高級語言提供高性能的編譯目標&#xff0c;尤其在瀏覽器環境中實現接近原生的執行效率。它主要用于前端性能密集型場景&#xff08;如游戲引擎、視頻編解碼、3D 渲染等&#xff09;&am…

unity中通過拖拽,自定義scroll view中子物體順序

1.在每個content的子物體上掛載DragHandler腳本&#xff0c;并且添加Canvs Group組件&#xff0c;設置見圖2.DragHandler腳本內容&#xff1a;using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections.Generic; using System.Coll…

用 Matplotlib 繪制餅圖:從基礎語法到實戰美化,全面掌握分類數據可視化技巧

用 Matplotlib 繪制餅圖:從基礎語法到實戰美化,全面掌握分類數據可視化技巧 在數據分析與可視化的世界里,**“圖勝千言”**早已成為共識。而在眾多圖表類型中,餅圖(Pie Chart)以其直觀的比例展示方式,成為展示分類數據分布的常見選擇。無論是業務報表、用戶畫像,還是市…

基礎算法之二分算法 --- 2

大家好&#xff0c;不同的時間&#xff0c;相同的地點&#xff0c;時隔多日我們又見面了。繼上次的二分算法后&#xff0c;我們這次要來學習的是二分答案了。這個部分相較于前面的二分算法難度有相當的提升&#xff0c;希望大家有所準備。雖然難度增加了&#xff0c;但是博主還…

發揮nano banana的最大能力

1. 概述Nano Banana 簡介&#xff1a;Nano Banana 是 Google DeepMind 開發的 AI 圖像生成與編輯模型&#xff0c;集成在 Google Gemini 平臺中&#xff08;具體為 Gemini 2.5 Flash 版本&#xff09;。它以高效的圖像編輯能力聞名&#xff0c;尤其在角色一致性、光影理解和快速…