【Redis 進階】Redis 典型應用 —— 緩存(cache)

一、什么是緩存

緩存(cache)是計算機中的一個經典的概念,在很多場景中都會涉及到。核心思路就是把一些常用的數據放到觸手可及(訪問速度更快)的地方,方便隨時讀取。

舉例:我需要去高鐵站坐高鐵,坐高鐵是需要反復刷身份證的(進入高鐵站、檢票、上車、乘車過程中、出站...)。正常來說,我的身份證是放在行李箱里的(行李箱的存儲空間大,足夠能裝),但是每次刷身份證都需要開一次行李箱找身份證就非常不方便。因此我就可以把身份證先放到口袋里,雖然口袋空間小,但是訪問速度比行李箱快很多。這樣的話每次刷身份證我只需要從口袋里掏身份證就行了,就不必打開行李箱了。此時 “口袋” 就是 “皮箱” 的緩存,使用緩存能夠大大提高訪問效率。

這里所說的 “觸手可及” 是個相對的概念。對于硬件的訪問速度來說,通常情況下:CPU 寄存器 > 內存 > 硬盤 > 網絡。那么硬盤相對于網絡來說是 “觸手可及的”,就可以使用硬盤作為網絡的緩存。內存相對于硬盤是 “觸手可及的”,就可以使用內存作為硬盤的緩存。CPU 寄存器相對于內存是 “觸手可及的”,就可以使用 CPU 寄存器作為內存的緩存。

對于計算機硬件來說,往往訪問速度越快的設備成本越高,存儲空間越小。緩存是更快,但是空間上往往是不足的,因此大部分的時候,緩存只放一些熱點數據(訪問頻繁的數據),就非常有用

關于 “二八定律”:20% 的熱點數據能夠應對 80% 的訪問場景。因此只需要把這少量的熱點數據緩存起來,就可以應對大多數場景,從而在整體上有明顯的性能提升。

二、使用?Redis 作為緩存

在一個網站中,經常會使用關系型數據庫(比如 MySQL)來存儲數據。關系型數據庫雖然功能強大,但是有一個很大的缺陷:性能不高(換而言之,進行一次查詢操作消耗的系統資源較多)。

為什么說關系型數據庫性能不高?

  1. 數據庫把數據存儲在硬盤上,硬盤的 IO 速度并不快,尤其是隨機訪問。
  2. 如果查詢不能命中索引,就需要進行表的遍歷,這就會大大增加硬盤 IO 次數。
  3. 關系型數據庫對于 SQL 的執行會做一系列的解析、校驗、優化工作。
  4. 如果是?些復雜查詢,比如聯合查詢,需要進行笛卡爾積操作,效率更是降低很多。

因此,如果訪問數據庫的并發量比較高,對于數據庫的壓力是很大的,很容易就會使數據庫服務器宕機。

為什么并發量高了就會宕機?

服務器每次處理一個請求,都是需要消耗一定的硬件資源的。所謂的硬件資源包括不限于 CPU、內存、硬盤、網絡帶寬... ... ?個服務器的硬件資源本身是有限的,一個請求消耗一份資源,請求多了自然把資源就耗盡了。后續的請求沒有資源可用,自然就無法正確處理,更嚴重的還會導致服務器程序的代碼出現崩潰。

如何讓數據庫能夠承擔更大的并發量呢?

核心思路主要是兩個:

  • 開源:引入更多的機器,部署更多的數據庫實例,構成數據庫集群(主從復制、分庫分表等...)。
  • 節流:引入緩存,使用其他的方式保存經常訪問的熱點數據,從而降低直接訪問數據庫的請求數量。

實際開發中,這兩種方案往往是會搭配使用的。

Redis 就是一個用來作為數據庫緩存的常見方案

Redis 訪問速度比 MySQL 快很多,或者說處理同?個訪問請求,Redis 消耗的系統資源比 MySQL 少很多,因此 Redis 能支持的并發量更大。

  • Redis 數據在內存中,訪問內存比硬盤快很多。
  • Redis 只是支持簡單的 key-value 存儲,不涉及復雜查詢的那么多限制規則。

  • 客戶端訪問業務服務器,發起查詢請求。
  • 業務服務器先查詢 Redis,看想要的數據是否在 Redis 中存在。
  1. 如果已經在 Redis 中存在了就直接返回,此時不必訪問 MySQL 了。
  2. 如果在 Redis 中不存在,再查詢 MySQL。

注意緩存是用來加快 “讀操作”?的速度的,如果是 “寫操作”,還是要老老實實寫數據庫,緩存并不能提高性能。

三、緩存的更新策略

到底哪些數據才是 “熱點數據”?呢?

1、定期生成

每隔一定的周期(比如一天 / 一周 / 一個月),對于訪問的數據頻次進行統計,挑選出訪問頻次最高的前 N% 的數據。

以搜索引擎為例:用戶在搜索引擎中會輸入一個 “查詢詞”,有些詞是屬于高頻的,大家都愛搜(鮮花、蛋糕、交友...),有些詞就屬于低頻的,大家很少搜。

搜索引擎的服務器會把哪個用戶在什么時間搜了什么詞,都通過日志的方式記錄的明明白白,然后每隔一段時間對這期間的搜索結果進行統計

上面這種做法實時性較低,對于一些突然情況應對的并不好。比如春節期間,“春晚”?這樣的詞就會成為非常高頻的詞,而平時則很少會有人搜索 “春晚”。

2、實時生成

先給緩存設定容量上限(可以通過 Redis 配置文件的?maxmemory?參數設定),接下來把用戶每次查詢:

  • 如果在 Redis 查到了,就直接返回。
  • 如果 Redis 中不存在,就從數據庫查,把查到的結果同時也寫入?Redis。(經過一段時間的 “動態平衡”,redis 中的 key 就逐漸成了熱點數據)

如果緩存已經滿了(達到上限),就觸發緩存淘汰策略,把?些 “相對不那么熱門”?的數據淘汰掉。按照上述過程持續一段時間之后 Redis 內部的數據自然就是 “熱門數據”?了。

通用的淘汰策略主要有以下幾種:

下列策略并非局限于 Redis,其他緩存也可以按這些策略展開。

  1. 把緩存中存在時間最久的(也就是先來的數據)淘汰掉。
  2. 記錄每個 key 的最近訪問時間,把最近訪問時間最?的 key 淘汰掉。
  3. 記錄每個 key 最近?段時間的訪問次數,把訪問次數最少的淘汰掉。
  4. 從所有的 key 中抽取幸運兒被隨機淘汰掉。

四、緩存預熱、緩存穿透、緩存雪崩和緩存擊穿

1、關于緩存預熱(Cache preheating)

(1)什么是緩存預熱

使用 Redis 作為 MySQL 的緩存的時候,當 Redis 剛剛啟動或者 Redis 大批 key 失效之后,此時由于 Redis 服務器是沒有什么緩存數據的,那么所有的請求就會打給 MySQL,MySQL 就可能直接被訪問到,從而造成較大的壓力。隨著時間的推移,redis 上的數據積累的越來越多,MySQL 承擔的壓力也就越來越小。因此就需要提前把熱點數據準備好,直接寫入到 Redis 中,使 Redis 可以盡快為 MySQL 撐起保護傘。

熱點數據可以基于之前介紹的統計的方式生成即可。這份熱點數據不一定非得那么 “準確”,只要能幫助 MySQL 抵擋大部分請求即可。隨著程序運行的推移,緩存的熱點數據會逐漸自動調整,來更適應當前情況。?

2、關于緩存穿透(Cache penetration)

(1)什么是緩存穿透

訪問的 key 在 Redis 和 數據庫中都不存在,此時這樣的 key 不會被放到緩存上,后續如果仍然在訪問該 key,依然會訪問到數據庫,這就會導致數據庫承擔的請求太多,壓力很大。這種情況稱為緩存穿透

(2)為什么會產生緩存穿透
  • 業務設計不合理。比如缺少必要的參數校驗環節,導致非法的 key 也被進行查詢了。
  • 開發 / 運維誤操作。不小新把部分數據從數據庫上誤刪了。
  • 黑客惡意攻擊。
(3)如何解決緩存穿透
  1. 針對要查詢的參數進行嚴格的合法性校驗,比如要查詢的 key 是用戶的手機號,那么就需要校驗當前 key 是否滿足?個合法的手機號的格式。
  2. 針對數據庫上也不存在的 key , 也存儲到 Redis 中,比如 value 就隨便設成?個 "",避免后續頻繁訪問數據庫。
  3. 使用布隆過濾器先判定 key 是否存在,再真正查詢。?

3、關于緩存雪崩(Cache avalanche)

(1)什么是緩存雪崩

短時間內大量的 key 在緩存上失效,導致數據庫壓力驟增,甚至直接宕機。本來 Redis 是 MySQL 的一個護盾,幫 MySQL 抵擋了很多外部的壓力。一旦護盾突然失效了,MySQL 自身承擔的壓力驟增,就可能直接崩潰。

(2)為什么會產生緩存雪崩

大規模 key 失效,其可能性主要有兩種:

  1. Redis 掛了。
  2. Redis 上的大量的 key 同時過期。
為什么會出現大量的 key 同時過期?

這種和可能是短時間內在 Redis 上緩存了大量的 key,并且設定了相同的過期時間。

(3)如何解決緩存雪崩
  • 部署高可用的 Redis 集群,并且完善監控報警體系。
  • 不給 key 設置過期時間或者設置過期時間的時候添加隨機時間因子。?

4、關于緩存擊穿(Cache breakdown)

(1)什么是緩存擊穿

此處把 breakdown 翻譯成 “擊穿”,我以為并非是?個好的選擇,容易和緩存穿透混淆,翻譯成 “癱瘓”?/?“崩潰”?也許更合適一些。

相當于緩存雪崩的特殊情況,針對熱點 key,突然過期了,導致大量的請求直接訪問到數據庫上,甚至引起數據庫宕機。

(2)如何解決緩存擊穿
  • 基于統計的方式發現熱點 key,并設置永不過期。
  • 進行必要的服務降級。例如訪問數據庫的時候使用分布式鎖,限制同時請求數據庫的并發數。

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

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

相關文章

RK3588 Ubuntu22.04 解決eth0未托管問題

在調試rk3588的Ubuntu的時候發現,網絡那里一直顯示eth0未托管,但是聯網功能又是正常的,猜測是某一個配置文件的問題修改如下:打開/etc/NetworkManager/NetworkManager.conf,將managed,修改成true即可然后重…

雷卯針對香橙派Orange Pi 3G-IoT-B開發板防雷防靜電方案

一、應用場景計算機、無線網絡服務器、游戲機、音樂播放器、高清視頻播放器、揚聲器、Android 設備、Scratch 編程平臺二、核心功能參數三、擴展接口詳情雷卯專心為您解決防雷防靜電的問題,有免費實驗室供檢測。開發板資料轉自深圳迅龍軟件。謝謝!

Science Robotics 豐田研究院提出通過示例引導RL的全身豐富接觸操作學習方法

人類表現出非凡的能力,可以利用末端執行器(手)的靈巧性、全身參與以及與環境的交互(例如支撐)來縱各種大小和形狀的物體。 人類靈活性的分類法包括精細和粗略的作技能。盡管前者(精細靈巧性)已在…

趣丸游戲招高級業務運維工程師

高級業務運維工程師趣丸游戲 廣州職位描述1、負責公司AI業務線運維工作,及時響應、分析、處理問題和故障,保證業務持續穩定; 2、負責基于分布式、微服務、容器云等復雜業務的全生命周期的穩定性保障; 3、參與設計運維平臺、工具、…

2025通用證書研究:方法論、崗位映射與四證對比

本文基于公開材料與典型招聘描述,對常見通用型或準入型證書做方法論級別的比較,不構成培訓或報考建議,也不涉及任何招生、返現、團購等信息。全文采用統一術語與可復用模板,以減少“經驗之爭”,便于不同背景的讀者獨立…

在WSL2-Ubuntu中安裝Anaconda、CUDA13.0、cuDNN9.12及PyTorch(含完整環境驗證)

WSL 搭建深度學習環境,流程基本上是一樣的,完整細節可參考我之前的博客: 在WSL2-Ubuntu中安裝CUDA12.8、cuDNN、Anaconda、Pytorch并驗證安裝_cuda 12.8 pytorch版本-CSDN博客 之所以記錄下來,是因為CUDA和cuDNN版本升級后&#x…

OpenFOAM中梯度場的復用(caching)和生命期管理

文章目錄OpenFOAM中梯度場的復用(caching)和生命期管理一、緩存機制的目標二、如何實現緩存(以 fvc::grad 為例)1. 使用 IOobject::AUTO_WRITE 和注冊名2. 示例:fvc::grad 的緩存實現(簡化邏輯)三、生命期管理是如何實…

【Hot100】貪心算法

系列文章目錄 【Hot100】二分查找 文章目錄系列文章目錄方法論Hot100 之貪心算法121. 買賣股票的最佳時機55. 跳躍游戲45. 跳躍游戲 II763. 劃分字母區間方法論 Hot100 之貪心算法 121. 買賣股票的最佳時機 121. 買賣股票的最佳時機:給定一個數組 prices &#…

電子電氣架構 --- 軟件項目復雜性的駕馭思路

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

SSE實時通信與前端聯調實戰

1.SSE 原理機制 sse 類似websocket,但是sse是單向的,不可逆的,只能服務端向客戶端發送數據流 2.解決跨域問題 Access to XMLHttpRequest at http://127.0.0.1:8090/sse/doChat from origin http://127.0.0.1:3000 has been blocked by CORS policy: Re…

從傳統到創新:用報表插件重塑數據分析平臺

一、傳統 BI 平臺面臨的挑戰 在當今數字化時代,數據已成為企業決策的重要依據。傳統的商業智能(BI)平臺在數據處理和分析方面發揮了重要作用,但隨著數據量的爆炸式增長和用戶需求的日益多樣化,其局限性也逐漸顯現。 …

MySQL--MySQL中的DECIMAL 與 Java中的BigDecimal

1. 為什么需要 DECIMAL在數據庫中,常見的數值類型有:INT、BIGINT → 整數,存儲容量有限。FLOAT、DOUBLE → 浮點數,存儲效率高,但存在精度丟失問題。DECIMAL(M, D) → 定點數,存儲精確值。例子:…

低空無人機系統關鍵技術與應用前景:SmartMediaKit視頻鏈路的基石價值

引言:低空經濟的新興格局 低空經濟作為“新質生產力”的代表,正在從政策驅動、技術突破和市場需求的共振中走向產業化。2023年,中國低空經濟的市場規模已超過 5000 億元人民幣,同比增長超過 30%。無人機(UAV&#xff…

在Windows系統上升級Node.js和npm

在Windows系統上升級Node.js和npm,我推薦以下幾種方法: 方法1:使用官網安裝包(最簡單) 訪問 nodejs.org 下載Windows安裝包(.msi文件) 運行安裝包,選擇"修復"或直接安裝新…

【Jetson】基于llama.cpp部署gpt-oss-20b(推理與GUI交互)

前言 本文在jetson設備上使用llama.cpp完成gpt-oss 20b的部署,包括后端推理和GUI的可視化交互。 使用的設備為orin nx 16g(super),這個顯存大小推理20b的模型完全沒有問題。 使用硬件如下,支持開啟super模式。&#…

Matplotlib 可視化大師系列(一):plt.plot() - 繪制折線圖的利刃

目錄Matplotlib 可視化大師系列博客總覽Matplotlib 可視化大師系列(一):plt.plot() - 繪制折線圖的利刃一、 plt.plot() 是什么?二、 函數原型與核心參數核心參數詳解三、 從入門到精通:代碼示例示例 1:最基…

第二階段Winfrom-8:特性和反射,加密和解密,單例模式

1_預處理指令 (1)源代碼指定了程序的定義,預處理指令(preprocessor directive)指示編譯器如何處理源代碼。例如,在某些情況下,我們希望編譯器能夠忽略一部分代碼,而在其他情況下&am…

【開題答辯全過程】以 微信小程序的醫院掛號預約系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人,語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

鴻蒙ArkUI 基礎篇-06-組件基礎語法-Column/Row/Text

目錄 掌握組件寫法,使用組件布局界面 ArkUI與組件 先布局再內容 DevEco Studio代碼實戰 預覽效果 總結 練習 掌握組件寫法,使用組件布局界面 ArkUI與組件 ArkUI(方舟開發框架):構建 鴻蒙 應用 界面 的框架 組件…

8.27 網格memo

lc329計算矩陣中最長遞增路徑長度嘗試從矩陣每個位置出發,int dfs() 往上下左右四個方向找嚴格遞增的路徑retmax(ret,dfs(x,y)1);return memo[i][j]ret;返回所有路徑里的最長長度 class Solution {public:int dx[4]{0,0,1,-1};int dy[4]{1,-1,0,0};int m,n;vector&l…