91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

4種常見的緩存問題及解決方案詳解

發布時間:2020-06-29 12:02:25 來源:網絡 閱讀:314 作者:架構師追風 欄目:編程語言

前言

使用緩存可以緩解大流量壓力,顯著提高程序的性能。我們在使用緩存系統時,尤其是大并發情況下,經常會遇到一些“疑難雜癥”。本文總結了一些使用緩存時常見的問題及解決方案,以后在遇到這類問題時可以作為參考,在設計緩存系統的時候也應該考慮這些常見的情況。

為了表述方便,本文以數據庫查詢緩存為例,使用緩存可以減小對數據庫的壓力。

4種常見的緩存問題及解決方案詳解

緩存穿透

我們在使用緩存時,往往先嘗試去緩存中取值,如果沒有,再去數據庫取值,如果數據庫也沒有值,則根據業務需求,返回空或者拋異常。

如果用戶一直訪問一個數據庫不存在的數據,比如id為-1的數據,就會導致每次請求都會先去緩存查一次,然后再去數據庫查一次,造成嚴重的性能問題。這種情況就叫緩存穿透。

解決方案

以下幾種解決方案:

  • 對請求參數做校驗,比如用戶鑒權校驗,id做基礎校驗,id <= 0的直接攔截。

  • 如果查詢到數據庫沒有值,也將對應的key存進緩存中,value為null。這樣下次查詢就直接從緩存返回了。但這里的key的緩存時間應該比較短,比如30s。防止后面在數據庫插入了這條數據,而用戶獲取不到。

  • 使用布隆過濾器,判斷一個key是否已經查過了,如果已經查過了,就不去數據庫查詢。

4種常見的緩存問題及解決方案詳解

緩存擊穿

緩存擊穿指的是,一個key的訪問量非常大,比如某秒殺活動,有1w/s的并發量。這個key在某一時刻過期,那這些大量的請求就會一瞬間到數據庫,數據庫可能會直接崩潰。

解決方案

緩存擊穿的解決方案也有幾種,可以配合使用:

  • 對于熱點數據,慎重考慮過期時間,確保熱點期間key不會過期,甚至有些可以設置永不過期。

  • 使用互斥鎖(比如Java的多線程鎖機制),第一個線程訪問key的時候就鎖住,等查詢數據庫返回后,把值插入到緩存后再釋放鎖,這樣后面的請求就可以直接取緩存里面的數據了。

緩存雪崩

緩存雪崩指的是,在某一時刻,多個key失效。這樣就會有大量的請求從緩存中獲取不到值,全部到數據庫。還有另一種情況,就是緩存服務器宕機,也算做緩存雪崩。

解決方案

針對上述兩種情況,緩存雪崩有兩種解決方案:

  • 對每個key的過期時間設置一個隨機值,而不是所有key都相同。

  • 使用高可用的分布式緩存集群,確保緩存的高可用性,比如redis-cluster。

4種常見的緩存問題及解決方案詳解

雙寫不一致

在使用數據庫緩存的時候,讀和寫的流程往往是這樣的:

  • 讀取的時候,先讀取緩存,如果緩存中沒有,就直接從數據庫中讀取,然后取出數據后放入緩存

  • 更新的時候,先刪除緩存,再更新數據庫

所謂雙寫不一致,就是在發生寫操作(更新)的時候或寫操作之后,可能會存在數據庫里面的值和緩存中的值不同的情況。

為什么更新的時候要先刪除緩存,再更新數據庫?因為如果先更新數據庫,然后在刪除緩存的時候失敗了,就會造成緩存里面的值和數據庫的值不一致。

然而這樣并不能完全避免雙寫不一致問題。假設在大并發情景下,一個線程先刪除緩存,然后取更新數據庫,這個時候另一個線程去取緩存,發現沒有值,于是去讀數據庫,然后把數據庫舊的值設置進緩存。等第一個線程更新完數據庫后,數據庫里面就是新的值,而緩存里面是舊的值,所以就存在了數據不一致的問題。

一個比較簡單的解決辦法是把過期時間設置得比較低,這樣就只有在緩存沒過期之前存在數據不一致問題,在一些業務場景下也還能接受。

另一種解決方案是使用隊列輔助。先更新數據庫,再刪除緩存。如果刪除失敗,就放進隊列。然后另一個任務從隊列中取出消息,不斷去重試刪除相應的key。

還有一種解決方案是使用對一個數據使用一個隊列,使讀寫操作串行化。比如對id為n的數據建立一個隊列。對這條數據的寫操作,刪除緩存后,放進一個隊列;然后另一個線程過來了,發現沒有緩存,則把這個讀操作也放進這個隊列里面。

歡迎大家關注我的公種浩【程序員追風】,文章都會在里面更新,整理的資料也會放在里面。

不過這樣會增加程序的復雜性,串行化也會降低程序的吞吐量,可能得不償失。一般主流的解決方案還是先刪除緩存,再更新數據庫。可以滿足絕大部分需求。

最后

歡迎大家一起交流,喜歡文章記得點個贊喲,感謝支持!


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新野县| 宁武县| 连平县| 临猗县| 宁陵县| 含山县| 财经| 南投县| 彝良县| 大余县| 扎兰屯市| 收藏| 尉氏县| 贺兰县| 徐州市| 喀什市| 哈尔滨市| 贡觉县| 土默特右旗| 宝清县| 天柱县| 秦皇岛市| 汝州市| 桂东县| 蒲江县| 额敏县| 永宁县| 白朗县| 唐山市| 麟游县| 盐边县| 桐梓县| 绩溪县| 上栗县| 南城县| 额尔古纳市| 锡林郭勒盟| 黑河市| 兴仁县| 沾化县| 永胜县|