Redis如何解決熱Key問題

目錄

    • **如何解決 Redis 的熱 Key(Hot Key)問題?**
      • **解決方案**
    • **1. 使用多級緩存**
      • **方案**
    • **2. 進行 Key 預分片(Key Sharding)**
      • **方案**
    • **3. 使用 Redis 復制機制(主從復制或集群)**
      • **方案**
    • **4. 采用批量 Key 輪換(Consistent Hash)**
      • **方案**
    • **5. 采用異步更新策略**
      • **方案**
    • **6. 限流和降級**
      • **方案**
    • **7. 結合 MQ 做異步削峰**
      • **方案**
    • **總結**
      • **面試標準回答**

如何解決 Redis 的熱 Key(Hot Key)問題?

熱 Key(Hot Key)是指訪問頻率極高的鍵,在高并發場景下可能會造成:

  1. 單個 Redis 節點壓力過大(大量請求命中一個 Key)。
  2. CPU 過載,響應變慢(甚至影響整個 Redis 集群)。
  3. 緩存失效后大量請求直接打到數據庫,導致數據庫崩潰(緩存擊穿)。

解決方案

針對不同場景,解決方案主要包括 “分散請求”“降低 Redis 負載” 兩個方向。


1. 使用多級緩存

核心思路:在 Redis 之前增加一級緩存,減少 Redis 訪問壓力。

方案

  1. 本地緩存(L1 Cache)

    • 在應用服務器上存儲熱點數據(如 Guava Cache, Caffeine)。
    • 優點:訪問速度更快,避免 Redis 過載。
    • 缺點:如果多個應用服務器同時緩存相同 Key,可能會有數據一致性問題。
  2. CDN 緩存(L0 Cache)

    • 適用于靜態資源或熱點數據(如商品詳情頁)。
    • 優點:減少數據庫、Redis 訪問壓力。

示例:使用 Guava 本地緩存

LoadingCache<String, String> localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterWrite(10, TimeUnit.MINUTES).build(new CacheLoader<String, String>() {public String load(String key) throws Exception {return redis.get(key); // 從 Redis 取數據}});// 讀取緩存
String value = localCache.get("hot_key");

2. 進行 Key 預分片(Key Sharding)

核心思路將單個熱 Key 拆分成多個 Key,讓不同的 Redis 節點存儲不同的副本,從而分散壓力。

方案

  • 存儲時:寫入多個不同的 Key,例如 hot_key_1, hot_key_2, hot_key_3
  • 查詢時:隨機訪問 hot_key_n,或使用一致性 Hash 計算 Key。

示例

// 寫入時分片
for (int i = 0; i < 3; i++) {redis.set("hot_key_" + i, value);
}// 讀取時隨機選一個
String key = "hot_key_" + (rand() % 3);
String value = redis.get(key);

適用場景

  • 高并發計數(如熱點直播間點贊)。
  • 高 QPS 的熱點數據(如秒殺商品庫存)。

3. 使用 Redis 復制機制(主從復制或集群)

核心思路通過 Redis 讀寫分離,多個節點分擔讀取壓力

方案

  • 主節點(Master)處理寫請求,多個從節點(Slave)處理讀請求
  • 結合 客戶端負載均衡,將 get 請求分發到不同的從節點。

示例(配置 Redis 讀從庫)

slaveof master_ip master_port

適用場景

  • 適用于 Redis 集群模式,大規模熱 Key 分布式緩存場景。

4. 采用批量 Key 輪換(Consistent Hash)

核心思路通過一致性哈希(Consistent Hashing)降低熱 Key 訪問壓力

方案

  1. 將一個 Key 拆分成多個時間窗口 Key
  2. 訪問時隨機選擇一個 Key,確保熱點數據均勻分布。
  3. 定期清理過時的 Key

示例

String key = "hot_key:" + (time(nullptr) % 5); // 輪換 Key
redis.set(key, value);

適用場景

  • 防止緩存擊穿(熱點數據定期輪換)。
  • 適用于短周期熱點數據(如秒殺、短時間訪問高峰)。

5. 采用異步更新策略

核心思路緩存失效后,先返回舊值,同時異步更新緩存,避免大量請求瞬間打到數據庫。

方案

  • 采用 雙緩存(Double Cache) 機制:
    1. 用戶查詢時返回舊緩存
    2. 后臺異步更新新數據

示例

String value = redis.get("hot_key");
if (value == null) {value = localCache.get("hot_key");  // 先從本地緩存讀取asyncUpdateRedis(); // 后臺線程更新 Redis
}
return value;

適用場景

  • 避免緩存擊穿問題(如商品價格、秒殺庫存)。

6. 限流和降級

核心思路:如果 Redis 無法支撐高并發請求,可以限制請求頻率,或者直接返回默認值

方案

  1. 限流(使用令牌桶 / 滑動窗口)

    • 限制相同 Key 的訪問頻率。
    • 避免短時間內 Redis 負載過高。
  2. 降級(請求超時時返回默認值)

    • 如果 Redis 繁忙,則返回本地默認值,減少 Redis 壓力。

示例(限流)

local key = KEYS[1]
local limit = tonumber(ARGV[1])
local current = redis.call('incr', key)if current == 1 thenredis.call('expire', key, 60) -- 60s 過期
endif current > limit thenreturn 0 -- 限流失敗
end
return 1

適用場景

  • API 訪問頻率控制(如搶購、直播點贊)。

7. 結合 MQ 做異步削峰

核心思路將高并發請求寫入消息隊列(如 Kafka / RabbitMQ),異步處理,降低 Redis 訪問壓力。

方案

  1. 將請求寫入 Kafka,批量處理。
  2. 后端定期刷新緩存,避免 Redis 承擔高并發壓力。

示例

// 生產者:將查詢請求寫入 MQ
kafkaProducer.send("hotKeyTopic", "hot_key");// 消費者:異步更新緩存
kafkaConsumer.onMessage(msg -> {String value = queryDatabase("hot_key");redis.set("hot_key", value);
});

適用場景

  • 適用于秒殺、短時熱點數據(如搶購、熱點新聞)。

總結

方法核心思路適用場景
多級緩存L1(本地緩存)+ L2(Redis 緩存)低延遲讀取,熱點數據
Key 預分片拆分熱 Key,分散訪問壓力高并發計數(直播點贊、熱點商品)
主從復制讀寫分離,提高讀性能Redis 集群,讀多寫少
輪換 Key使用 Hash 輪轉 Key秒殺庫存、短時間熱點數據
異步更新先返回舊緩存,后臺更新價格、秒殺商品庫存
限流和降級限制訪問頻率,防止 Redis 過載高 QPS 接口,秒殺搶購
MQ 削峰通過 Kafka / RabbitMQ 處理請求高并發訂單、熱點數據

面試標準回答

解決 Redis 熱 Key 主要有 3 類方法

  1. 減少 Redis 訪問壓力(本地緩存、CDN、讀寫分離)。
  2. 分散 Key 訪問(Key 預分片、輪換 Key)。
  3. 限制并發(限流、降級、MQ 削峰)。
    最推薦的方案是:本地緩存 + Key 預分片 + Redis 讀寫分離,結合業務需求選擇最優方案!🚀

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

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

相關文章

云計算架構學習之Ansible-playbook實戰、Ansible-流程控制、Ansible-字典循環-roles角色

一、Ansible-playbook實戰 1.Ansible-playbook安裝軟件 bash #編寫yml [rootansible ansible]# cat wget.yml - hosts: backup tasks: - name: Install wget yum: name: wget state: present #檢查playbook的語法 [rootansible ansible]…

【Web前端開發精品課 HTML CSS JavaScript基礎教程】第二十四章課后題答案

文章目錄 問題1&#xff1a;問題2&#xff1a;問題3&#xff1a; 問題1&#xff1a; 在HTML中嵌入JavaScript&#xff0c;應該使用的標簽是&#xff08; &#xff09;。 選項&#xff1a; A. <style></style> B. <script></script> C. <js><…

用python進行二分法查找(python實例三十)

目錄 1.認識Python 2.環境與工具 2.1 python環境 2.2 Visual Studio Code編譯 3.代碼示例 4.運行結果 1.認識Python Python 是一個高層次的結合了解釋性、編譯性、互動性和面向對象的腳本語言。 Python 的設計具有很強的可讀性&#xff0c;相比其他語言經常使用英文關鍵…

Qt學習(五)自定義對話框,多窗口開發---添加設計師類, MDI多窗口開發

一 對話框 實現功能&#xff1a;打開文件&#xff0c;選擇目錄&#xff0c;保存文件&#xff0c;選擇顏色&#xff0c;選擇字體&#xff0c;輸入信息&#xff0c; 消息提示框 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE na…

用 Python 實現簡易的 Web 爬蟲:從入門到實戰

一、引言 在信息爆炸的時代,網絡上蘊含著海量的數據。如果我們想要獲取特定的信息,手動從網頁上復制粘貼顯然效率極低。這時,Web 爬蟲就派上了用場。Web 爬蟲是一種自動獲取網頁內容的程序,它可以模擬人類在瀏覽器中的操作,快速地抓取網頁上的數據。本文將帶領大家使用 Py…

機器視覺檢測中,2D面陣相機和線掃相機的區別

2D面陣相機和線掃相機是工業視覺系統中常用的兩種相機類型&#xff0c;各有其特點和應用場景。 2D面陣相機 特點&#xff1a; 成像方式&#xff1a;通過二維傳感器一次性捕捉整個場景的圖像。 分辨率&#xff1a;分辨率由傳感器的像素數決定&#xff0c;常見的有百萬像素到幾千…

ECharts極簡入門

ECharts 是一個基于 JavaScript的開源可視化圖表庫&#xff0c;廣泛應用于數據可視化的場景中&#xff0c;支持多種圖表類型&#xff0c;如柱狀圖、折線圖、餅圖、散點圖、雷達圖等&#xff0c;且具有強大的自定義功能。 1. ECharts 基本使用 首先需要引入 ECharts 庫&#xf…

go設置鏡像代理

前言 在 Go 開發中&#xff0c;如果直接從官方源&#xff08;https://proxy.golang.org&#xff09;下載依賴包速度較慢&#xff0c;可以通過設置 鏡像代理 來加速依賴包的下載。以下是增加 Go 鏡像代理的詳細方法&#xff1a; 一、設置 Go 鏡像代理 1. 使用環境變量設置代理…

Linux部署DeepSeek r1 模型訓練

之前寫過一篇windows下部署deepseekR1的文章&#xff0c;有小伙伴反饋提供一篇linux下部署DeepSeek r1 模型訓練教程&#xff0c;在 Linux 環境下&#xff0c;我找了足夠的相關資料&#xff0c;花費了一些時間&#xff0c;我成功部署了 DeepSeek R1 模型訓練任務&#xff0c;結…

AI Agent架構深度解析:從ReAct到AutoGPT,自主智能體的技術演進與工程實踐

前言 覺得不錯就點個贊吧&#xff01;。 一、AI Agent技術架構演進圖譜 &#xff08;配圖&#xff1a;AI Agent架構演進時間軸&#xff0c;標注關鍵技術節點&#xff09; 1.1 三代架構對比分析 架構類型代表系統核心特征局限性反應式DeepBlue預置規則庫無長期記憶認知式Wats…

嵌入式經常用到串口,如何判斷串口數據接收完成?

說起通信&#xff0c;首先想到的肯定是串口&#xff0c;日常中232和485的使用比比皆是&#xff0c;數據的發送、接收是串口通信最基礎的內容。這篇文章主要討論串口接收數據的斷幀操作。 空閑中斷斷幀 一些mcu&#xff08;如&#xff1a;stm32f103&#xff09;在出廠時就已經在…

HTML/CSS中并集選擇器

1.作用:選中多個選擇器對應的元素,又稱:分組選擇器 所謂并集就是或者的含義. 2.語法:選擇器1,選擇器2,選擇器3,......選擇器n 多個選擇器通過,連接,此處,的含義就是:或. .rich,.beauty{color: blue;} 3.注意事項 1.并集選擇器,我們一般豎著寫 2.任何形式的選擇器,都可以作為并…

解鎖機器學習核心算法 | 隨機森林算法:機器學習的超強武器

一、引言 在機器學習的廣闊領域中&#xff0c;算法的選擇猶如為一場冒險挑選趁手的武器&#xff0c;至關重要。面對海量的數據和復雜的任務&#xff0c;合適的算法能夠化繁為簡&#xff0c;精準地挖掘出數據背后隱藏的模式與價值。機器學習領域有十大核心算法&#xff0c;而隨…

Shapr3D在ipad上無法識別鼠標點擊問題

此問題我去過長沙Apple官方直營店咨詢過此問題&#xff0c;官方直營店也不知道解決方案&#xff0c;遂在此提醒長沙Apple官方線下直營店的所有店員。 問題描述 1.不知道為什么在買了Magic Keyboard后還是無法識別單擊觸控板&#xff0c;遂為了解決這個問題我特意從江西跑到長沙…

【架構】微內核架構(Microkernel Architecture)

微內核架構(Microkernel Architecture) 核心思想 微內核架構(又稱插件式架構)通過最小化核心系統,將可擴展功能以插件模塊形式動態加載,實現高內聚低耦合。其核心設計原則: 核心最小化:僅封裝基礎通用能力(如插件管理、通信機制、安全校驗)功能插件化:所有業務功能…

AI 編程助手 cursor的系統提示詞 prompt

# Role 你是一名極其優秀具有10年經驗的產品經理和精通java編程語言的架構師。與你交流的用戶是不懂代碼的初中生&#xff0c;不善于表達產品和代碼需求。你的工作對用戶來說非常重要&#xff0c;完成后將獲得10000美元獎勵。 # Goal 你的目標是幫助用戶以他容易理解的…

javaSE學習筆記21-線程(thread)-鎖(synchronized 與Lock)

死鎖 多個線程各自占有一些共享資源&#xff0c;并且互相等待其他線程占有的資源才能運行&#xff0c;而導致兩個或者多個線程 都在等待對方釋放資源&#xff0c;都停止執行的情形&#xff0c;某一個同步塊同時擁有“兩個以上對象的鎖”時&#xff0c;就可能 會發生“死鎖&quo…

uni-app發起網絡請求的三種方式

uni.request(OBJECT) 發起網絡請求 具體參數可查看官方文檔uni-app data:請求的參數; header&#xff1a;設置請求的 header&#xff0c;header 中不能設置 Referer&#xff1b; method&#xff1a;請求方法&#xff1b; timeout&#xff1a;超時時間&#xff0c;單位 ms&a…

SpringBoot速成概括

視頻&#xff1a;黑馬程序員SpringBoot3Vue3全套視頻教程&#xff0c;springbootvue企業級全棧開發從基礎、實戰到面試一套通關_嗶哩嗶哩_bilibili 圖示&#xff1a;

GoFound 與 MySQL 集成優化方案

GoFound 與 MySQL 集成優化方案 1. 明確需求 文章信息存儲在 MySQL 數據庫中。使用 GoFound 實現全文搜索功能。搜索時&#xff0c;先從 GoFound 中獲取匹配的文章 ID&#xff0c;然后從 MySQL 中查詢完整的文章信息。 2. 優化思路 數據同步&#xff1a;將 MySQL 中的文章數…