談一談數據庫的那些事

面向面試的博客,以問答式Q/A方式呈現。


Question1:介紹一下數據庫存儲引擎,以及羅列你所知道的幾種不同的數據庫存儲引擎?

Answer1:

數據庫存儲引擎含義

數據庫存儲引擎是數據庫底層軟件組織,數據庫管理系統(DBMS)使用數據引擎進行創建、查詢、更新和刪除數據。不同的存儲引擎提供不同的存儲機制、索引技巧、鎖定水平等功能,使用不同的存儲引擎,還可以 獲得特定的功能。現在許多不同的數據庫管理系統都支持多種不同的數據引擎。存儲引擎主要有: 1. InnoDB,2. Federated ,3. MyIsam ,4. Memory。

存儲引擎1:InnoDB ( B+樹 )

InnoDB 底層存儲結構爲B+樹, B樹的每個節點對應innodb的一個page,page大小是固定的,一般設爲 16k。其中非葉子節點只有鍵值,葉子節點包含完成數據

在這裏插入圖片描述
適用場景:
1)併發,經常更新的表,適合處理多重併發的更新請求。
2)容災,可以從災難中恢復(通過 bin-log 日誌等)。
3)事務,支持事務。
4)外鍵,外鍵約束,只有它支持外鍵。
5)主鍵,支持自動增加列屬性 auto_increment。

存儲引擎2:TokuDB( Fractal Tree-節點帶數據 )

TokuDB 底層存儲結構爲 Fractal Tree,Fractal Tree 的結構與 B+樹有些類似, 在 Fractal Tree中,每一個 child 指針除了需要指向一個 child 節點外,還會帶有一個 Message Buffer ,這個Message Buffer 是一個 FIFO 的隊列,用來緩存更新操作

例如,一次插入操作只需要落在某節點的 Message Buffer 就可以馬上返回了,並不需要搜索到葉子節點。這些緩存的更新會在查詢時或後臺異步合併應用到對應的節點中。

在這裏插入圖片描述

優點:TokuDB 在線添加索引,不影響讀寫操作, 非常快的寫入性能, Fractal-tree 在事務實現上有優勢。 他主要適用於訪問頻率不高的數據或歷史數據歸檔。

存儲引擎3:MyIASM

MyIASM是MySQL默認的引擎,不支持數據庫事務,也不支持行級鎖和外鍵。

優點:執行寫操作(INSERT或UPDATE)時需要鎖定整個表(即使用表級鎖),效率便會低一些。

缺點:執行讀取操作的速度很快,而且不佔用大量的內存和存儲資源。在設計之初就預想數據組織成有固定長度的記錄,按順序存儲的。

存儲引擎4:Memory

Memory(也叫 HEAP)堆內存:使用內存中的內容來創建表。每個 MEMORY 表只實際對應一個磁盤文件。

優點:訪問快,MEMORY 類型的表訪問非常得快,因爲它的數據是放在內存中的,並且默認使用HASH 索引。
缺點:易失,一旦服務關閉,表中的數據就會丟失掉,因爲內存是易失性的。

Memory 同時支持B樹索引和散列索引,B樹索引可以使用範圍查詢和通配查詢,也可以使用<,>和>=等操作符方便數據挖掘,散列索引相等的比較快但是對於範圍的比較慢很多。


Question2:談一談如何設計出高效的索引(或談一談你所知道的索引設計法則或如何在索引層面提高查詢速度)?

Answer2:

索引(Index)是幫助 MySQL 高效獲取數據的數據結構。常見的查詢算法,順序查找,二分查找,二叉排序樹查找,哈希散列法,分塊查找,平衡多路搜索樹 B 樹(B-tree)。

常見索引原則有:

  1. 選擇唯一性索引。做法:唯一性索引的值是唯一的,可以更快速的通過該索引來確定某條記錄。
  2. 重要的字段才索引。做法:爲經常需要排序、分組和聯合操作的字段建立索引 ;爲經常作爲查詢條件的字段建立索引 ; 避免帶函數的查詢參與索引(索引列不能參與計算,保持列“乾淨”)。
  3. 索引列選擇。儘量使用數據量少的索引;儘量選擇區分度高的列作爲索引,區分度的公式是表示字段不重複的比例。
  4. 限制索引的數目。理由:越多的索引,會使更新表變得很浪費時間。做法:刪除不再使用或者很少使用的索引;儘量的擴展索引,不要新建索引。
  5. 限制索引長度。理由:如果索引的值很長,那麼查詢的速度會受到影響。做法:儘量使用前綴來索引,如果索引字段的值很長,最好使用值的前綴來索引;最左前綴匹配原則,非常重要的原則。

Question3:介紹一下數據庫的三大範式?

Answer3:

範式是具有最小冗餘的表結構。三大範式具體如下:

1、第一範式(1st NF -列都是不可再分,拆分列)

第一範式的目標是確保每列的原子性:如果每列都是不可再分的最小數據單元(也稱爲最小的原子單元),則滿足第一範式(1NF)。

下圖左邊Address列同時描述國家和城市兩個屬性,將其優化以滿足第一範式,分爲Country City兩個列,保證每個列描述一個屬性。

在這裏插入圖片描述

2、第二範式(2nd NF -每個表只描述一件事情,拆分表)

首先滿足第一範式,並且表中非主鍵列對主鍵的完全依賴。 第二範式要求每個表只描述一件事情。

下圖左邊Orders表既描述訂單的意思(訂單編號、訂購日期兩個列),又描述產品的意思(產品編號、價格兩個列),將其優化以滿足第二範式,分爲Orders訂單表和Products產品表,保證每一個表描述一個事情,非主鍵列對主鍵列完全依賴。
在這裏插入圖片描述

3、第三範式(3rd NF - 不存在對非主鍵列的傳遞依賴,去掉多餘的列)

第三範式定義是,滿足第二範式,並且表中任何非主鍵列不依賴於其它非主鍵列,除了主鍵訂單編號外,顧客姓名依賴於非主鍵顧客編號。

下圖左邊Orders表,顧客姓名列除了依賴訂單編號,也可以單獨有顧客編號確定,也依賴顧客編號,將其優化以滿足第三範式,去掉這個顧客姓名列。

在這裏插入圖片描述


Question4:介紹一下數據庫事務ACID ?

Answer4:

事務(TRANSACTION)是作爲單個邏輯工作單元執行的一系列操作,這些操作作爲一個整體一起向系統提交,要麼都執行、要麼都不執行 。事務是一個不可分割的工作邏輯單元。

事務必須具備以下四個屬性,簡稱 ACID 屬性:

原子性( Atomicity )
事務是一個完整的操作。事務的各步操作是不可分的(原子的);要麼都執行,要麼都不執行。

一致性( Consistency )
當事務完成時,數據必須處於一致狀態。

隔離性( Isolation )
對數據進行修改的所有併發事務是彼此隔離的,這表明事務必須是獨立的,它不應以任何方式依賴於或影響其他事務。

永久性( Durability )
事務完成後,它對數據庫的修改被永久保持,事務日誌能夠保持事務的永久性。


Question5:介紹一下數據庫事務隔離機制?

Answer5:

數據庫事務隔離相關問題的含義

髒讀:指一個線程中的事務讀取到了另外一個線程中未提交的數據。
不可重複讀(虛讀):指一個線程中的事務讀取到了另外一個線程中提交的update的數據。
幻讀:指一個線程中的事務讀取到了另外一個線程中提交的insert的數據。

四種隔離級別

READ UNCOMMITTED(未提交讀)
在READ UNCOMMITTED級別,事務中的修改,即使沒有提交,對其他事務也都是可見的。事務可以讀取未提交的數據,這也被稱爲髒讀( Dirty Read),這個級別會導致很多問題,從性能上來說, READ UNCOMMITTED不會比其他的級別好太多,但卻缺乏其他級別的很多好處,除非真的有非常必要的理由,在實際應用中一般很少使用。

READ CONIIED(提交讀)
大多數數據庫系統的默認都是 READ COMITTED(但 MySQL不是),READ COMMITTED滿足前面提到的隔離性的簡單定義:一個事務開始時,只能“看見”已經提交的事務所做的修改。換句話說,一個事務從開始直到提交之前,所做的任何修改對其他事務都是不可見的,這個級別有時候也叫做不可重複讀( nonrepeatable read),因爲兩次執行同樣的查詢,可能會得到不一樣的結果。

REPEATABLE READ(可重複讀)
REPEATABLE READ解決了髒讀的問題。該級別保證了在同一個事務中多次讀取同樣記錄的結果是一致的,但是理論上,可重複讀隔離級別還是無法解決另外一個幻讀 ( Phantom Read)的問題。所謂幻讀,指的是當某個事務在讀取某個範圍內的記錄時,另外一個事務又在該範圍內插入了新的記錄,當之前的事務再次讀取該範圍的記錄時,會產生幻行( Phantom Row). InnoDB和 XtraDB存儲引擎通過多版本併發控制(MvC, Multiversion Concurrency Control)解決了幻讀的問題,。可重複讀是MySQL的默認事務隔離級別

SERIALIZABLE(可串行化)
SERIALIZABLE是最高的隔離級別。它通過強制事務串行執行,避免了幻讀問題。簡單來說,SERIALIZABLE會在讀取的每一行數據上都加鎖,所以可能導致大量的超時和鎖爭用的問題。實際應用中也很少用到這個隔離級別, 只有在非常需要確保數據的一致性而且可以接受沒有併發的情況下,才考慮採用該級別。

一表小結

隔離級別 髒讀(Dirty Read) 不可重複讀(NonRepeatable Read) 幻讀(Phantom Read)
未提交讀(Read uncommitted) 可能 可能 可能
已提交讀(Read committed) 不可能 可能 可能
可重複讀(Repeatable read) 不可能 不可能 可能
可串行化(Serializable ) 不可能 不可能 不可能

Question6:介紹一下數據庫事務存儲過程( 特定功能的SQL語句集)?

Answer6:

一組爲了完成特定功能的 SQL 語句集,存儲在數據庫中,經過第一次編譯後再次調用不需要再次編譯,用戶通過指定存儲過程的名字並給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象。

存儲過程優化思路:

  1. 避免循環:儘量利用一些 sql 語句來替代一些小循環,例如聚合函數,求平均函數等。
  2. 避免循環:查找語句儘量不要放在循環內。
  3. 中間結果:中間結果存放於臨時表,加索引。
  4. 遊標Cursor:少使用遊標。sql 是個集合語言,對於集合運算具有較高性能。而 cursors 是過程運算。比如對一個 100 萬行的數據進行查詢。遊標需要讀表 100 萬次,而不使用遊標則只需要少量幾次讀取。
  5. 事務:事務越短越好。sqlserver 支持併發操作。如果事務過多過長,或者隔離級別過高,都會造成併發操作的阻塞,死鎖。導致查詢極慢,cpu 佔用率極地。
  6. 異常:使用 try-catch 處理錯誤異常。

Question7:談一談觸發器(一段能自動執行的程序)?

Answer7:

觸發器是一段能自動執行的程序,是一種特殊的存儲過程。

觸發器和普通的存儲過程的區別是:觸發器是當對某一個表進行操作時觸發。
諸如:update、insert、delete 這些操作的時候,系統會自動調用執行該表上對應的觸發器。

觸發器能夠自動響應某種行爲,所以對於必須對某種行爲做出業務級別響應的情況,觸發器很合適。

觸發器可以分爲兩類:DML 觸發器和DDL 觸發器。DML觸發器包含了用於對錶或視圖的insert、update、delete操作做出響應的T-SQL代碼;DDL觸發器對服務器或數據庫事件做出響應而不是數據修改。


Question8:介紹一下數據庫併發策略?

Answer8:

併發控制一般採用三種方法,分別是樂觀鎖和悲觀鎖以及時間戳。

樂觀鎖認爲一個用戶讀數據的時候,別人不會去寫自己所讀的數據;悲觀鎖就剛好相反,覺得自己讀數據庫的時候,別人可能剛好在寫自己剛讀的數據,其實就是持一種比較保守的態度;時間戳就是不加鎖,通過時間戳來控制併發出現的問題。

1、樂觀鎖
樂觀鎖認爲一個用戶讀數據的時候,別人不會去寫自己所讀的數據,所以不加鎖,操作成功則無事,操作失敗則回退。

2、悲觀鎖

悲觀鎖就是在讀取數據的時候,爲了不讓別人修改自己讀取的數據,就會先對自己讀取的數據加鎖,只有自己把數據讀完了,才允許別人修改那部分數據,或者反過來說,就是自己修改某條數據的時候,不允許別人讀取該數據,只有等自己的整個事務提交了,才釋放自己加上的鎖,才允許其他用戶訪問那部分數據。以上悲觀鎖所說的加“鎖”,其實包括兩種鎖:排它鎖(寫鎖)和共享鎖(讀鎖)。

3、時間戳

時間戳就是在數據庫表中單獨加一列時間戳,比如“TimeStamp”,每次讀出來的時候,把該字段也讀出來,當寫回去的時候,把該字段加1,提交之前 ,跟數據庫的該字段比較一次,如果比數據庫的值大的話,就允許保存,否則不允許保存,這種處理方法雖然不使用數據庫系統提供的鎖機制,但是這種方法可以大大提高數據庫處理的併發量。


Question9:介紹一下數據庫鎖?

Answer9:

1、行級鎖

行級鎖是一種排他鎖,防止其他事務修改此行;在使用以下語句時,Oracle 會自動應用行級鎖:

  1. 鎖定:INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT]; 語句允許用戶一次鎖定多條記錄進行更新
  2. 解鎖:使用 COMMIT 或 ROLLBACK 語句釋放鎖。

2、表級鎖

表級鎖定包括表共享讀鎖(共享鎖)與表獨佔寫鎖(排他鎖)。表示對當前操作的整張表加鎖,它實現簡單,資源消耗較少,被大部分 MySQL 引擎支持。最常使用的 MYISAM 與 INNODB 都支持表級鎖定。

3、頁級鎖

頁級鎖是 MySQL 中鎖定粒度介於行級鎖和表級鎖中間的一種鎖。表級鎖速度快,但衝突多,行級衝突少,但速度慢。所以取了折衷的頁級,一次鎖定相鄰的一組記錄。BDB 支持頁級鎖。


Question10:介紹一下數據庫基於Redis的分佈式鎖?

Answer10:

  1. 獲取鎖的時候,使用 setnx(SETNX key val:當且僅當 key 不存在時,set 一個 key爲 val 的字符串,返回 1;若 key 存在,則什麼都不做,返回 0)加鎖,鎖的 value值爲一個隨機生成的 UUID,在釋放鎖的時候進行判斷。並使用 expire 命令爲鎖添加一個超時時間,超過該時間則自動釋放鎖。
  2. 獲取鎖的時候調用 setnx,如果返回 0,則該鎖正在被別人使用,返回 1 則成功獲取鎖。 還設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。
  3. 釋放鎖的時候,通過 UUID 判斷是不是該鎖,若是該鎖,則執行 delete 進行鎖釋放。

Question11:介紹一下數據庫分區、分表技術?

Answer11:

分庫分表有垂直切分和水平切分兩種。

垂直切分 ( 按照功能模塊 )
將表按照功能模塊、關係密切程度劃分出來,部署到不同的庫上。例如,我們會建立定義數據庫 workDB、商品數據庫 payDB、用戶數據庫 userDB、日誌數據庫 logDB 等,分別用於存儲項目數據定義表、商品定義表、用戶數據表、日誌數據表等。

在這裏插入圖片描述

水平切分 ( 按照規則劃分存儲 )
當一個表中的數據量過大時,我們可以把該表的數據按照某種規則,例如 userID 散列,進行劃分,然後存儲到多個結構相同的表,和不同的庫上。

在這裏插入圖片描述


Question12:談一談數據庫兩階段提交協議?

Answer12:

分佈式事務是指會涉及到操作多個數據庫的事務,在分佈式系統中,各個節點之間在物理上相互獨立,通過網絡進行溝通和協調。

XA 就是 X/Open DTP 定義的交易中間件與數據庫之間的接口規範(即接口函數),交易中間件用它來通知數據庫事務的開始、結束以及提交、回滾等。 XA 接口函數由數據庫廠商提供。

二階段提交(Two-phaseCommit)是指,在計算機網絡以及數據庫領域內,爲了使基於分佈式系統架構下的所有節點在進行事務提交時保持一致性而設計的一種算法(Algorithm)。通常,二階段提交也被稱爲是一種協議(Protocol))。在分佈式系統中,每個節點雖然可以知曉自己的操作時成功或者失敗,卻無法知道其他節點的操作的成功或失敗。當一個事務跨越多個節點時,爲了保持事務的 ACID 特性,需要引入一個作爲協調者的組件來統一掌控所有節點(稱作參與者)的操作結果並最終指示這些節點是否要把操作結果進行真正的提交(比如將更新後的數據寫入磁盤等等)。

因此,二階段提交的算法思路可以概括爲:參與者將操作成敗通知協調者,再由協調者根據所有參與者的反饋情報決定各參與者是否要提交操作還是中止操作。

1、準備階段

事務協調者(事務管理器)給每個參與者(資源管理器)發送 Prepare 消息,每個參與者要麼直接返回失敗(如權限驗證失敗),要麼在本地執行事務,寫本地的 redo 和 undo 日誌,但不提交,到達一種“萬事俱備,只欠東風”的狀態。

2、提交階段
如果協調者收到了參與者的失敗消息或者超時,直接給每個參與者發送回滾(Rollback)消息;否則,發送提交(Commit)消息;參與者根據協調者的指令執行提交或者回滾操作,釋放所有事務處理過程中使用的鎖資源。(注意:必須在最後階段釋放鎖資源)

3、兩階段提交存在的缺點

(1)參與者:同步阻塞問題
執行過程中,所有參與節點都是事務阻塞型的。

(2)協調者:單點故障
由於協調者的重要性,一旦協調者發生故障。參與者會一直阻塞下去。

(3)參與者:數據不一致 (腦裂問題)
在二階段提交的階段二中,當協調者向參與者發送 commit 請求之後,發生了局部網絡異常或者在發送 commit 請求過程中協調者發生了故障,導致只有一部分參與者接受到了commit 請求。於是整個分佈式系統便出現了數據部一致性的現象(腦裂現象)。

(4)協調者:二階段無法解決的問題 (數據狀態不確定)
協調者再發出 commit 消息之後宕機,而唯一接收到這條消息的參與者同時也宕機了。那麼即使協調者通過選舉協議產生了新的協調者,這條事務的狀態也是不確定的,沒人知道事務是否被已經提交。


Question13:介紹一下數據庫三階段提交協議?

Answer13:

三 階 段 提 交 ( Three-phase commit ) , 也 叫 三 階 段 提 交 協 議 ( Three-phase commit protocol),是二階段提交(2PC)的改進版本。

與兩階段提交不同的是,三階段提交有兩個改動點。

1、引入超時機制。同時在協調者和參與者中都引入超時機制。

2、在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段之前各參與節點的狀態是一致的。也就是說,除了引入超時機制之外,3PC 把 2PC 的準備階段再次一分爲二,這樣三階段提交就有 CanCommit、PreCommit、DoCommit 三個階段。

(1)CanCommit 階段
協調者向參與者發送 commit 請求,參與者如果可以提交就返回 Yes 響應,否則返回 No 響應。

(2)PreCommit 階段
協調者根據參與者的反應情況來決定是否可以繼續進行,有以下兩種可能。假如協調者從所有的參與者獲得的反饋都是Yes響應,那麼就會執行事務的預執行;假如有任何一個參與者向協調者發送了 No 響應,或者等待超時之後,協調者都沒有接到參與者的響應,那麼就執行事務的中斷。

(3)doCommit 階段
該階段進行真正的事務提交,主要包含
a.協調者發送提交請求
b.參與者提交事務
c.參與者響應反饋( 事務提交完之後,向協調者發送 Ack 響應,告訴協調者自己提交完了)
d.協調者確定完成事務。


Question14:介紹一下CAP原則?

Answer14:

CAP 原則又稱 CAP 定理,指的是在一個分佈式系統中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),三者不可得兼。

一致性(C)
在分佈式系統中的所有數據備份,在同一時刻是否同樣的值(等同於所有節點訪問同一份最新的數據副本)。

可用性(A)
在集羣中一部分節點故障後,集羣整體是否還能響應客戶端的讀寫請求(對數據更新具備高可用性)。

分區容忍性(P)
以實際效果而言,分區相當於對通信的時限要求。系統如果不能在時限內達成數據一致性,就意味着發生了分區的情況,必須就當前操作在 C 和 A 之間做出選擇。


Question15:談一談對柔性事務的認識?

Answer15:

BASE 理論是在 CAP 理論的基礎之上的延伸,包括 基本可用(Basically Available)、柔性狀態(Soft State)、最終一致性(Eventual Consistency)。

通常所說的柔性事務分爲:兩階段型、補償型、異步確保型、最大努力通知型幾種。

1、兩階段型

就是分佈式事務兩階段提交,對應技術上的 XA、JTA/JTS。這是分佈式環境下事務處理的典型模式。

2、補償型

TCC 型事務(Try/Confirm/Cancel)可以歸爲補償型。

WS-BusinessActivity 提供了一種基於補償的 long-running 的事務處理模型。服務器 A 發起事務,服務器 B 參與事務,服務器 A 的事務如果執行順利,那麼事務 A 就先行提交,如果事務 B 也執行順利,則事務 B 也提交,整個事務就算完成。但是如果事務 B 執行失敗,事務 B 本身回滾,這時事務 A 已經被提交,所以需要執行一個補償操作,將已經提交的事務 A 執行的操作作反操作,恢復到未執行前事務 A 的狀態。這樣的 SAGA 事務模型,是犧牲了一定的隔離性和一致性的,但是提高了 long-running 事務的可用性。

在這裏插入圖片描述

3、異步確保型
通過將一系列同步的事務操作變爲基於消息執行的異步操作, 避免了分佈式事務中的同步阻塞操作的影響。

在這裏插入圖片描述

4、最大努力通知型 (多次嘗試)
這是分佈式事務中要求最低的一種, 也可以通過消息中間件實現, 與前面異步確保型操作不同的一點是, 在消息由 MQ Server 投遞到消費者之後, 允許在達到最大重試次數之後正常結束事務。


Question16:介紹一下分佈式緩存(包括緩存雪崩、緩存穿透等)?

Answer16:

1、常見問題:緩存雪崩

緩存雪崩我們可以簡單的理解爲:由於原有緩存失效,新緩存未到期間所有原本應該訪問緩存的請求都去查詢數據庫了,而對數據庫 CPU 和內存造成巨大壓力,嚴重的會造成數據庫宕機。從而形成一系列連鎖反應,造成整個系統崩潰。一般有三種處理辦法:

  1. 一般併發量不是特別多的時候,使用最多的解決方案是加鎖排隊。
  2. 給每一個緩存數據增加相應的緩存標記,記錄緩存的是否失效,如果緩存標記失效,則更新數據緩存。
  3. 爲 key 設置不同的緩存失效時間。

2、 常見問題:緩存穿透

緩存穿透是指用戶查詢數據,在數據庫沒有,自然在緩存中也不會有。這樣就導致用戶查詢的時候,在緩存中找不到,每次都要去數據庫再查詢一遍,然後返回空(相當於進行了兩次無用的查詢)。這樣請求就繞過緩存直接查數據庫,這也是經常提的緩存命中率問題。

有很多種方法可以有效地解決緩存穿透問題,最常見的則是採用布隆過濾器,將所有可能存在的數據哈希到一個足夠大的 bitmap 中,一個一定不存在的數據會被這個 bitmap 攔截掉,從而避免了對底層存儲系統的查詢壓力。另外也有一個更爲簡單粗暴的方法,如果一個查詢返回的數據爲空(不管是數據不存在,還是系統故障),我們仍然把這個空結果進行緩存,但它的過期時間會很短,最長不超過五分鐘。通過這個直接設置的默認值存放到緩存,這樣第二次到緩衝中獲取就有值了,而不會繼續訪問數據庫。

3、常見技巧:緩存預熱

緩存預熱就是系統上線後,將相關的緩存數據直接加載到緩存系統。這樣就可以避免在用戶請求的時候,先查詢數據庫,然後再將數據緩存的問題!用戶直接查詢事先被預熱的緩存數據!

4、常見技巧:緩存更新

緩存更新除了緩存服務器自帶的緩存失效策略之外(Redis 默認的有 6 中策略可供選擇),我們還可以根據具體的業務需求進行自定義的緩存淘汰,常見的策略有兩種:
(1)定時去清理過期的緩存;
(2)當有用戶請求過來時,再判斷這個請求所用到的緩存是否過期,過期的話就去底層系統得到新數據並更新緩存。

5、常見技巧:緩存降級

當訪問量劇增、服務出現問題(如響應時間慢或不響應)或非核心服務影響到核心流程的性能時,仍然需要保證服務還是可用的,即使是有損服務。系統可以根據一些關鍵數據進行自動降級,也可以配置開關實現人工降級。降級的最終目的是保證核心服務可用,即使是有損的。而且有些服務是無法降級的(如加入購物車、結算)。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章