Redis 實踐指南與核心概念
一、Java 中常用的 Redis 使用場景與實踐
-
緩存(Caching)
-
場景:熱點數據、頻繁訪問的數據,如商品詳情、用戶信息。通過緩存減少數據庫壓力,提高系統響應速度。
-
工業界實踐:
- 淘寶/天貓:商品詳情頁、用戶會話、購物車等核心數據大量使用 Redis 緩存,通過多級緩存(CDN -> Nginx/OpenResty Lua -> 本地緩存 -> Redis Cluster -> DB)分擔流量,降低數據庫壓力。秒殺場景下,利用 Redis 預熱庫存、扣減庫存,并通過 Lua 腳本保證原子性。
- 美團:大規模 KV 存儲服務(如 Squirrel 內存 KV、Cellar 持久化 KV)承載萬億級請求,保持高可用性,廣泛應用于團購、外賣等業務的核心數據緩存 。
- 拼多多/字節跳動:類似電商、內容推薦等場景,也大量使用 Redis 作為緩存層,優化數據讀取性能,支撐高并發訪問。
-
實現:在 Java 中,通常使用 Spring Cache、Redisson 或 Jedis 等客戶端。Spring Cache 提供了聲明式緩存支持,通過注解即可實現。
-
示例:
@Servicepublic class ProductService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Cacheable(value = "products", key = "#productId", unless = "#result == null")public void getProductById(Long productId) {} } ```
-
配置與引用:
- Maven 依賴:引入
spring-boot-starter-data-redis
和spring-boot-starter-cache
。 application.properties
配置:spring.redis.host=localhost spring.redis.port=6379 spring.redis.password= spring.redis.database=0 spring.redis.timeout=5000ms spring.cache.type=redis # 配置緩存的默認過期時間(例如:1小時) spring.cache.redis.time-to-live=3600000
- Key 命名規范:工業界通常會采用
業務域:業務類型:唯一標識
的方式,例如product:detail:123
,user:info:abc
。這有助于管理和排查問題。 - 過期時間:根據數據熱度、一致性要求設置。對于強一致性要求不高的數據,可以設置較長過期時間;對于實時性要求高的數據,過期時間應短,或配合消息隊列進行主動失效。
- Maven 依賴:引入
-
-
分布式鎖(Distributed Locks)
- 場景:在分布式系統中,確保同一時間只有一個服務實例能執行特定代碼塊,防止并發問題,如秒殺系統庫存扣減、防止重復提交訂單。
- 工業界實踐:
- 電商平臺(淘寶、拼多多):在秒殺、搶購等高并發場景下,廣泛使用 Redis 分布式鎖來控制庫存的原子性扣減,防止超賣。通常會結合 Lua 腳本保證操作的原子性,并利用 Redisson 等框架提供的看門狗機制自動續期,避免死鎖。
- 美團/滴滴:在訂單處理、支付、優惠券發放等核心業務流程中,使用分布式鎖來保證數據一致性,避免重復操作或并發沖突。
- 實現:基于 Redis 的
SETNX
命令(或SET key value NX EX
)實現。工業界常用 Redisson 框架,它提供了更高級的鎖功能,如可重入鎖、公平鎖、看門狗機制(自動續期)。 - 示例:
@Autowired private RedissonClient redissonClient; public void processOrder(String orderId) {RLock lock = redissonClient.getLock("order_lock:" + orderId);try {// 嘗試獲取鎖,等待10秒,鎖自動釋放5秒(看門狗默認30秒,這里是手動設置)if (lock.tryLock(10, 5, TimeUnit.SECONDS))// 業務邏輯:處理訂單,例如扣減庫存、創建訂單記錄}} catch (InterruptedException e) {Thread.currentThread().interrupt();System.err.println("Order processing interrupted for " + orderId + ": " + e.getMessage());} finally {// 確保鎖被當前線程持有才釋放,防止誤刪if (lock.isLocked() && lock.isHeldByCurrentThread()) {lock.unlock();}} }
- 避坑指南:
- 必須設置過期時間:防止因服務宕機導致死鎖。
- 使用唯一標識:避免誤刪其他線程的鎖。
- 任務執行時間 < 鎖超時時間:避免業務未完成鎖已釋放,導致并發問題。Redisson 的看門狗機制可以自動續期,緩解此問題。
-
消息隊列(Message Queue)
- 場景:異步處理、服務解耦、流量削峰填谷,如訂單支付成功后的后續處理(發貨、積分)、日志收集、數據同步。
- 工業界實踐:
- 美團/餓了么:在訂單狀態變更、配送信息更新、用戶消息通知等場景,利用 Redis 作為輕量級消息隊列,實現服務間的異步通信和解耦。
- 字節跳動/快手:在短視頻、直播等場景,利用 Redis Stream 存儲用戶行為日志、點贊、評論等實時數據,進行實時處理和分析。
- 電商平臺:用于處理用戶下單后的異步操作,如庫存扣減、積分發放、短信通知等,避免阻塞主流程。
- 實現:利用 Redis 的 List(
LPUSH
/BRPOP
)或 Stream 數據結構。List 簡單易用,適合簡單的隊列;Stream 功能更強大,支持消費者組、消息持久化等,更適合復雜的 MQ 場景。 - 示例(List 實現簡單隊列):
@Autowired private StringRedisTemplate redisTemplate;public void sendMessage(String queueName, String message) {redisTemplate.opsForList().leftPush(queueName, message); // 生產者:從左側入隊}public String receiveMessage(String queueName) {// 消費者:阻塞式從右側出隊,等待0秒表示一直阻塞直到有消息String message = redisTemplate.opsForList().rightPop(queueName, 0, TimeUnit.SECONDS);return message; }
-
計數器/排行榜(Counters/Leaderboards)
- 場景:實時統計網站訪問量、文章點贊數、商品銷量、游戲積分榜、用戶活躍度。
二、Redis 核心原理與面試要點
-
為什么 Redis 這么快?
- 基于內存:所有數據都存儲在內存中,避免了磁盤 I/O 的開銷。
- 單線程模型:Redis 內部使用單線程處理所有請求,避免了多線程的上下文切換開銷和鎖競爭問題。雖然是單線程,但 Redis 采用了 I/O 多路復用技術(如 epoll、kqueue),可以在一個線程中同時監聽多個 socket 連接,實現高并發。
- 高效的數據結構:Redis 內部實現了多種高效的數據結構,如跳躍表(Skip List)、壓縮列表(Zip List)、哈希表(Hash Table)等,針對不同的數據類型進行了優化,使得操作效率極高。
- 非阻塞 I/O:使用 I/O 多路復用,避免了傳統阻塞 I/O 的等待。
- C 語言實現:C 語言的執行效率高,且對內存控制更精細。
-
Redis 的主要數據結構及應用場景
- String(字符串):最基本的數據類型,可以存儲字符串、整數或浮點數。常用于緩存、計數器、分布式鎖(配合
SETNX
)。- 底層實現:SDS(Simple Dynamic String),類似于 C++ 的
std::string
,支持動態擴容,減少內存重新分配次數,并記錄長度,獲取字符串長度為 O(1)。
- 底層實現:SDS(Simple Dynamic String),類似于 C++ 的
- Hash(哈希):鍵值對集合,適合存儲對象。常用于存儲用戶信息、商品信息等。
- 底層實現:當哈希的鍵值對數量較少且鍵值長度較小時,使用
ziplist
(壓縮列表)存儲,節省內存;否則使用hashtable
(哈希表)。
- 底層實現:當哈希的鍵值對數量較少且鍵值長度較小時,使用
- List(列表):有序的字符串列表,可以從兩端進行插入和刪除。常用于消息隊列、最新消息列表。
- 底層實現:Redis 3.2 之前使用
ziplist
和linkedlist
,之后統一使用quicklist
,它是一個雙向鏈表,每個節點是一個ziplist
,兼顧了內存效率和操作性能。
- 底層實現:Redis 3.2 之前使用
- Set(集合):無序的字符串集合,元素唯一。常用于存儲共同關注、抽獎活動、標簽。
- 底層實現:當集合中元素都是整數且數量較少時,使用
intset
(整數集合)存儲,節省內存;否則使用hashtable
。
- 底層實現:當集合中元素都是整數且數量較少時,使用
- ZSet(有序集合):有序的字符串集合,每個元素關聯一個分數,通過分數進行排序。常用于排行榜、帶權重的任務隊列。
- 底層實現:當有序集合中元素數量較少且元素長度較小時,使用
ziplist
存儲;否則使用skiplist
(跳躍表)和hashtable
的組合,跳躍表用于快速查找和范圍查詢,哈希表用于 O(1) 時間復雜度獲取元素分數。
- 底層實現:當有序集合中元素數量較少且元素長度較小時,使用
- Geospatial(地理空間):存儲地理位置信息,可以計算兩點距離、查找附近的人/地點。底層基于 ZSet 實現。
- HyperLogLog:用于基數統計(不重復元素的數量),例如統計網站 UV。允許一定誤差,但內存占用極小。
- Stream:Redis 5.0 引入的新的數據結構,類似于 Kafka,支持多消費者組、消息持久化、消息回溯等。適用于消息隊列、事件日志。
- String(字符串):最基本的數據類型,可以存儲字符串、整數或浮點數。常用于緩存、計數器、分布式鎖(配合
-
Redis 持久化機制
- RDB(Redis Database):快照持久化,在指定時間間隔內將內存中的數據集快照寫入磁盤。優點是恢復速度快,適合備份;缺點是可能丟失最后一次快照之后的數據。
- AOF(Append Only File):增量持久化,記錄 Redis 執行的每個寫命令。優點是數據完整性高,丟失數據少;缺點是文件可能較大,恢復速度相對 RDB 慢。
- 混合持久化(Redis 4.0+):RDB 和 AOF 的結合,啟動時加載 RDB 文件,再重放 AOF 文件中 RDB 快照之后的操作,兼顧了恢復速度和數據完整性。
-
Redis 淘汰策略(內存滿了怎么辦?)
- 當 Redis 內存達到上限時,會根據配置的淘汰策略來刪除鍵。
noeviction
:默認策略,不刪除任何鍵,寫操作會報錯。allkeys-lru
:從所有鍵中選擇最近最少使用的鍵進行淘汰。volatile-lru
:從設置了過期時間的鍵中選擇最近最少使用的鍵進行淘汰。allkeys-random
:從所有鍵中隨機淘汰。volatile-random
:從設置了過期時間的鍵中隨機淘汰。allkeys-ttl
:從所有鍵中選擇即將過期的鍵進行淘汰。volatile-ttl
:從設置了過期時間的鍵中選擇即將過期的鍵進行淘汰。
-
Redis 事務
- Redis 事務通過
MULTI
、EXEC
、DISCARD
、WATCH
命令實現。 MULTI
:開啟事務,后續命令入隊。EXEC
:執行所有入隊命令。DISCARD
:取消事務,清空命令隊列。WATCH
:監視一個或多個鍵,如果在事務執行前這些鍵被其他客戶端修改,則事務會被打斷(樂觀鎖)。- 特點:Redis 事務是原子性的(要么都執行,要么都不執行),但不支持回滾(命令入隊時檢查語法錯誤,執行時即使出錯也不會回滾)。
- Redis 事務通過
-
Redis 主從復制
- 目的:實現數據冗余、讀寫分離、故障恢復。
- 原理:主節點負責寫操作,從節點負責讀操作。主節點將寫命令同步給從節點。
- 全量復制:當從節點第一次連接主節點或斷線重連后,主節點會生成 RDB 文件發送給從節點,從節點加載 RDB 文件。
- 增量復制:主從節點都維護一個復制偏移量和復制積壓緩沖區,主節點將新的寫命令發送給從節點。
-
Redis Sentinel(哨兵)
- 目的:解決主從復制的自動故障轉移問題,實現高可用。
- 功能:監控 Redis 主從節點狀態、自動故障轉移(當主節點宕機時,從節點中選舉新的主節點)、通知客戶端新的主節點地址。
- 部署:通常部署多個 Sentinel 實例,形成 Sentinel 集群,通過投票機制決定是否進行故障轉移。
-
Redis Cluster(集群)
- 目的:解決單機 Redis 的容量和并發瓶頸,實現分布式存儲和高可用。
- 分片:Redis Cluster 采用哈希槽(Hash Slot)的方式進行數據分片,共有 16384 個哈希槽,每個鍵通過 CRC16 算法計算哈希值,然后對 16384 取模,決定分配到哪個槽。
- 節點:每個節點負責一部分哈希槽,節點之間通過 Gossip 協議進行通信,維護集群狀態。
- 高可用:每個主節點可以有多個從節點,當主節點宕機時,從節點可以自動晉升為主節點。
- 擴容與縮容:支持在線擴容和縮容,通過遷移哈希槽實現。
-
緩存穿透、緩存擊穿、緩存雪崩
- 緩存穿透:查詢一個不存在的數據,導致每次請求都打到數據庫。解決方案:布隆過濾器、緩存空對象。
- 緩存擊穿:某個熱點數據過期,大量請求同時打到數據庫。解決方案:設置熱點數據永不過期、加分布式鎖。
- 緩存雪崩:大量緩存同時失效,導致所有請求都打到數據庫。解決方案:緩存過期時間錯開、多級緩存、熔斷降級。
-
Redis 為什么沒有替代品?
-
性能卓越:在內存數據庫領域,Redis 的性能表現非常突出,能夠滿足絕大多數高并發場景的需求。
-
功能豐富:除了基本的鍵值存儲,還提供了豐富的數據結構和功能(如發布訂閱、事務、Lua 腳本等),能夠應對多種復雜業務場景。
-
生態成熟:擁有龐大的社區支持、豐富的客戶端庫和完善的周邊工具,易于集成和使用。
-
簡單易用:API 簡潔明了,學習成本低,部署和維護相對簡單。
-
高可用和擴展性:通過主從復制、Sentinel、Cluster 等機制,提供了完善的高可用和橫向擴展解決方案。
-
應用廣泛:在互聯網行業得到了廣泛應用,積累了大量的實踐經驗和解決方案。
-
工業界實踐:
- 新聞/內容推薦平臺(字節跳動、騰訊新聞):實時統計文章閱讀量、點贊數、評論數,并根據這些指標生成熱門文章排行榜。
- 電商平臺(淘寶、京東):實時更新商品銷量、評價數,并用于生成商品熱銷榜、好評榜。
- 游戲公司:實時更新玩家積分、排名,用于游戲排行榜。
-
實現:使用 String 的
INCR
/DECR
命令實現簡單計數;使用 Sorted Set(ZSet)實現排行榜,ZSet 能夠根據分數自動排序。 -
示例(ZSet 實現排行榜):
@Autowired private StringRedisTemplate redisTemplate;public void updateScore(String userId, double score) {redisTemplate.opsForZSet().add("game_leaderboard", userId, score);}public Set<ZSetOperations.TypedTuple<String>> getTopPlayers(long count) {// 獲取分數從高到低的前N名玩家Set<ZSetOperations.TypedTuple<String>> topPlayers = redisTemplate.opsForZSet().reverseRangeWithScores("game_leaderboard", 0, count - 1);return topPlayers; }
-
-
Session 共享(Session Sharing)
- 場景:分布式部署的 Web 應用(如微服務架構),用戶登錄后 Session 需要在不同服務實例間共享,以實現無狀態服務。
- 工業界實踐:
- 大型互聯網公司:幾乎所有大型分布式 Web 應用都會將用戶 Session 存儲在 Redis 中,以實現 Session 共享和高可用。這使得用戶在訪問不同服務實例時,無需重新登錄,提升用戶體驗。
- 微服務架構:在微服務體系中,Session 共享是實現無狀態服務的重要一環,Redis 作為高性能的內存數據庫,是理想的 Session 存儲方案。
- 實現:將 Session 存儲到 Redis 中。Spring Session Redis 提供了開箱即用的解決方案,無需手動管理 Session 的存取。
- 配置示例(Spring Boot):
# application.properties spring.session.store-type=redis spring.redis.host=localhost spring.redis.port=6379 # ... 其他 Redis 配置
-
布隆過濾器(Bloom Filter)
- 場景:判斷一個元素是否存在于一個大規模集合中,允許一定的誤判率,但絕不允許漏判。常用于防止緩存穿透(查詢不存在的數據導致數據庫壓力)、垃圾郵件過濾、用戶黑名單。
- 工業界實踐:
- 新聞/內容推薦平臺(字節跳動):用于判斷用戶是否已讀某篇文章,避免重復推薦;或用于過濾垃圾評論、敏感詞。
- 電商平臺(淘寶、拼多多):在防止緩存穿透方面發揮重要作用,預先判斷商品 ID、用戶 ID 等是否存在,減少對數據庫的無效查詢。
- 美團/滴滴:在黑名單過濾、防止惡意請求等方面有應用。
- 實現:Redis Modules 提供了布隆過濾器功能(如 RedisBloom),Java 客戶端如 Redisson 可以集成。
- 示例:
// 假設使用 Redisson 的 RBloomFilter @Autowired private RedissonClient redissonClient;public void checkAndAddUser(String userId) {RBloomFilter<String> bloomFilter = redissonClient.getBloomFilter("user_exists_filter");// 初始化布隆過濾器,預計插入1000萬個元素,誤判率1% (m=10000000, fpp=0.01)// 實際生產中,這些參數應根據業務需求精確計算if (!bloomFilter.isInitialized()) {bloomFilter.tryInit(10000000L, 0.01);}if (!bloomFilter.contains(userId)) {// 布隆過濾器說不存在,則一定不存在。執行業務邏輯并添加到布隆過濾器bloomFilter.add(userId);// 實際業務:查詢數據庫,如果存在則添加到緩存,如果不存在則緩存空值} else {// 布隆過濾器說可能存在,則可能存在(有誤判率)。繼續查詢緩存或數據庫} }
三、緩存一致性解決方案
緩存策略=寫入策略×失效策略緩存策略 = 寫入策略 \times 失效策略緩存策略=寫入策略×失效策略
常用模式:
-
Cache-Aside(旁路緩存)
- 讀流程:
$ \text{先讀緩存} \rightarrow \text{緩存未命中} \rightarrow \text{讀DB} \rightarrow \text{回填緩存} $
- 寫流程:
$ \text{先更新DB} \rightarrow \text{再刪除緩存} $
- 工業界實踐:這是最常用的模式,簡單有效。刪除緩存而非更新緩存是為了避免并發寫導致的數據不一致問題(例如,線程A更新DB后更新緩存,線程B在線程A更新DB后、更新緩存前更新DB并更新緩存,導致緩存中是舊數據)。
- 讀流程:
-
Write-Through(直寫緩存)
- 所有寫操作同時更新緩存和DB。
- 工業界實踐:通常用于對數據一致性要求極高,且寫操作不頻繁的場景。性能開銷較大,因為每次寫都要同步更新兩個存儲。
-
Write-Behind(回寫緩存)
- 寫操作只更新緩存,然后異步地將數據回寫到DB。
- 工業界實踐:性能最高,但數據一致性風險最大,因為數據可能只存在于緩存中,尚未寫入DB。適用于對數據丟失不敏感的場景,如日志、計數器。
數據同步公式:
Tconsistency=max?(Tdb_write,Tcache_invalid)+δnetworkT_{consistency} = \max(T_{db\_write}, T_{cache\_invalid}) + \delta_{network} Tconsistency?=max(Tdb_write?,Tcache_invalid?)+δnetwork?
四、常見問題解決清單與工業界應對
問題類型 | 現象 | 解決方案 | 工業界應對 |
---|---|---|---|
緩存雪崩 | 大量 Key 同時失效,導致大量請求直接打到數據庫,使數據庫宕機。 | 1. 隨機過期時間:在原有過期時間上增加隨機值,使 Key 分散失效。 2. 多級緩存:引入本地緩存或二級緩存。 3. 熔斷降級:當 Redis 不可用時,直接返回默認值或錯誤,保護數據庫。 | 工業界實踐:大型互聯網公司通常會結合隨機過期、多級緩存(如 Guava Cache/Caffeine)、服務熔斷(Hystrix/Sentinel)等手段。對于重要數據,有時會設置永不過期,通過消息隊列或定時任務主動更新。 |
緩存穿透 | 查詢不存在的數據,緩存不命中,導致每次請求都穿透到數據庫,造成數據庫壓力。 | 1. 布隆過濾器:預先存儲所有可能存在的 Key,查詢前先通過布隆過濾器判斷 Key 是否存在。 2. 緩存空值:對于查詢結果為空的數據,也將其緩存起來,并設置較短的過期時間。 | 工業界實踐:廣泛使用布隆過濾器進行第一層過濾,結合緩存空值策略,有效攔截惡意攻擊和無效查詢。 |
熱 Key 問題 | 單個 Key 訪問量過大,導致 Redis 某個節點(或單機 Redis)的 CPU 或網絡帶寬成為瓶頸。 | 1. 本地緩存:在應用層增加本地緩存(如 Caffeine),減少對 Redis 的訪問。 2. Key 分片:將熱 Key 分散到多個 Key 上,例如 hotkey:1 , hotkey:2 ,通過哈希等方式訪問。 3. 讀寫分離:對于讀多寫少的場景,可以考慮將熱 Key 的讀請求分發到多個 Redis 從節點。 | 工業界實踐:大型互聯網公司通常會結合本地緩存、Key 分片(如將商品庫存拆分為多個 Key)、以及 Redis 集群的讀寫分離能力來應對。對于極熱 Key,甚至會考慮在 CDN 層進行緩存。 |
大 Key 問題 | 單個 Value 過大(例如超過 1MB),導致網絡傳輸開銷大、Redis 內存碎片化、主從復制延遲、AOF/RDB 持久化效率低。 | 1. 數據拆分:將大 Value 拆分為多個小 Key-Value 存儲 。 2. 壓縮存儲:對 Value 進行壓縮后再存儲 。 3. 選擇合適的數據結構:例如,使用 Hash 存儲對象,而不是將整個 JSON 字符串作為 String 存儲 。 | 工業界實踐:普遍嚴格限制 Key 的大小(例如,建議不超過 10KB,最大不超過 512MB,但實際開發中應遠小于此) 2">2< 。通過代碼規范、Lint 工具、以及 Redis 監控系統進行檢測和治理 。對于不可避免的大 Key,會進行拆分或壓縮 。 |
Key 過期時間 | Key 的存活時長設置不合理,導致數據提前失效或長期占用內存。 | 根據業務場景和數據特性合理設置過期時間。對于需要長期存在的 Key,可以設置為永不過期,并通過業務邏輯或消息隊列進行主動更新/刪除。 | 工業界實踐:很多公司會強制要求 Key 的最大存活時長(例如 1天、7天),防止 Key 長期占用內存或因業務邏輯錯誤導致 Key 無法刪除。對于特殊場景,需要申請白名單。 |
五、Redis 核心數據結構
-
基礎類型
- 字符串(String):最基本的數據類型,可以存儲字符串、整數或浮點數。支持位操作(Bitmap)。
- 命令示例:
SET key value
,GET key
,INCR key
,DECR key
,GETBIT key offset
,SETBIT key offset value
- 命令示例:
- 哈希(Hash):存儲鍵值對的集合,適合存儲對象。一個 Hash 可以存儲多個字段和值。
- 命令示例:
HSET user:1 name "Alice" age 30
,HGET user:1 name
,HGETALL user:1
- 命令示例:
- 列表(List):有序的字符串列表,底層是雙向鏈表實現。可以作為隊列或棧使用。
- 命令示例:
LPUSH queue task1 task2
,RPUSH queue task3
,LPOP queue
,RPOP queue
,LRANGE queue 0 -1
- 命令示例:
- 集合(Set):無序的字符串集合,元素唯一。支持集合間的操作,如交集、并集、差集。
- 命令示例:
SADD tags redis mysql
,SMEMBERS tags
,SISMEMBER tags redis
,SINTER set1 set2
- 命令示例:
- 有序集合(ZSet):Set 的一個擴展,每個成員都關聯一個分數(score),通過分數進行排序。適用于排行榜、帶權重的隊列。
- 命令示例:
ZADD leaderboard 100 user1 90 user2
,ZRANGE leaderboard 0 -1 WITHSCORES
,ZSCORE leaderboard user1
- 命令示例:
- 字符串(String):最基本的數據類型,可以存儲字符串、整數或浮點數。支持位操作(Bitmap)。
-
高級結構
- 位圖(Bitmap):實際上是 String 類型,通過位操作實現。常用于統計用戶活躍度、簽到等。
- 命令示例:
SETBIT login:20231101 100 1
(表示用戶ID 100在2023年11月1日活躍)
- 命令示例:
- HyperLogLog:用于基數估算(統計獨立元素的數量),允許有少量誤差,但內存占用極小。適用于統計 UV、獨立訪客數等。
- 命令示例:
PFADD ip_20231101 192.168.1.1 192.168.1.2
,PFCOUNT ip_20231101
- 命令示例:
- 地理空間(GEO):存儲地理位置信息(經度、緯度),并支持計算距離、查找附近的人/地點。
- 命令示例:
GEOADD cities 116.40 39.90 Beijing
,GEODIST cities Beijing Shanghai
,GEORADIUS cities Beijing 100 km
- 命令示例:
- 流(Stream):Redis 5.0 引入的全新數據結構,類似于 Kafka,支持多生產者、多消費者、消費者組、消息持久化等。適用于構建消息隊列、事件溯源等。
- 命令示例:
XADD orders * product_id 1001 user_id 200
,XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS orders >
- 命令示例:
- 位圖(Bitmap):實際上是 String 類型,通過位操作實現。常用于統計用戶活躍度、簽到等。
六、Redis 新特性解析
-
Redis 7.0 Multi-Part AOF
- 特性:將 AOF 文件分割為多個片段(如
appendonly.1.aof
,appendonly.2.aof
),而不是一個巨大的文件。 - 優勢:
- 文件大小控制:單個 AOF 文件不會無限增長,便于管理。
- 重寫效率提升:增量式重寫替代全量重寫,減少重寫時的阻塞時間。
- 故障恢復加速:只需加載損壞的片段,而不是整個 AOF 文件,提高恢復速度。
- 特性:將 AOF 文件分割為多個片段(如
-
Redis 8.0 布隆過濾器(原生支持)
- 特性:Redis 8.0 計劃原生支持布隆過濾器,無需通過 Redis Modules。
- 優勢:更低的部署和使用成本,更好的性能和穩定性。
- 與模塊版對比:
參數 模塊版(RedisBloom) 原生實現(Redis 8.0) 內存占用 可變 固定預分配 誤判率 可配置 默認 0.1%(可能可配置) 集群支持 需同步 自動同步
七、思維導圖框架
八、開源項目設計(todo)
項目名:Redis-Solution-Kit
目錄結構:
├── distributed_lock
│ ├── redlock.py # Redlock實現
│ └── test_deadlock.py
├── cache_consistency
│ ├── double_delete.py # 雙刪策略
│ └── binlog_sync.py # 基于MySQL binlog同步
├── bloom_filter
│ ├── redis8_native.py # 原生布隆過濾器
│ └── scaling_bf.py # 動態擴容實現
└── disaster_recovery├── avalanche.py # 雪崩防護└── penetration.py # 穿透防護