阿里P8架構師談:分佈式緩存的應用場景、選型比較、問題和挑戰

爲何要使用分佈式緩存

高併發環境下,例如典型的淘寶雙11秒殺,幾分鐘內上億的用戶涌入淘寶,這個時候若是訪問不加攔截,讓大量的讀寫請求涌向數據庫,因爲磁盤的處理速度與內存顯然不在一個量級,服務器立刻就要宕機。從減輕數據庫的壓力和提升系統響應速度兩個角度來考慮,都會在數據庫以前加一層緩存,訪問壓力越大的,在緩存以前就開始CDN攔截圖片等訪問請求。面試

而且因爲最先的單臺機器的內存資源以及承載能力有限,若是大量使用本地緩存,也會使相同的數據被不一樣的節點存儲多份,對內存資源形成較大的浪費,所以,才催生出了分佈式緩存。redis

阿里P8架構師談:分佈式緩存的應用場景、選型比較、問題和挑戰

 

分佈式緩存應用場景

  1. 頁面緩存.用來緩存Web 頁面的內容片斷,包括HTML、CSS 和圖片等;
  2. 應用對象緩存.緩存系統做爲ORM 框架的二級緩存對外提供服務,目的是減輕數據庫的負載壓力,加速應用訪問;
  3. 解決分佈式Web部署的session同步問題,狀態緩存.緩存包括Session 會話狀態及應用橫向擴展時的狀態數據等,這類數據通常是難以恢復的,對可用性要求較高,多應用於高可用集羣。
  4. 並行處理.一般涉及大量中間計算結果須要共享;
  5. 雲計算領域提供分佈式緩存服務。

分佈式緩存比較:Memcache VS Redis

一、Redis不只僅支持簡單的k/v類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。而memcache只支持簡單數據類型,須要客戶端本身處理複雜對象數據庫

二、Redis支持數據的持久化,能夠將內存中的數據保持在磁盤中,重啓的時候能夠再次加載進行使用(PS:持久化在rdb、aof)。數組

三、因爲Memcache沒有持久化機制,所以宕機全部緩存數據失效。Redis配置爲持久化,宕機重啓後,將自動加載宕機時刻的數據到緩存系統中。具備更好的災備機制。緩存

四、Memcache可使用Magent在客戶端進行一致性hash作分佈式。Redis支持在服務器端作分佈式(PS:Twemproxy/Codis/Redis-cluster多種分佈式實現方式)性能優化

五、Memcached的簡單限制就是鍵(key)和Value的限制。最大鍵長爲250個字符。能夠接受的儲存數據不能超過1MB(可修改配置文件變大),由於這是典型slab 的最大值,不適合虛擬機使用。而Redis的Key長度支持到512k。服務器

六、Redis使用的是單線程模型,保證了數據按順序提交。Memcache須要使用cas保證數據一致性。CAS(Check and Set)是一個確保併發一致性的機制,屬於「樂觀鎖」範疇;原理很簡單:拿版本號,操做,對比版本號,若是一致就操做,不一致就放棄任何操做網絡

cpu利用。因爲Redis只使用單核,而Memcached可使用多核,因此平均每個核上Redis在存儲小數據時比Memcached性能更 高。而在100k以上的數據中,Memcached性能要高於Redis 。session

七、memcache內存管理:使用Slab Allocation。原理至關簡單,預先分配一系列大小固定的組,而後根據數據大小選擇最合適的塊存儲。避免了內存碎片。(缺點:不能變長,浪費了必定空間)memcached默認狀況下下一個slab的最大值爲前一個的1.25倍。數據結構

八、redis內存管理: Redis經過定義一個數組來記錄全部的內存分配狀況, Redis採用的是包裝的malloc/free,相較於Memcached的內存 管理方法來講,要簡單不少。因爲malloc 首先以鏈表的方式搜索已管理的內存中可用的空間分配,致使內存碎片比較多。

在此我向你們推薦一個Java高級羣 :725633148 裏面會分享一些資深架構師錄製的視頻錄像:(有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構、面試資料)等這些成爲架構師必備的知識體系 進羣立刻免費領取,目前受益良多!

分佈式緩存選型總結

其實對於企業選型Memcache、Redis而言,更多仍是應該看業務使用場景(由於Memcache、Redis二者都具備足夠高的性能和穩定性)。倘若業務場景須要用到持久化緩存功能、或者支持多種數據結構的緩存功能,那麼Redis則是最佳選擇。

(PS:Redis集羣解決方式也優於Memcache,Memcache在客戶端一致性hash的集羣解決方案,Redis採用無中心的服務器端集羣解決方案)

綜上所述:爲了讓緩存系統可以支持更多的業務場景,選擇Redis會更優。

分佈式緩存的常見問題和挑戰

1.緩存雪崩

緩存雪崩咱們能夠簡單的理解爲:因爲原有緩存失效,新緩存未到期間(例如:咱們設置緩存時採用了相同的過時時間,在同一時刻出現大面積的緩存過時),全部本來應該訪問緩存的請求都去查詢數據庫了,而對數據庫CPU和內存形成巨大壓力,嚴重的會形成數據庫宕機。從而造成一系列連鎖反應,形成整個系統崩潰。

2.緩存穿透

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

3.緩存預熱

緩存預熱這個應該是一個比較常見的概念,相信不少小夥伴都應該能夠很容易的理解,緩存預熱就是系統上線後,將相關的緩存數據直接加載到緩存系統。這樣就能夠避免在用戶請求的時候,先查詢數據庫,而後再將數據緩存的問題!用戶直接查詢事先被預熱的緩存數據!

4.緩存更新

除了緩存服務器自帶的緩存失效策略以外,咱們還能夠根據具體的業務需求進行自定義的緩存淘汰,常見的策略有兩種:

(1)定時去清理過時的緩存;

(2)當有用戶請求過來時,再判斷這個請求所用到的緩存是否過時,過時的話就去底層系統獲得新數據並更新緩存。

二者各有優劣,第一種的缺點是維護大量緩存的key是比較麻煩的,第二種的缺點就是每次用戶請求過來都要判斷緩存失效,邏輯相對比較複雜!具體用哪一種方案,你們能夠根據本身的應用場景來權衡。

5.緩存降級

當訪問量劇增、服務出現問題(如響應時間慢或不響應)或非核心服務影響到核心流程的性能時,仍然須要保證服務仍是可用的,即便是有損服務。系統能夠根據一些關鍵數據進行自動降級,也能夠配置開關實現人工降級。

降級的最終目的是保證核心服務可用,即便是有損的。並且有些服務是沒法降級的(如加入購物車、結算)。

在進行降級以前要對系統進行梳理,看看系統是否是能夠丟卒保帥;從而梳理出哪些必須誓死保護,哪些可降級;好比能夠參考日誌級別設置預案:

(1)通常:好比有些服務偶爾由於網絡抖動或者服務正在上線而超時,能夠自動降級;

(2)警告:有些服務在一段時間內成功率有波動(如在95~100%之間),能夠自動降級或人工降級,併發送告警;

(3)錯誤:好比可用率低於90%,或者數據庫鏈接池被打爆了,或者訪問量忽然猛增到系統能承受的最大閥值,此時能夠根據狀況自動降級或者人工降級;

(4)嚴重錯誤:好比由於特殊緣由數據錯誤了,此時須要緊急人工降級。

相關文章
相關標籤/搜索