三高項目-緩存設計
分流、并發
導流:將原本復雜操作的請求,引導到簡單的操作上。以后再來查,不需要經過復雜的計算。
成本:空間,收益:節省了時間。
不要以為僅僅是 redis,map等。
對應。kv值。
1計算k,2 查詢k,3 得到值,做轉換。
如果能做好對應,最好,做不好對應呢? 命中率。沒有命中的緩存,查原數據。
數據的查詢時間:時間(123)+(1-命中率p)*查原數據的時間。
命中率=緩存中能查到的數據/數據庫總數據
如何 提升緩存的收益:
減少 123時間。
提高命中率(*)。
應用場景:
讀多寫少用緩存。
查詢原數據時間特別長的場景。
Key
鍵K有關
生成時間
不同功能業務的,key值要不一樣,否則會被覆蓋。
要唯一,避免碰撞。
單向函數:hash。給定輸入的情況下,很容易計算出結果,而給定結果的情況下,幾乎不可能計算出輸入值。
一般不存在。正向快速,逆向困難,輸入敏感,沖突避免。
md4 , md5,sha-0,sha-1,sha-2(用)
查詢時間
緩存的位置。內存,硬盤,本地。
數據結構。
1234567890
234567890-
equals,hashcode。
鍵總結
無碰撞(唯一),高效生成(不需要,約定好),高效比較。
系統標識+功能標識+業務標識+前后綴。
13910712345+vcode: 123456
公司統一標準。
值
序列化值(二進制),對象值。
數據污染:
0-0.5-1 1-2 存的不是最終值
緩存只是 在 調用方和 數據提供方之間的一個 暫存方。
統一:緩存中數據怎么來的,查詢的時候,如果沒有,就從數據提供方獲取,然后放到緩存中。
緩存的更新機制
時效性更新機制
固定時間過期,被動更新
:緩存中的數據設置一個過期時間。如果緩存數據過期,那么,我會去提供方查詢,這樣就相當于將 提供方 的數據 更新到緩存中了。
放棄了:實時一致性。(商品關注人數,評論數,瀏覽量,評論點贊收藏)
讀,
寫:只寫數據提供方。不理會緩存。
主動更新機制
清風:cap。
cache aside
寫:先更新,更新數據提供方,刪除緩存。
概率很低:
1。 讀的時候,緩存里 沒有數據。
2。 讀的時候,有寫在同時進行。
3。讀的時長大于 寫操作。(不那么容易發生 1%)。
4。 讀寫操作 同時發生時,讀到的是舊值。50%。
可以用。鴕鳥算法。
在計算機科學中,鴕鳥算法?是一個忽略潛在問題的一種算法策略,這種策略對計算機程序可能出現的問題采取無視態度(類似于鴕鳥在遇到危險時將頭埋在地里,裝作看不見)。鴕鳥算法的使用前提是,問題出現的概率很低。
三高項目-緩存
雙寫一致性
先刪除緩存,再更新數據提供方。 延遲雙刪。
1。更新緩存,更新數據庫。更容易造成數據的不一致,緩存成功,數據提供方失敗。更糟糕。
2。更新數據庫,更新緩存。有缺點,一點點稍微可取。
缺點:A 更新了數據庫。B更新了數據庫,B更新了緩存,A更新了緩存。
空干活,經過復雜的計算,給緩存設置值,但是用的少,浪費了資源。
3。刪除緩存,更新數據庫。延遲雙刪
4。更新數據庫,刪掉緩存。上節課所說的額cache aside。
延遲雙刪:刪除緩存,更新數據提供方,睡眠一段時間(根據實際業務),再刪除緩存。
如果第二次 刪除失敗了,怎么辦? 重試一下。
自己寫重試代碼,沒問題。自己掛了呢?
轉移風險。重試的組件? 消息隊列。
上面所說的,不管方案多么復雜,完善,總不能保證一致性。
Read/Write Through
直接 將 結果寫入緩存。再從緩存 同步到數據提供方。調用方只需要和緩存交互。
寫成功標識:緩存成功,數據提供方成功。TCC。
初始化:1。 啟動緩存,從數據提供方,初始化。2。讀取緩存 ,初始化。
緩存預熱。命中率低,慢慢的命中率才高。
保障:緩存 非常 可靠。
Write Behind
在上面 做了升級,異步寫入到數據提供方。加入消息隊列,保證最終一致性。
緩存空間足夠大,能緩存所有的數據,命中率 100%。
清理機制
以提高緩存命中率為目標。
過去訪問多的,未來訪問也多。
最近被更新的,未來訪問的多。
時效性清理
過期全部清理。要求緩存中的數據都有一個生存期,有效期。
1條數據:data,ttl。2min。
輪詢時效清理:額外開啟一個程序,定期掃描所有數據的有效期,到期了,干掉。
自動時效清理:cookie。本質:上面的 輪詢。
數目閾值清理
1 條數,2 每條的大小。
FIFO: 隊列大小是10,
LRU:左神算法。數據訪問次數,頭部,刪尾部。
LinkedHashMap 都可以實現 fifo,lru。
如果空間充足,則緩存多多的,提高命中率。如果空間不夠,再回收空間,把空間給其他人讓出來。
垃圾回收。
強引用:只要被強引用,就不會被回收。內存不足時,哪怕自己掛掉,也不回收。
軟引用:空間不足時,才會被回收。
弱引用,虛引用。
SoftReference。 java實現它。
用java實現一個 根據內存空間大小的使用情況,做一個緩存組件。
Map?<k,SoftReference<>>。
實戰:
時效性清理+數據閾值式= 1。過期就干掉。2,密集查詢,導致空間急劇增大。
LRU+軟引用:保證最近用的數據在,然后最近不用的,放到軟引用里,用軟引用包裝一下。
不建議:只用軟引用。緩存的存活與否,從業務逃脫。業務控制不了。
三高項目
緩存風險點
每增加一個環節,就多一個風險。
緩存穿透
緩存沒有數據,數據提供方也沒有數據,穿透了。
無效的調用,增加數據提供方的壓力,緩存基本無效。
解決方案:在緩存中,緩存一份 空數據。key有值,value為空。
緩存雪崩
大量緩存突然失效,引發的數據提供方壓力 驟增。
數據閾值式清理:(緩存是逐個失效的)閾值比較低的時候會。10個緩存。閾值高,可以緩解。
時效式清理:會造成雪崩。避免緩存在同一時刻失效。過期時間=固定值+隨機值。錯峰失效。
軟引用清理:當空間緊張的時候,緩存占據的空間會被回收。單純的軟引用無法解決。lru:對經常訪問的數據建立強引用。
緩存擊穿
有數據提供方 兜底,不叫穿透。
lru:高頻訪問的數據,大概率在前面 fifo。
read/write through, write behind。更新機制。緩存里有沒有?因為數據的寫、更新,先操作的是緩存。
cache aside: 有一個節點,緩存被刪除。可能有擊穿。
實際工作:
清理機制+更新機制,針對緩存,共同考慮。
緩存預熱
啟動系統的時候,提前加載一些數據。預加載。
緩存服務啟動后,腳步直接灌入。init
時效式清理機制:緩存重復預熱。
緩存的位置
需要緩存的數據,一定要靠前。。要想系統性能好,緩存一定要趁早。
前置模塊:減少和后端通信的成本。
后置模塊:公共模塊,盡量用這個方式。
客戶端緩存
客戶端:瀏覽器,c軟件,安卓,ios,h5,小程序。
瀏覽器:cookie,過期時間。輕量級的緩存。
F12 application。h5支持 & 瀏覽器的支持。
sqlite :安卓端的一個數據庫。規則類。開機圖片,引導頁。
cdn 靜態緩存
靜態資源:頁面,圖片。
數據:重點:地名,字典,行業分類,統計局 那些標準化的數據。三級聯動。算。廣義:與用戶個體無關的具有通用性的數據,都可以作為靜態數據。
數據:用戶不同,參數不同,時間不同,----結果不同。 對系統性能造成負面影響。
服務端緩存
redis。localcache,guava。
數據庫緩存
冗余字段,中間表
操作完業務,需要做統計,非實時的數據,讓它后置。
新增訂單:
insert order (xxxxxx), 統計表 (訂單數據 + 1) 10s。
5s, 定時任務掃描(48h-24h) +10。
冗余字段:
訂單表(商品的數據)快照。
三高項目
寫緩存
讀緩存。調用方 數據提供方。
寫緩存:調用方和 數據 處理方之間。目的:減少巨量調用操作對數據處理方的沖擊。庫存。削峰。
消息隊列。
寫緩存收益:原始時間 <(寫緩存時間+緩存中數據向后傳遞的時間+原始時間)
收益在于用戶的角度:目標用戶的響應時間 降低了。
讀緩存:是以緩存命中的數據 替代 數據提供方的操作。
寫緩存:通過增加額外花費的時間,來延遲數據處理方的工作。
寫緩存實踐:redis(發布訂閱),消息隊列(發布訂閱),數據庫(先生成數據,后期再進行統計,耗時的&對實時性要求不高的,后置)
適合場景:請求峰谷值變化明顯&對實時性要求不高的系統中。
搶購系統,競品系統,秒殺系統,搶紅包系統。
消息推送系統:極光,百度。
實時性不高。
大廠:
需求:平峰(請求量在某個閾值之下):正常處理。峰值超過閾值的時候,觸發寫緩存。
降級:微服務降級組件處理可以。
灰度發布。配置灰度規則(規則中 請求的閾值,根據閾值的不同,調用不同的系統)。
限流。要對流量進行 評估。
面試:寫的訪問量增大,怎么處理。
下單:訂閱消息,不重要的系統訂閱關鍵 業務的數據。