億級系統的Redis快取如何設計???
知識分享,以技會友。大家好,我是Tom哥。閱讀本文大約需要 15 分鐘。
快取設計可謂老生常談了,早些時候都是採用memcache
,現在大家更多傾向使用redis
,除了知曉常用的資料儲存型別,結合業務場景有針對性選擇,好像其他也沒有什麼大的難點。
工程中引入Redis Client
二方包,初始化一個Bean例項RedisTemplate
,一切搞定,so easy。
如果是幾十、幾百併發的業務場景,快取設計
可能並不需要考慮那麼多,但如果是億級的系統呢?
首先,先了解快取知識圖譜
早期的快取用於加速CPU資料交換的RAM。隨著網際網路的快速發展,快取的應用更加寬泛,用於資料高速交換的儲存介質都稱之為快取。
使用快取時,我們要關注哪些指標?快取有哪些應用模式?以及快取設計時有哪些Tip技巧?一圖勝千言,如下:
七大經典問題
快取在使用過程不可避免會遇到一些問題,對於高頻的問題我們大概歸為了7類。具體內容下面我們一一道來
1、快取集中失效
當業務系統查詢資料時,首先會查詢快取,如果快取中資料不存在,然後查詢DB再將資料預熱到Cache
中,並返回。快取的效能比 DB 高 50~100 倍以上。
很多業務場景,如:秒殺商品、微博熱搜排行、或者一些活動資料,都是透過跑任務方式,將DB資料批次、集中預熱到快取中,快取資料有著近乎相同的過期時間
。
當過這批資料過期時,會一起過期
,此時,對這批資料的所有請求,都會出現快取失效
,從而將壓力轉嫁到DB,DB的請求量激增,壓力變大,響應開始變慢。
那麼有沒有解呢?
當然有了。
我們可以從快取的過期時間入口
,將原來的固定過期時間,調整為過期時間=基礎時間+隨機時間
,讓快取慢慢過期,避免瞬間全部過期,對DB產生過大壓力。
2、快取穿透
不是所有的請求都能查到資料,不論是從快取中還是DB中。
假如駭客攻擊了一個論壇,用了一堆肉雞訪問一個不存的帖子id
。按照常規思路,每次都會先查快取,快取中沒有,接著又查DB,同樣也沒有,此時不會預熱到Cache中,導致每次查詢,都會cache miss
。
由於DB的吞吐效能較差,會嚴重影響系統的效能,甚至影響正常使用者的訪問。
解決方案:
方案一:查存DB 時,如果資料不存在,預熱一個 特殊空值
到快取中。這樣,後續查詢都會命中快取,但是要對特殊值,解析處理。方案二:構造一個 BloomFilter
過濾器,初始化全量資料,當接到請求時,在BloomFilter
中判斷這個key是否存在,如果不存在,直接返回即可,無需再查詢快取和DB
3、快取雪崩
快取雪崩是指部分快取節點不可用,進而導致整個快取體系甚至服務系統不可用的情況。
分散式快取設計一般選擇一致性Hash
,當有部分節點異常時,採用 rehash
策略,即把異常節點請求平均分散到其他快取節點。但是,當較大的流量洪峰到來時,如果大流量 key 比較集中,正好在某 1~2 個快取節點,很容易將這些快取節點的記憶體、網路卡過載,快取節點異常 Crash,然後這些異常節點下線,這些大流量 key 請求又被 rehash 到其他快取節點,進而導致其他快取節點也被過載 Crash,快取異常持續擴散,最終導致整個快取體系異常,無法對外提供服務。
解決方案:
方案一:增加實時監控,及時預警。透過機器替換、各種故障自動轉移策略,快速恢復快取對外的服務能力 方案二:快取增加多個副本,當快取異常時,再讀取其他快取副本。為了保證副本的可用性,儘量將多個快取副本部署在不同機架上,降低風險。
4、快取熱點
對於突發事件,大量使用者同時去訪問熱點資訊,這個突發熱點資訊所在的快取節點就很容易出現過載和卡頓現象,甚至 Crash,我們稱之為快取熱點。
這個在新浪微博經常遇到,某大V明星出軌、結婚、離婚,瞬間引發數百千萬的吃瓜群眾圍觀,訪問同一個key,流量集中打在一個快取節點機器,很容易打爆網路卡、頻寬、CPU的上限,最終導致快取不可用。
解決方案:
首先能先找到這個 熱key
來,比如透過Spark
實時流分析,及時發現新的熱點key。將集中化流量打散,避免一個快取節點過載。由於只有一個key,我們可以在key的後面拼上 有序編號
,比如key#01
、key#02
。。。key#10
多個副本,這些加工後的key位於多個快取節點上。每次請求時,客戶端隨機訪問一個即可
可以設計一個快取服務治理管理後臺,實時監控快取的SLA,並打通分散式配置中心,對於一些
hot key
可以快速、動態擴容。
5、快取大Key
當訪問快取時,如果key對應的value過大,讀寫、載入很容易超時,容易引發網路擁堵。另外快取的欄位較多時,每個欄位的變更都會引發快取資料的變更,頻繁的讀寫,導致慢查詢。如果大key過期被快取淘汰失效,預熱資料要花費較多的時間,也會導致慢查詢。
所以我們在設計快取的時候,要注意快取的粒度
,既不能過大,如果過大很容易導致網路擁堵;也不能過小,如果太小,查詢頻率會很高,每次請求都要查詢多次。
解決方案:
方案一:設定一個閾值,當value的長度超過閾值時,對內容啟動壓縮,降低kv的大小 方案二:評估 大key
所佔的比例,由於很多框架採用池化技術
,如:Memcache,可以預先分配大物件空間。真正業務請求時,直接拿來即用。方案三:顆粒劃分,將大key拆分為多個小key,獨立維護,成本會降低不少 方案四:大key要設定合理的過期時間,儘量不淘汰那些大key
6、快取資料一致性
快取是用來加速的,一般不會持久化儲存。所以,一份資料通常會存在DB
和快取
中,由此會帶來一個問題,如何保證這兩者的資料一致性。另外,快取熱點問題會引入多個副本備份,也可能會發生不一致現象。
解決方案:
方案一:當快取更新失敗後,進行重試,如果重試失敗,將失敗的key寫入MQ訊息佇列,透過非同步任務補償快取,保證資料的一致性。 方案二:設定一個較短的過期時間,透過自修復的方式,在快取過期後,快取重新載入最新的資料
7、資料併發競爭預熱
網際網路系統典型的特點就是流量大,一旦快取中的資料過期、或因某些原因被刪除等,導致快取中的資料為空,大量的併發執行緒請求(查詢同一個key)就會一起併發查詢資料庫
,資料庫的壓力陡然增加。
如果請求量非常大,全部壓在資料庫,可能把資料庫壓垮,進而導致整個系統的服務不可用。
解決方案:
方案一:引入一把 全域性鎖
,當快取未命中時,先嚐試獲取全域性鎖,如果拿到鎖,才有資格去查詢DB
,並將資料預熱到快取中。雖然,client端發起的請求非常多,但是由於拿不到鎖,只能處於等待狀態,當快取中的資料預熱成功後,再從快取中獲取
為了便於理解,簡單畫了個流程圖。這裡面特別注意一個點,由於有一個併發時間差,所以會有一個二次check快取是否有值的校驗,防止快取預熱重複覆蓋。
方案二:快取資料建立多個備份,當一個過期失效後,可以訪問其他備份。
寫在最後
快取設計時,有很多技巧,最佳化手段也是千變萬化,但是我們要抓住核心要素。那就是,讓訪問儘量命中快取,同時保持資料的一致性。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024924/viewspace-2937622/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何設計快取系統:快取穿透,快取擊穿,快取雪崩解決方案分析快取穿透
- 系統架構設計:程式快取和快取服務,如何抉擇?架構快取
- 解析分散式系統的快取設計分散式快取
- Mybatis的二級快取、使用Redis做二級快取MyBatis快取Redis
- 如何使用 Redis 快取Redis快取
- 聊聊如何利用redis實現多級快取同步Redis快取
- Vue 全站快取二:如何設計全站快取Vue快取
- 詳談分散式系統快取的設計細節分散式快取
- 億級流量系統架構之如何設計高容錯分散式計算系統架構分散式
- 如何快速清除 Ubuntu 的系統快取Ubuntu快取
- Redis快取篇(一)Redis是如何工作的Redis快取
- 如何設計電商行業億級使用者秒殺系統行業
- JAVA快取-Redis入門級使用Java快取Redis
- 探討下如何更好的使用快取 —— Redis快取的特殊用法以及與本地快取一起構建多級快取的實現快取Redis
- 千萬級DAU系統該如何設計
- 如何優雅的設計和使用快取?快取
- Java中的多級快取設計與實現Java快取
- 深入理解 MyBatis的二級快取的設計原理MyBatis快取
- MySQL與Redis實現二級快取MySqlRedis快取
- OpenResty+lua+redis+mysql多級快取RESTRedisMySql快取
- 使用Java和Redis構建高效能的快取系統JavaRedis快取
- PB級資料持久化快取系統——lest持久化快取
- Redis的快取穿透、快取雪崩、快取擊穿的區別Redis快取穿透
- 億級流量客戶端快取之Http快取與本地快取對比客戶端快取HTTP
- Redis快取擊穿、快取穿透、快取雪崩Redis快取穿透
- [Redis]快取穿透/快取擊穿/快取雪崩Redis快取穿透
- MyBatis快取機制(一級快取,二級快取)MyBatis快取
- 億級流量系統架構之如何設計高容錯分散式計算系統【石杉的架構筆記】架構分散式筆記
- 如何提高Redis快取命中率Redis快取
- Redis快取使用技巧和設計方案,有必要看看Redis快取
- Alluxio在多級分散式快取系統中的應用UX分散式快取
- 萬級TPS億級流水-中臺賬戶系統架構設計架構
- 虹科案例 | Redis企業雲如何透過快取輕鬆擴充套件到億級請求?Redis快取套件
- 淺談快取寫法(三):記憶體快取該如何設計快取記憶體
- 以微擎版教育系統開發為例,如何實現redis快取Redis快取
- Java進階專題(十八) 系統快取架構設計 (下)Java快取架構
- Java進階專題(十七) 系統快取架構設計 (上)Java快取架構
- mybatis快取-二級快取MyBatis快取