【redis】redis應用場景,緩存的各種問題解析

来源:https://www.cnblogs.com/ztfjs/archive/2019/08/21/redis-cache.html
-Advertisement-
Play Games

如果你還不知道redis的基本命令與基本使用方法,請看 【redis】redis基礎命令學習集合 緩存 redis還有另外一個重要的應用領域——緩存 引用來自網友的圖解釋緩存在架構中的位置 預設情況下,我們的服務架構如下圖,客戶端請求service,然後service去讀取mysql資料庫 問題存在 ...


如果你還不知道redis的基本命令與基本使用方法,請看 

【redis】redis基礎命令學習集合

緩存

redis還有另外一個重要的應用領域——緩存

引用來自網友的圖解釋緩存在架構中的位置

預設情況下,我們的服務架構如下圖,客戶端請求service,然後service去讀取mysql資料庫

avatar

問題存在於,資料庫性能不夠用,資料庫是整個架構中最重要的一個環節,它在高併發,高寫入頻次的時候非常容易崩掉,這是一般的資料庫本身的特性所決定的,它們的架構模式註定了不可以承受較大的併發量,所以就有了緩存:

avatar

service與高速的緩存進行交互,如果緩存中有數據直接返回客戶端,如果沒有才會從MySql中去查詢。減小資料庫的壓力,提升效率,避免宕機。

例如上面章節提到的,超賣問題,有可能瞬間的流量高達上萬,我們不可能把這些請求都響應到資料庫上,這樣速度慢不說,還隨時可能宕機。

提到緩存,就不得不說下麵的四大緩存名場面,幾乎是做緩存必須面對的問題。

緩存擊穿

想象一個場景,現在在一個xx辦事大廳

張三、李四、王五、趙六、錢錢、劉八、陳九 七個人正在排隊

辦事處有一個視窗,有一些自動業務機,視窗裡面的同志一下子只能接待一個人,而自動業務機因為速度很快可以很快接待很多人。

現在,突然、自動業務機都壞了... 所有人都排到了視窗,這下忙死了視窗裡面的同志,直接撂挑子不幹了!

這個例子中,自動業務機就像是緩存,起了一個緩衝的作用,業務員就像是資料庫,處理能力比自動機器慢,而且很容易炸毛。

緩存擊穿就是這樣,當某個緩存故障、或者在高峰期緩存突然無效了,就會導致所有請求都跑到資料庫去排隊,就造成了緩存擊穿。

 

緩存相當於給資料庫加了一層保護能量罩,敵人進來的時候如果某個地方沒有能量,那麼如果這個地方的敵人特別多,就會導致緩存擊穿。當從緩存中查詢不到我們需要的數據就要去資料庫中查詢了。如果被黑客利用,或者高峰流量,頻繁去訪問緩存中沒有的數據,那麼緩存就失去了存在的意義,瞬間所有請求的壓力都落在了資料庫上,這樣會導致資料庫連接異常。

解決方案:

  • 後臺設置定時任務,主動的去更新緩存數據。這種方案容易理解,就是在自動業務機旁邊加了一個維護員,壞了趕緊修好,但是機器多了就比較複雜,維護員不一定能搞得定,當key比較分散的時候,操作起來還是比較複雜的

  • 分級緩存。什麼意思呢,就是放兩台業務機器,平時用第一臺,第一臺壞了馬上用第二台,用第二台的時候修第一臺,設置兩層緩存保護層,1級緩存失效時間短,2級緩存失效時間長。有請求過來優先從1級緩存中去查找,如果在1級緩存中沒有找到相應數據,則對該線程進行加鎖,這個線程再從資料庫中取到數據,更新至1級和2級緩存。其他線程則直接從2級線程中獲取

緩存穿透

緩存穿透本質上和緩存擊穿所面臨的問題一樣,大量請求落到資料庫中。

但是出發點略有不用,緩存穿透的問題是,在高併發下,查詢一個不存在的值時,緩存不會被命中,導致大量請求直接落到資料庫上,如活動系統裡面查詢一個不存在的活動。

也就是說,緩存擊穿是當數據是存在的,但沒有被緩存到,而緩存穿透是去訪問根本不存在的值。想象一個場景,黑客截取了一個已經過期的活動的數據介面,然後不斷的去請求它,這時候有可能因為這個活動本身已經過期了,緩存不會命中,請求就全部落地到資料庫了,這時候就造成了緩存穿透。

緩存穿透的問題解決方案也有很多

直接緩存NULL值

這個比較容易理解,就算是沒數據我也緩存一下,你下次過來命中的是空數據。

這種方法需要特別註意,為空的值不能緩存的太久,否則有可能在真的有數據的時候影響了業務正常流程。

布隆過濾器

什麼是布隆過濾器

布隆過濾器判斷一個值不存在,那麼這個值100%不存在

布隆過濾器判斷一個值存在,這個值90%是存在的

布隆過濾器本質是一個位數組,位數組就是數組的每個元素都只占用 1 bit 。每個元素只能是 0 或者 1。這樣申請一個 10000 個元素的位數組只占用 10000 / 8 = 1250 B 的空間。布隆過濾器除了一個位數組,還有 K 個哈希函數。

等一下,是不是有點繞,不太好理解。

我們知道hash函數可以根據一個值生成一個對應的數字,然後與一個長度可以取模可以得到一個下標值 (你不知道?看看HashMap的實現吧)

或者你根本不知道hash是怎麼實現的,沒關係,也可以先理解下麵的,我們先把這個函數假設為 int getIndex (String value), 根據值獲取到一個下標

假設我們現在有一個數組,長度是5,每個元素的值都是0

0 , 0 , 0 , 0 , 0

現在我們資料庫中一共有五個id

a , b , c , d , e

現在我們對id們執行getIndex函數可以得到

getIndex(a) = 0

getIndex(b) = 1

getIndex(c) = 1 // 假設函數有一些誤差

getIndex(d) = 2

getIndex(e) = 3

想一想,現在來了一個新元素,f 怎麼樣判斷在id裡面存在不存在呢?

我們把開始的數組和getIndex關聯起來, 將getindex的值作為下標,設置值為1,數組就會變成

1 , 1 , 1 , 1 , 0

然後我們再來判斷f是否存在,假設 getIndex(f) = 4

ok了,我們只需要判斷數組裡的下標4是否是1,是1就存在,0就不存在了嘛

那如果 getIndex(f) = 2 呢? 我們開了上帝視角,很明顯f不存在呀。

布隆過濾器不能100%判斷一個元素是否真的存在數組中,但能100%判斷它不存在與數組中,這取決於hash函數的演算法程度

布隆過濾器防止緩存穿透

通過對布隆過濾器的理解,我們能就過濾掉大部分的無效請求了,把資料庫中所有的id都getindex解析一次放到布隆過濾器中,請求過來的時候判斷,如果不存在就直接返回空就行了

緩存雪崩

如果緩存集中在一段時間內失效,發生大量的緩存穿透,所有的查詢都落在資料庫上,造成了緩存雪崩。

其實與緩存擊穿的理論差不多,都是突然失效導致的擊穿資料庫。

雪崩與擊穿的不同點在於雪崩強調集中失效兩個字

想象~ 我現在有三個緩存key存在redis中,過期時間是一天

一天後,由於key有可能是同時設置的緩存,導致這三個key同時失效了,即使我的緩存擊穿問題已經解決,這時候因為集中的key失效,也會造成擊穿!,這是量級發生了改變,就像x和y的關係, x表示key的多少,y表示請求的多少。。。

解決方案

  • 設置不同的過期時間

熱度數據

你永遠不可能每個緩存都能命中的。什麼是好的緩存策略,好的緩存策略是能夠識別熱點數據,併在熱點被讀取的時候能夠保證命中,這是一個好的緩存策略所必須的條件之一。

 

緩存一致性

 

資料庫的數據和緩存的數據是不可能一致的,數據分為最終一致和強一致兩類。

強一致 不可以使用緩存

緩存能做的只能保證數據的最終一致性。

我們能做的只能是儘可能的保證數據的一致性。

不管是先刪庫再刪緩存 還是 先刪緩存再刪庫,都可能出現數據不一致的情況,因為讀和寫操作是併發的,我們沒辦法保證他們的先後順序。

具體應對策略根據業務需求來制訂。

 

緩存過期和淘汰

 

Redis設置的過期時間。這個key過期時是怎麼刪除的?

Redis採用的是定期刪除,註意不是定時刪除,不可能為每一個key做一個定時任務去監控刪除,這樣會耗盡伺服器資源。

預設是每100ms檢測一次,遇到過期的key則進行刪除,這裡的檢測也不是順序檢測,而是隨機檢測。

另外為了防止有漏網之魚,例如在100ms檢查的中間間隙,某個key過期,但同時key訪問又進來了,這時觸發 惰性刪除策略 redis會在讀取時判斷是否已經過期,過期則直接刪除。

記憶體淘汰是指一部分key在記憶體不夠用的情況下會被Redis自動刪除,從而會出現從緩存中查不到數據的情況。

例如我們的伺服器記憶體為2G、但是隨著業務的發展緩存的數據已經超過2G了。但是這並不能影響我們程式的運行。所以redis會從key列表中抽取一定的熱度低的數據進行淘汰策略,騰出空間存儲新的key

 

...持續更新

 

github: https://github.com/294678380/redis-lerning


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 恢復內容開始 設計表的時候 1. 不同的表涉及同一個公共意義欄位不要使用不同的數據類型(可能導致索引不可用,查詢結果有偏差) 2. 不要一張表放太多的數據 主表20~30個欄位 其他表最好不超過20個 3. 最好不要有為Null的列,原因:https://mp.weixin.qq.com/s/U4R ...
  • 公司在Azure的Iaas虛擬機上部署有好幾台MySQL資料庫,至於沒有選擇Azure Database for MySQL,是因為預算有限(錢不夠啊!說多了也是淚,坑的還是DBA自己)。選擇了Iaas的話,DBA就必須考慮離線備份(offline backup),以預防災難性故障出現。我們選擇將歷... ...
  • 分享一篇關於實時流式計算的經典文章,這篇文章名為Streaming 101: The world beyond batch 那麼流計算如何超越批處理呢? 從這幾個方面說明:實時流計算系統,數據處理模式,還有大數據的未來。 一、實時流式計算系統 實時流式計算的意義: 1、企業渴望獲得更及時的數據,實時 ...
  • 所需補丁及高版本opatch上傳後將p6880880_112000_Linux-x86-64.zip解壓覆蓋$ORACLE_HOME/OPatch目錄即可[oracle@localhost OPatch]$ ./opatch versionOPatch Version: 11.2.0.3.16OPa... ...
  • 1.Redo Log The redo log is a disk-based data structure used during crash recovery to correct data written by incomplete transactions. During normal op ...
  • 轉載、節選於 https://dev.mysql.com/doc/refman/8.0/en/innodb-doublewrite-buffer.html The doublewrite buffer is a storage area located in the system tablespac ...
  • 概念介紹 CDH概覽 CDH是Apache Hadoop和相關項目的最完整、最受測試和最流行的發行版。CDH提供Hadoop的核心元素 可伸縮存儲和分散式計算 以及基於web的用戶界面和重要的企業功能。CDH是Apache許可的開放源碼,是唯一提供統一批處理、互動式SQL和互動式搜索以及基於角色的訪 ...
  • 本數據源來自 https://www.kafan.cn/edu/922556.html 目的為了備忘 把原來的sql server 2005直接裝成了2012,然後在建立鏈接伺服器鏈接一臺sql server 2000的伺服器時,報錯信息大概是“SQL Server Native Client 11 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...