官术网_书友最值得收藏!

4.3 緩存何時存儲數據

使用緩存的邏輯如下。

1)先嘗試從緩存中讀取數據。

2)若緩存中沒有數據或者數據過期,再從數據庫中讀取數據保存到緩存中。

3)最終把緩存數據返回給調用方。

這種邏輯唯一麻煩的地方是,當用戶發來大量的并發請求時,它們會發現緩存中沒有數據,那么所有請求會同時擠在第2)步,此時如果這些請求全部從數據庫讀取數據,就會讓數據庫崩潰。

數據庫的崩潰可以分為3種情況。

1)單一數據過期或者不存在,這種情況稱為緩存擊穿

解決方案:第一個線程如果發現Key不存在,就先給Key加鎖,再從數據庫讀取數據保存到緩存中,最后釋放鎖。如果其他線程正在讀取同一個Key值,那么必須等到鎖釋放后才行。關于鎖的問題前面已經講過,此處不再贅述。

2)數據大面積過期或者Redis宕機,這種情況稱為緩存雪崩

解決方案:設置緩存的過期時間為隨機分布或設置永不過期即可。

3)一個惡意請求獲取的Key不在數據庫中,這種情況稱為緩存穿透

比如正常的商品ID是從100000到1000000(10萬到100萬之間的數值),那么惡意請求就可能會故意請求2000000以上的數據。這種情況如果不做處理,惡意請求每次進來時,肯定會發現緩存中沒有值,那么每次都會查詢數據庫,雖然最終也沒在數據庫中找到商品,但是無疑給數據庫增加了負擔。這里給出兩種解決辦法。

①在業務邏輯中直接校驗,在數據庫不被訪問的前提下過濾掉不存在的Key。

②針對惡意請求的Key存放一個空值在緩存中,防止惡意請求騷擾數據庫。

最后說一下緩存預熱

上面這些邏輯都是在確保查詢數據的請求已經過來后如何適當地處理,如果緩存數據找不到,再去數據庫查詢,最終是要占用服務器額外資源的。那么最理想的就是在用戶請求過來之前把數據都緩存到Redis中。這就是緩存預熱。

其具體做法就是在深夜無人訪問或訪問量小的時候,將預熱的數據保存到緩存中,這樣流量大的時候,用戶查詢就無須再從數據庫讀取數據了,將大大減小數據讀取壓力。

關于緩存何時存數據的問題就討論完了,接下來開始討論更新緩存的問題,這部分內容因涉及雙寫(緩存+數據庫),所以會花費一些篇幅。

主站蜘蛛池模板: 汽车| 凤冈县| 天水市| 天水市| 东港市| 淮安市| 永修县| 米林县| 中阳县| 仙游县| 株洲县| 湘潭县| 颍上县| 霞浦县| 龙泉市| 吴江市| 中超| 康马县| 呈贡县| 三门峡市| 全南县| 盐源县| 射洪县| 隆安县| 盘锦市| 个旧市| 德兴市| 镇安县| 汝阳县| 汉沽区| 随州市| 永和县| 大埔县| 广灵县| 尼木县| 晋江市| 莱芜市| 仪陇县| 张北县| 随州市| 镇雄县|