天天看點

【金三銀四】緩存面試題-web層緩存

【金三銀四】緩存面試題-web層緩存

由于緩存的種類衆多,不同場景的緩存也存在着一些不一樣的特點。内容太多。本文僅限于Web應用層緩存

什麼是緩存,為什麼要用緩存?

速度問題

由于記憶體的讀寫速度要比磁盤的讀寫速度快一個數量級。

一般的ddr3代1333的速度讀寫在7000mb/s以上,

ssd硬碟讀寫大概500mb/s

如果是機械硬碟,或者其他儲存設備,那讀寫速度可能會更低。

連接配接問題

假如公司網站首頁有個接口。需要去資料庫擷取一些資訊。(别和栗子較真)格式如下:

curl  http://xxx.cn/homeInfo

#傳回值
{
	"pageName": "home",
	"title": "XXXX",
	"website": "http://www.xxxx.com/",
	"companyName": "xxxx",
	"employees": "103699人",
	"desc": "XXXX網絡技術有限公司(簡稱:XXXX集團或XXXX)是以曾擔任英語教師的馬某為首的18人于1999年在浙江省杭州市創立的公司"
}      

比如現在用戶端有100萬個使用者打開了一個網站的。那麼就會有100萬個請求去讀資料庫。

這裡會發現一個問題,就是我100萬個人明明擷取的資料都是同一份資料,但是我資料庫要查100萬次。

先不說資料庫能不能抗的住這100萬的請求。會發現這操作就很重複,很備援,很低效。

基于上面兩個問題。那麼緩存就能很好的解決這兩個問題。

緩存的主要任務就是為了減少資料庫(硬碟)的讀寫次數。

沒有緩存得請求方式

【金三銀四】緩存面試題-web層緩存

加了緩存的請求方式

【金三銀四】緩存面試題-web層緩存

緩存的流程

請求到Java時,Java先從Redis中讀取資料,如果讀取到資料直接傳回給前端。

如果讀取不到則從資料庫中讀取,存入Redis中,并傳回。當下次讀取時redis就已經有資料了。不會再直接通路資料庫了。

緩存資料一緻性問題

資料庫中的資料緩存在Redis之後。如果資料庫資料發生修改。那麼從緩存中讀到的資料就會不正确。

是以為了保證緩存中的資料和資料庫的資料保持一緻。我們通常的做法是。

在資料庫進行新增,修改,删除的時候。清楚redis中的緩存。這樣當下次查詢的時候,會重新讀取資料庫再緩存到Redis中。

緩存的三大坑

緩存穿透

  • 緩存穿透是指查詢的資料在資料庫是沒有的,那麼在緩存中自然也沒有,是以在緩存中查不到就會去資料庫查詢,這樣的請求一多,我們資料庫的壓力自然會增大。
  • 解決

    對于傳回為 NULL 的依然緩存,對于抛出異常的傳回不進行緩存,注意不要把抛異常的也給緩存了

    制定一些規則過濾一些不可能存在的資料,小資料用 BitMap,大資料可以用布隆過濾器

緩存擊穿

  • 對于某些 Key 設定了過期時間,但是它是熱點資料,如果某個 Key 失效,可能大量的請求打過來,緩存未命中,然後去資料庫通路,此時資料庫通路量會急劇增加
  • 加分布式鎖

    異步加載,對這部分熱點資料采取到期自動重新整理的政策

緩存雪崩

  • 緩存雪崩是指緩存不可用或者大量緩存由于逾時時間相同在同一時間段失效,大量請求直接通路資料庫,資料庫壓力過大導緻系統雪崩。
  • 增加緩存系統可用性,通過監控關注緩存的健康程度,根據業務量适當的擴容緩存。

    采用多級緩存,不同級别緩存設定的逾時時間不同,即使某個級别緩存都過期,也有其他級别緩存兜底。

    緩存的 Key 值可以取個随機值,比如以前是設定 10 分鐘的逾時時間,那每個 Key 都可以随機 8-13 分鐘過期,盡量讓不同 Key 的過期時間不同。

如圖,當Redis出現問題的時候,多個JVM程序将使用從Map中擷取緩存的資料。而不至于直接通路資料庫。

【金三銀四】緩存面試題-web層緩存

本地緩存

本地緩存可以簡單的使用map或者一些第三方工具

如Guava的Cache,Hutool的Cache等。

這些工具類也都是繼承了Map做了LRU緩存,失效時間緩存等功能。

其都是依賴于JVM程序的。

優點是:單個服務挂了,不會影響其他JVM程序。

缺點是:沒有序列化,重新開機或者斷電緩存資料丢失;

使用不恰當時,容易記憶體溢出;

總結

好的緩存系統因該讓使用者體驗不到他的存在。而隻享受它所帶來的速度提升。

是以緩存一定要做好相容。不要因為引入了緩存,導緻系統不可用。那是得不償失的。

選擇适合自己的緩存方案。不一定所有的系統都需要緩存。下面列舉一些簡單的web應用緩存方案。

緩存方案

無緩存方式

在一些内部系統,甚至一些通路量及其小的網站。完全可以不用緩存。資料庫的性能其實并沒有那麼不堪一擊。

無依賴輕量級緩存

僅僅個别地方可能需要一些簡單的緩存。那麼可以直接在成員變量中使用Map(或ConcurrentHashMap)做簡單的緩存。如果使用LRU緩存淘汰,或者失效緩存,可以簡單引用一些第三方工具類,如Guava的Cache,Hutool的Cache等。

Redis緩存

Redis緩存也是根據自己的需要來使用。從單機Redis到高可用的Redis叢集。

單機Redis比較簡單,直接在一台伺服器上安裝一個Redis配置即可使用

{
	"author": "大火yzs",
	"title": "【金三銀四】緩存面試題-web層緩存",
	"tag": "Redis,緩存,面試題",
	"createTime": "2021-03-07  23:01"
}