【Redis篇】數據庫架構演進中Redis緩存的技術必然性—高并發場景下穿透、擊穿、雪崩的體系化解決方案

💫《博主主頁》:
   🔎 CSDN主頁__奈斯DB
   🔎 IF Club社區主頁__奈斯、
🔥《擅長領域》:擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控;并對SQLserver、NoSQL(Redis)有了解
💖如果覺得文章對你有所幫助,歡迎點贊收藏加關注💖

在這里插入圖片描述
????作為DBA或運維在日常與Redis打交道時,往往更關注部署安裝🔧、Key清理🧹、內存回收💾、備份恢復🔄等這些運維層面的問題,也就是非業務相關的問題。但大家否深入思考過:
?為什么現代數據庫架構中需要引入Redis做緩存?
?不同的NoSQL在緩存場景下各有怎樣的特性?
?當高并發來臨時,緩存穿透、擊穿、雪崩這些問題究竟會對系統造成什么影響?
????博主在此之前也沒有考慮過這些問題(應該大部分DBA或者運維都沒有考慮過這些問題,因為引用緩存技術,以及緩存策略(穿透/擊穿/雪崩的防治)通常被視為研發的職責范疇),因為DBA或者運維更多的是關心NoSQL本身的穩定性保障,直到親身經歷了一次高并發場景下的緩存雪崩事故,才意識到意識到這些業務邏輯對運維人的重要性。
????那么今天這篇文章就從業務角度出發,一起來了解和學習一下互聯網數據庫架構演進中Redis緩存的技術必然性,以及其他NoSQL在緩存場景下的特點比較,并在高并發場景下緩存穿透、緩存擊穿、緩存雪崩的體系化解決方案。
????寫這篇文章的初衷是想讓不懂為什么加緩存技術的小伙伴們明白,此篇文章的內容來源于B站UP主“遇見狂神說”中的前部分視頻講解內容,博主在文章中對內容稍加潤色,并對流程圖重新構圖加以個人理解。那么正好也借此機會推薦給大家這個Redis好課,在B站上搜索“遇見狂神說”UP主,就可以搜索到他講的Redis課程,UP主是個大佬,Redis講的非常通透,最最最主要的是UP主是無償且免費的把Redis這套課程分享出來的(免費!香!),并且視頻中的相關講解UP主也愿意讓學習過的小伙伴進行整理和分享,免費是情誼,收費是本分,感謝大佬為愛發電💞,為我們帶來了如此寶貴的學習資源。


目錄

    • Redis介紹
    • NoSQL分類
    • 一、緩存穿透(Cache Penetration)
    • 二、緩存擊穿(Cache Breakdown)
    • 三、緩存雪崩(Cache Avalanche)


???
20世紀90年代:數據庫的單機時代:
????在互聯網發展初期,網站訪問量普遍較小,許多網站仍以靜態HTML頁面為主。由于用戶請求量有限,應用服務器和數據庫服務器的負載壓力并不大。因此,單臺關系型數據庫(如MySQL)足以滿足數據存儲和查詢的需求。這一階段的架構簡單直接,甚至數據庫服務和應用部署在同一臺機器上,無需復雜的分布式設計或性能優化。
????那么這一時期的Web應用主要呈現以下特點:

  • 靜態內容占絕對主導,動態請求占比很低
  • 單臺MySQL數據庫完全能夠滿足存儲和查詢需求
  • 應用服務器和數據庫服務器都承受著極小的壓力

????此時的典型架構如下:
在這里插入圖片描述

架構圖說明

Web服務器:

  1. 請求分發中心
    • 接收所有HTTP請求(GET/POST)
    • 區分靜態請求(.html/.jpg)和動態請求(.php/.asp)
    • 靜態請求直接返回文件,動態請求轉發給后端處理
  2. 基礎服務支撐
    • 單進程/單線程模型(早期Apache的prefork模式)
    • 不支持keep-alive(每個請求新建TCP連接)
    • 典型配置:Pentium 100MHz CPU + 32MB內存
      ???
      ???

MySQL 數據庫層:

  • 數據庫用于持久化存儲應用的核心數據,例如用戶、訂單、商品等結構化數據。
  • 數據庫層需要處理事務、并發訪問、數據一致性等問題。
  • 數據庫也提供了 ACID 特性,保證數據的可靠性和完整性。

???

21世紀00年代,大數據時代:
????隨著互聯網的發展和數據量的不斷增長,傳統單臺數據庫在處理海量數據時逐漸暴露出性能瓶頸。以下是一些常見的問題:

  1. 存儲瓶頸: 隨著數據的激增,單臺服務器的磁盤空間逐漸不足。單一磁盤和服務器無法滿足日益增長的數據存儲需求。
  2. 單表數據量過大: 例如,當一張表的數據量達到幾百萬條時,查詢操作將會消耗大量內存,導致性能下降,且在沒有合理優化的情況下,查詢速度會急劇下降。
  3. 高并發訪問: 隨著訪問量增加,單臺數據庫服務器可能無法承受來自多個用戶的并發請求。每秒鐘的查詢次數(QPS)會造成數據庫的負載過重,導致響應時間延遲。
  4. 查詢效率低: 當大量用戶頻繁查詢相同的數據時,數據庫不斷重復執行相同的查詢操作,使得查詢效率下降,嚴重時可能會導致數據庫崩潰。

????在大數據和高并發的背景下,提升查詢效率成為了一個至關重要的課題。傳統的數據庫雖然是存儲數據的核心技術,但隨著數據量的增加,單臺數據庫在高并發場景下的響應時間會急劇上升,甚至導致系統性能瓶頸。為了應對這些挑戰,技術進步經歷了幾個階段,從最初的數據庫結構和索引優化,到文件緩存和磁盤I/O優化,再到如今的緩存技術,特別是Redis等內存緩存技術的應用。
????首先,數據庫通過優化表結構和索引來提升查詢效率。這些優化可以減少掃描全表的操作,快速定位所需數據,進而提升查詢速度。然而,隨著數據量的劇增,這種優化方式逐漸顯得力不從心,尤其是在面對高并發請求時,數據庫的負載急劇增加,查詢性能出現瓶頸。
????隨著技術的發展,文件緩存和磁盤I/O優化成為了重要的提升手段。特別是SSD(固態硬盤)的普及,使得磁盤I/O性能得到了顯著提升。文件緩存通過將部分數據存儲在磁盤上,以減少數據庫的頻繁讀寫,從而減輕數據庫的壓力。然而,磁盤I/O的速度畢竟不如內存,因此,文件緩存雖然有效,但也有限。
????既然磁盤I/O的速度畢竟不如內存,那么能不能將數據庫中的數據緩存到內存中用來提高查詢效率呢?答案是當然可以,舉一個例子💫,在一般情況下網站80%的情況都是在讀,高并發的去查詢單臺數據庫的話就會增加查詢響應時間,比如張三查詢了1號商品,李四也同樣去查詢了一樣的1號商品,都是同樣的查詢操作,每次都要去查詢數據庫的話讓壓力本來就很大的數據庫更加雪上加霜,因此能不能讓多次不變的1號商品做成緩存,讓李四或者其他同樣想查詢1號商品的用戶直接可以在緩存中調用1號商品,而避免再次在數據庫中查詢呢?為了解決這一問題,緩存技術孕育而生,緩存技術是解決上述問題的關鍵技術之一。
????那么,緩存技術的核心目標是:減少對數據庫的訪問,避免頻繁執行重復的查詢操作。緩存通過將熱點數據保存在內存中,首先檢查緩存中是否有該數據,若有,則直接從緩存中讀取,避免了對數據庫的多次查詢。這不僅提升了響應速度,還顯著降低了數據庫的壓力,尤其在高并發的場景下,緩存能夠有效減輕數據庫的負擔,提升系統的整體性能。
????其中,Redis作為一種高效的內存鍵值數據庫,成為了最常用的緩存解決方案。它以其超低的延遲和高效的讀寫性能,尤其適用于需要處理大量并發請求的應用場景。例如,電商平臺、社交媒體等高訪問量的應用,通過將熱點數據存儲在Redis緩存中,避免頻繁訪問數據庫,從而提升系統性能。緩存不僅減少了數據庫的壓力,還改善了用戶的體驗,尤其是在響應速度上。

那么總結一下緩存的作用:

  • 提高查詢效率: 緩存將高頻訪問的數據存儲在內存中,避免每次都去查詢數據庫,極大地提高了響應速度。
  • 減少數據庫負載: 通過緩存,數據庫的查詢壓力得以減少,尤其是在高并發的情況下,緩存能夠有效地減輕數據庫的負擔。
  • 提升用戶體驗: 減少查詢延遲,提升用戶對系統的響應速度和體驗。
    ???

在總結一下緩存的工作原理:
????緩存將數據存儲在快速訪問的存儲介質(如內存)中,每當用戶發起查詢時,系統首先檢查緩存中是否有該數據。如果數據存在,就直接從緩存中讀取,避免了對數據庫的多次訪問。這種機制不僅加快了查詢速度,也大幅降低了數據庫的壓力。

????不過,緩存技術并不是萬能的,它主要用于加速對高頻訪問數據的讀取,而對于大多數長期存儲的數據,傳統的關系型數據庫依然不可替代。因此,緩存技術往往與數據庫的讀寫分離技術結合使用,以進一步優化系統性能。通過ProxySQL等工具,可以實現數據庫的讀寫分離,將寫操作集中在主數據庫上,而將讀操作分散到多個從數據庫上,這樣可以有效提高系統的并發處理能力。
????從最初的數據庫結構優化,再到文件緩存和磁盤I/O優化,再到緩存技術與傳統關系型數據庫的結合(發展過程:優化數據結構和索引---->文件緩存(磁盤IO性能的提升,比如SSD全閃盤)---->然后才到緩存技術,也就是NoSQL),整個技術演變使得高并發場景下的性能瓶頸得到了有效解決。Redis與傳統關系型數據庫的結合(NoSQL+RDBMS技術),形成了一個高效的協作機制:Redis負責緩存高頻訪問的數據,而數據庫則存儲長期數據。兩者協同工作,使得系統能夠在面對大量請求時保持高效運行。
在這里插入圖片描述

架構圖說明

Redis 緩存層:緩存層不僅僅可以是Redis,也可以是Memcached(緩存,內存數據庫)。不僅僅NoSQL數據庫可以做緩存,其實只要帶有緩存技術的都可以在緩存層。

  • 緩存存儲:Redis 用于存儲高頻查詢的數據,例如用戶信息、熱門商品、常見查詢結果等。
  • 緩存策略:采用合適的緩存過期策略(TTL,Time-To-Live)來確保緩存數據不會過期。可以使用 LRU(Least Recently Used) 策略來避免緩存溢出。
  • 異步更新:通常,緩存的數據會有一定的過期時間,過期后緩存失效。數據庫中的數據變化時,可以觸發緩存的更新(例如,更新操作后刪除對應的緩存)。
    ???
    ???

MySQL 數據庫層:

  • 數據庫用于持久化存儲應用的核心數據,例如用戶、訂單、商品等結構化數據。
  • 數據庫層需要處理事務、并發訪問、數據一致性等問題。
  • 數據庫也提供了 ACID 特性,保證數據的可靠性和完整性。

???
21世紀10年代:多元數據時代
????在2010至2020年間,世界經歷了巨大的變化,尤其是在信息技術和互聯網的飛速發展下,出現了許多以前未曾存在的數據類型。例如,互聯網中的地圖定位信息、音樂視頻信息、新聞熱榜信息等,這些信息不再僅僅是文本數據,而是變得更加多元化,涵蓋了圖片、音頻、視頻、地理位置等多種數據形式。
????隨著這些多元數據的涌現,傳統的關系型數據庫,尤其是MySQL,在存儲大文件、圖片等信息時面臨著巨大的挑戰。特別是在查詢時,MySQL的效率顯著降低,數據庫的壓力急劇上升。原因在于,單一的MySQL數據庫已無法滿足存儲這些復雜、多元化數據的需求。因此,必須研發新的數據庫類型來應對這些變化。例如,專門用于存儲定位信息的數據庫、用于存儲大文件的數據庫,或是圖數據庫,專門用于存儲圖片等數據。
????此外,隨著互聯網的普及,用戶的個人信息、社交網絡、地理位置、音樂視頻、以及用戶自己產生的數據(如日志等)都在爆發式增長。與傳統的行列數據存儲方式不同,這些數據往往呈現出無序、動態變化的特點。例如,社交網絡和地理位置數據是一個動態發展的圖譜,新聞熱榜則需要實時更新。這些數據不適合傳統的關系型數據庫,以表格中的行或列來存儲。
????為了解決這些問題,技術發展引入了NoSQL技術,提供了更加靈活和高效的方式來處理這類動態、無序的數據。NoSQL數據庫能夠更好地適應這些數據的存儲需求,其橫向擴展性使得存儲和處理這些數據變得更加可行。
在這里插入圖片描述

架構圖說明

API網關:
???統一接入層,負責協議轉換、限流鑒權等,典型技術:Kong/Nginx
???
???

統一數據服務層UDSL:
???Unified Data Service Layer, UDSL,是一種用于整合和管理企業內部各種數據源的中間層
???
???

數據存儲層(核心組件):

  1. MySQL集群:
    • 分庫分表:用戶訂單按user_id哈希分片
    • GTID復制:全局事務標識保證主從一致性
    • 典型場景:銀行交易、庫存管理等ACID場景
  2. MongoDB分片集群:
    • 自動分片:基于shard key自動平衡數據
    • 文檔版本控制:MVCC并發控制
    • 典型場景:CMS系統、產品目錄
  3. Neo4j集群:
    • 原生圖存儲:免索引鄰接設計
    • Cypher查詢:聲明式圖查詢語言
    • 典型場景:社交關系、推薦系統
  4. InfluxDB集群:
    • 時間分片:按時間范圍自動分區
    • 連續查詢:實時聚合時序數據
    • 典型場景:IoT設備監控、應用指標
  5. Redis生態圈:
    • RedisJSON:支持JSON文檔操作
    • RedisGraph:圖數據庫功能
    • 典型場景:會話緩存、實時排行榜
      ???
      ???

數據湖:

  • 數據集成:通過各數據庫的變更捕獲機制(如MySQL binlog)集中原始數據
  • 典型技術:Apache Kafka + Delta Lake
  • 用途:離線分析、機器學習訓練

???

那么互聯網風云激蕩的這些年的架構變化到這里就算簡單介紹完成啦,下面開始了解一下Redis和NoSQL的分類

???
???

Redis介紹

????Redis(Remote Dictionary Server,即遠程字典服務),簡稱Redis。是一個開源的使用ANSI C語言編寫、支持網絡、可基于內存亦可持久化的日志型、Key-Value數據庫,并提供多種語言的API, 并且免費和開源!
????redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎上實現了master-slave(主從)同步。
????Redis 是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關系數據庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。
????Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。這使得Redis可執行單層樹復制。存盤可以有意無意的對數據進行寫操作。由于完全實現了發布/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道并接收主服務器完整的消息發布記錄。同步對讀取操作的可擴展性和數據冗余很有幫助。
????redis的官網地址,非常好記,是redis.io。(域名后綴io屬于國家域名,是british Indian Ocean territory,即英屬印度洋領地),Vmware在資助著redis項目的開發和維護。
????從2010年3月15日起,Redis的開發工作由VMware主持。從2013年5月開始,Redis的開發由Pivotal贊助。
????并且Redis推薦在Linux上搭建,不推薦在windows上搭建。

Redis性能方面的表現:
????下面是官方的bench-mark數據:
????????????測試完成了50個并發執行100000個請求。
????????????設置和獲取的值是一個256字節字符串。
????????????Linux box是運行Linux 2.6,這是X3320 Xeon 2.5 ghz。
????????????文本執行使用loopback接口(127.0.0.1)。
????結果: 讀的速度是110000次/s,寫的速度是81000次/s。
???
???
Redis的特性:

特性描述
內存存儲Redis 是內存數據庫,所有數據存儲在內存中,提供非常高的讀寫性能。
數據結構豐富支持多種數據結構:String、List、Set、Sorted Set、Hash、Bitmap、HyperLogLog、Geospatial。
高性能提供低延遲(微秒級別)和高吞吐量,適合高并發、高吞吐量應用場景。
持久化機制提供 RDB 快照和 AOF 日志持久化方式,確保數據持久性。可配置混合持久化模式。
高可用性通過 Redis Sentinel 提供自動故障轉移和高可用性。
分布式支持支持 Redis Cluster,提供自動分片和水平擴展。
事務支持支持事務,通過 MULTI、EXEC、WATCH實現命令的原子執行。
Lua 腳本支持支持在服務器端執行 Lua 腳本,實現原子操作,減少客戶端與服務器的交互。
發布/訂閱模式支持 Pub/Sub 模式,允許客戶端訂閱頻道并實時接收消息。
輕量級和易部署Redis 非常輕量,易于啟動和部署,支持單機及分布式部署。
內存管理策略提供 LRU、LFU 等內存淘汰策略,確保有效利用內存資源。
強一致性保證Redis 提供強一致性,支持復制和故障轉移機制。
客戶端支持支持多種編程語言的客戶端,包括 Java、Python、Go、Node.js、C、C++、PHP、Ruby 等。
應用場景廣泛用于緩存、消息隊列、排行榜、實時數據分析、會話存儲等多種場景。

???

NoSQL分類

什么是NoSQL:
????NoSQL = Not only SQL(不僅僅是SQL),泛指非關系型數據庫。也就是存儲新時代中的多元化數據。比如專門儲存定位信息的數據庫,專門存儲大文件的數據庫,專門存儲圖片的圖關系數據庫,等等等。
???
???

NoSQL的特點:

  1. 方便擴展,數據之間沒有關系,不需要過多的操作就可以橫向擴展。
  2. 大數據量高性能。官方測試Redis一秒寫8萬次,讀取11萬次。NoSQL的緩存記錄級是一種細粒度的緩存,性能會比較高
  3. 數據類型是多樣型的。對于關系型數據庫需要事先設計數據的表結構(現實中很少有人可以通過三大范式把數據庫設計的很好),對于NoSQL而言不需要事先設計數據庫,隨取隨用。
    ???
    ???

RDBMS關系型數據庫和NoSQL非關系型數據庫的區別:

關系型數據庫非關系型數據庫
結構化數據不僅僅是數據。非結構化數據,多元化數據結構
有特定的SQL語句沒有固定的查詢語句
數據和關系都存在單獨的表中(row行、column列)鍵值對存儲,列存儲,文檔存儲,圖形數據庫(社交關系)
數據定義語言(DML、DDL、DQL、DCL、TCL)
嚴格的一致性(遵循ACID特性)最終一致性
基礎的事務
CAP定理和BASE(異地多活、)
高性能、高可用、高擴展性高性能、高可用、高擴展性

???
???
NoSQL的四大分類:

  1. 內存鍵值存儲(Key-value stores):redis、memcached、Tair、Voldemort、Oracle BDB
  2. 文檔存儲(Document stores):mongoDB、conthDB
  3. 列存儲數據庫:Redshift、BigQuery、Snowflake、HBase、分布式文件系統。注意:關系型數據庫大多以行存儲
  4. 圖關系數據庫(Graph DBMS):Neo4j、infoGrdid、Infinite Graph。注意:圖關系數據庫存的不是圖形,而是存放圖關系的。比如:朋友圈社交網絡、廣告推薦等
分類舉例典型應用場景數據模型優點缺點
內存鍵值存儲(Key-value stores)redis、memcached、Tair、Voldemort、Oracle BDB內容緩存,主要用于處理大量數據的高訪問負載,也用于一些日志系統等等。Key 指向Value 的鍵值對,通常用hash table來實現。查找速度快數據無結構化,通常只被當作字符串或者二進制數據
文檔存儲(Document stores)mongoDB、conthDBWeb應用(與Key-Value類似,Value是結構化的,不同的是數據庫能夠了解Value的內容)Key-Value對應的鍵值對,Value為結構化數據數據結構要求不嚴格,表結構可變,不需要像關系型數據庫一樣需要預先定義表結構查詢性能不高,而且缺乏統一的查詢語法。
列存儲數據庫Redshift、BigQuery、Snowflake、HBase、分布式文件系統分布式的文件系統以列簇式存儲,將同一列數據存在一起查找速度快,可擴展性強,更容易進行分布式擴展功能相對局限
圖關系數據庫(Graph DBMS)Neo4J、InfoGrid、Infinite Graph社交網絡、推薦系統等。專注于構建關系圖譜圖結構利用圖結構相關算法。比如最短路徑尋址,N度關系查找等很多時候需要對整個圖做計算才能得出需要的信息,而且這種結構不太好做分布式的集群方案

???
????互聯網架構演變 + Redis初探 + NoSQL分類介紹的講解到這里就算完成了!相信看完的小伙伴們對緩存技術的理解已經煥然一新了?。不過一個人的精力畢竟是有限的🕶?,文章中可能有些細節沒覆蓋全面,歡迎各位大佬評論區拍磚補充 💬,提出改進意見。
????各位看官可以休息一下,摸魚10分鐘🕒…
????下一站高能預警 🚨: 直擊高并發三大緩存問題——
🔥 緩存穿透(請求像穿了隱身衣👻)
💥 緩存擊穿(熱點數據突然暴斃💣)
?? 緩存雪崩(集體去世的慘案🏔?)
在這里插入圖片描述


???

一、緩存穿透(Cache Penetration)

理解緩存穿透:
????緩存穿透是指查詢一個在數據庫中肯定不存在的數據。為了避免每次請求都直接訪問數據庫,我們通常會使用緩存來提高查詢效率。
????正常的緩存使用流程大致如下:

  1. 查詢緩存:首先,會檢查緩存中是否存在需要的數據。如果緩存中有數據,就直接返回,不需要訪問數據庫。
  2. 緩存失效或不存在數據:如果緩存中沒有數據,或者緩存的數據已經過期,那么系統會訪問數據庫去查找數據。
  3. 查詢結果為空:如果數據庫中查詢到的數據為空(即數據確實不存在),那么我們不會把這個空結果存入緩存。

????舉個例子,比如我傳一個用戶 id 為 -1,這個用戶 id 在緩存里面是肯定不存在的,所以會去數據庫里面查詢,如果有搞事情的人,大批量請求并傳用戶 id 為 -1,那就和沒用 redis 一樣,導致數據庫壓力過大而崩潰。
????總結來說,緩存穿透問題就是指我們查詢的那個數據本來就不存在,而這種查詢沒有被有效地攔截,導致每次都要訪問數據庫,造成緩存的無效使用。
在這里插入圖片描述
???
???
解決方法:

  • 接口層增加校驗:不合法的參數直接返回(如ID格式、范圍限制)。不相信任務調用方,根據自己提供的 API 接口規范來,作為被調用方,要考慮可能任何的參數傳值。
  • 緩存空值:在緩存查不到,DB 中也沒有的情況,可以將對應的 key 的 value 寫為 null,或者其他特殊值寫入緩存,同時將過期失效時間設置短一點(如30秒),以免影響正常情況。這樣是可以防止反復用同一個 ID 來暴力攻擊。
if (data == null) {cache.set(key, null, 30); // 緩存空值
}
  • 網關設置閾值:正常用戶是不會這樣暴力功擊,只有是惡意者才會這樣做,可以在網關 NG 作一個配置項,為每一個 IP 設置訪問閾值。
  • 布隆過濾器:高級用戶布隆過濾器(Bloom Filter), 這個也能很好地防止緩存穿透。原理就是利用高效的數據結構和算法快速判斷出你這個 Key 是否在 DB 中存在,不存在你 return 就好了,存在你就去查了 DB 刷新 KV 再 return。

???

二、緩存擊穿(Cache Breakdown)

理解緩存擊穿:
????緩存擊穿是指某個緩存中的熱點數據(即頻繁訪問的數據)在短時間內失效,導致大量并發請求繞過緩存,直接訪問數據庫。這種情況就像是屏障上的一個洞,導致數據查詢瞬間變得非常慢。
????具體來說,當一個非常熱門的緩存數據失效時,如果沒有其他機制來保護,所有的并發請求都會直接去訪問數據庫,給數據庫帶來巨大的壓力。這樣,原本應該由緩存處理的請求就會集中到數據庫,造成性能瓶頸,甚至可能導致數據庫崩潰。
????舉個例子,好比秒殺某一個商品或者某個top實時熱搜,這個key一直在緩存中,但緩存是有過期時間的,假如這個key是1800秒(30分鐘)過期,1800秒后這個key還是非常熱點,但key過期了,那么會直接在數據庫中進行查詢,查詢到后放入緩存中,在放入緩存這段過程,雖然時間很短很短,比如只有0.1秒,但就是這0.1秒會直接讓數據庫并發激增,甚至導致宕機。
在這里插入圖片描述
???
???
解決方法:

  • 互斥鎖:在緩存失效時,為獲取數據的請求加鎖(如Redis的SETNX),確保只有一個請求去查詢數據庫并更新緩存,其他請求等待獲取緩存更新后的結果。
String value = cache.get(key);
if (value == null) {if (lock.tryLock()) { // 獲取分布式鎖try {value = db.get(key); // 查數據庫cache.set(key, value);} finally {lock.unlock();}}
}
  • 提前更新緩存:在數據更新時,提前刷新相關緩存,以避免緩存失效。
  • 熱點數據永不過期(慎用):對極熱點數據不設過期時間,通過后臺任務定期更新,充分把 Redis 高吞吐量性能利用起來。
  • 邏輯過期:不設置物理過期時間,而是在value中存儲過期時間。業務邏輯判斷是否過期,異步更新緩存。

???

三、緩存雪崩(Cache Avalanche)

理解緩存雪崩:
????緩存雪崩是指在同一時間,大量緩存數據同時失效,導致大量請求直接訪問數據庫。這樣會給數據庫帶來極大壓力,甚至可能導致數據庫崩潰。
????舉個例子,雙十一期間,凌晨12點會迎來搶購高峰期,熱點商品都會放在緩存中,假設緩存1小時,那么到凌晨1點這批熱點數據就會批量過期,那么就會導致大量的商品直接在數據庫中進行查詢,直接讓數據庫并發激增,導致宕機。
????還有就是緩存數據庫異常宕機,大量緩存同時失效,導致所有請求涌向數據庫。
在這里插入圖片描述
???
???
解決方案:

  • 分散過期時間:為緩存key設置分散的過期時間(如基礎時間+隨機偏移量),避免同一時間大量緩存同時失效。
cache.set(key, value, baseTime + random.nextInt(300)); // 基礎時間+隨機秒數
  • 提前預熱緩存:在系統負載較低時,提前加載重要的數據到緩存中。
  • 使用多級緩存:采用多層級緩存(如本地緩存+Redis),避免單點故障。
  • 高可用架構:Redis集群部署(主從+哨兵/Cluster模式),避免全盤崩潰。
  • 接口限流:當訪問的不是核心數據的時候,在查詢的方法上加上接口限流保護。

???
總結一下:

  1. 緩存穿透: 查詢一個 不存在的數據,緩存和數據庫都沒有,導致每次請求都直接訪問數據庫(如惡意請求不存在的ID)。
  2. 緩存擊穿: 某個 熱點key過期 時,大量并發請求同時穿透緩存,直接訪問數據庫。
  3. 緩存雪崩: 大量緩存key同時失效或緩存服務宕機,導致所有請求涌向數據庫。
問題觸發條件核心解決方案
緩存穿透查詢不存在的數據(如惡意請求不存在的ID)。1、接口層增加校驗
2、緩存空值
3、網關設置閾值
4、布隆過濾器
緩存擊穿熱點key突然失效1、互斥鎖
2、提前更新緩存
3、熱點數據永不過期(慎用)
4、邏輯過期
緩存雪崩大量key同時失效/服務宕機1、分散過期時間
2、提前預熱緩存
3、使用多級緩存
4、高可用架構
5、接口限流

????呼,關于這篇的內容到這里就結束啦!🎉 尤其是文章中的6個示意圖,花了接近4小時精心繪制?,就是希望能更直觀地展現原理,讓枯燥的文字變得生動易懂💡。看在博主爆肝作圖、瘋狂掉發的份上😝,各位大佬賞個三連吧👍?💬!也讓博主有更多的動力去認真撰寫后續的博客~🚀

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

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

相關文章

Docker 實踐與應用案例

引言 在當今的軟件開發和部署領域,高效、可移植且一致的環境搭建與應用部署是至關重要的。Docker 作為一款輕量級的容器化技術,為解決這些問題提供了卓越的方案。Docker 通過容器化的方式,將應用及其依賴項打包成一個獨立的容器,…

《論三生原理》以非共識路徑實現技術代際躍遷??

AI輔助創作: 《論三生原理》以顛覆傳統數學范式的非共識路徑驅動多重技術代際躍遷,其突破性實踐與爭議并存,核心論證如下: 一、技術代際躍遷的實證突破? ?芯片架構革新? 為華為三進制邏輯門芯片提供理論支撐,通過對…

一體機電腦為何熱度持續上升?消費者更看重哪些功能?

一體機電腦(AIO,All-in-One)將主機硬件與顯示器集成于單一機身。通常僅需連接電源線,配備無線鍵盤、鼠標即可啟用。相比傳統臺式電腦和筆記本電腦,選購一體機的客戶更看重一體機的以下特點。 一體機憑借其節省空間、簡…

無人機載重模塊技術要點分析

一、技術要點 1. 結構設計創新 雙電機卷揚系統:采用主電機(張力控制)和副電機(卷揚控制)協同工作,解決繩索纏繞問題,支持30米繩長1.2m/s高速收放,重載穩定性提升。 軸雙槳布局…

【大模型推理】工作負載的彈性伸縮

基于Knative的LLM推理場景彈性伸縮方案 1.QPS 不是一個好的 pod autoscaling indicator 在LLM推理中, 為什么 2. concurrency適用于單次請求資源消耗大且處理時間長的業務,而rps則適合較短處理時間的業務。 3.“反向彈性伸縮”的概念 4。 區分兩種不同的…

STM32F103_Bootloader程序開發12 - IAP升級全流程

導言 本教程使用正點原子戰艦板開發。 《STM32F103_Bootloader程序開發11 - 實現 App 安全跳轉至 Bootloader》上一章節實現App跳轉bootloader,接著,跳轉到bootloader后,下位機要發送報文‘C’給IAP上位機,表示我準備好接收固件數…

AI驅動的未來軟件工程范式

引言:邁向智能驅動的軟件工程新范式 本文是一份關于構建和實施“AI驅動的全生命周期軟件工程范式”的簡要集成指南。它旨在提供一個獨立、完整、具體的框架,指導組織如何將AI智能體深度融合到軟件開發的每一個環節,實現從概念到運維的智能化…

Hawk Insight|美國6月非農數據點評:情況遠沒有看上去那么好

7月3日,美國近期最重要的勞動力數據——6月非農數據公布。在ADP遇冷之后,市場對這份報告格外期待。 根據美國勞工統計局公布報告,美國6月非農就業人口增加 14.7萬人,預期 10.6萬人,4月和5月非農就業人數合計上修1.6萬人…

Python 的內置函數 reversed

Python 內建函數列表 > Python 的內置函數 reversed Python 的內置函數 reversed() 是一個用于序列反轉的高效工具函數,它返回一個反向迭代器對象。以下是關于該函數的詳細說明: 基本用法 語法:reversed(seq)參數:seq 可以是…

溝通-交流-說話-gt-jl-sh-goutong-jiaoliu-shuohua

溝通,先看|問狀態(情緒) 老婆下班回家,我說,到哪兒了,買點玉米哦;她說你為啥不買, 我說怎么如此大火氣, 她說你安排我,我不情愿;你怎么看 和女人溝通不能目標優先 先問狀態并表達關心 用感謝代替要求(“你上次買的玉米特別甜,今天突然又饞了…

Ubuntu20.04運DS-5

準備工作: cd /home/rlk/rlk/runninglinuxkernel_5.0 #make clean mkdir _install_arm64/dev sudo mknod _install_arm64/dev/console c 5 1 ./build_ds5_arm64.sh git checkout boot-wrapper-aarch64/fvp-base-gicv3-psci.dtb ./build_ds5_arm64.sh創建工程步驟2.5…

區塊鏈網絡P2P通信原理

目錄 區塊鏈網絡P2P通信原理引言:去中心化的網絡基石1. P2P網絡基礎架構1.1 區塊鏈網絡拓撲1.2 節點類型對比2. 節點發現與連接2.1 初始引導過程2.2 節點發現協議3. 網絡通信協議3.1 消息結構3.2 核心消息類型4. 數據傳播機制4.1 交易傳播流程4.2 Gossip協議實現4.3 區塊傳播優…

RNN和Transformer區別

RNN(循環神經網絡)和 Transformer 是兩種廣泛應用于自然語言處理(NLP)和其他序列任務的深度學習架構。它們在設計理念、性能特點和應用場景上存在顯著區別。以下是它們的詳細對比:1. 基本架構RNN(循環神經網…

[學習記錄]Unity-Shader-幾何著色器

幾何著色器是可編程渲染管線中的一個可選階段,位于頂點著色器之后和片段著色器之前。其核心能力在于動態生成和操作幾何體圖元。 一.圖元 了解圖元是理解幾何著色器的基礎和前提,因為幾何著色器的工作就是接收圖元,然后輸出圖元。 幾何著色…

Paimon 布隆過濾器索引

布隆過濾器原理布隆過濾器的最優參數推導是其理論核心,理解了這個過程,就能明白 BloomFilter64 構造函數里計算公式的由來了。下面我們一步步來推導。首先,我們定義幾個關鍵變量:n: 預估要插入的元素數量 (對應代碼中的 items)。m…

Python-GUI-wxPython-布局

1 需求 2 接口 wx.Sizer().Add() proportion(比例)參數是一個整數,用于指定當父布局管理器的空間有剩余時,被添加的對象(這里是 general_sizer 及其包含的組件)在布局方向上可以占據的額外空間的比例。 當…

springboot 鏈路追蹤實現

traceid實現 需要依賴<dependency><groupId>com.alibaba</groupId><artifactId>transmittable-thread-local</artifactId><version>2.14.5</version></dependency>public class TraceIdContext {private static final String …

JavaEE初階第七期:解鎖多線程,從 “單車道” 到 “高速公路” 的編程升級(五)

專欄&#xff1a;JavaEE初階起飛計劃 個人主頁&#xff1a;手握風云 一、死鎖 1.1. 死鎖的概念 死鎖是指兩個或多個并發進程&#xff08;或線程&#xff09;在執行過程中&#xff0c;因爭奪資源而造成的一種互相等待的現象。如果沒有外力作用&#xff0c;這些進程將永遠無法繼…

黑暗中的爆破(船訊網Ais爬蟲暨爬蟲實戰js逆向學習經驗分享)

事先聲明:本文章所獲得的信息均通過合法手段獲得(本人為政府部門工作,爬蟲行為均經過授權),爬蟲需遵守各項法律法規,不該爬取的信息不爬。 最近因為做博士畢業設計需要用到ais信息,但在船訊網爬取ais的時候遇到了問題,因為之前爬取的人太多,所以網站加上了反爬措施,c…

代碼混淆的步驟

在 Android 開發中&#xff0c;代碼混淆&#xff08;ProGuard/R8&#xff09;是保護代碼安全和縮減應用體積的關鍵步驟。以下是詳細的混淆流程和優化策略&#xff1a; 一、基礎混淆步驟 1. 啟用混淆 在 build.gradle 中配置&#xff1a; android {buildTypes {release {mini…