大廠都咋用平臺、分佈式緩存?起碼你要懂技術,高級還得懂業務

image
全部程序猿都對那緩存並不陌生,好似那風同樣的女子只爲你獨自而舞。只見那回眸一笑百媚生,讓你甚是吝惜,惹人憐愛。docker

但隨着項目規模不斷增大變強,光是單個緩存就難以招架,優而顯得力不從心。數據庫

這時伴隨着多級緩存得化繭成蝶,平臺級緩存和分佈式緩存在應用上就都相輔相成。編程

但一山難容二虎,每每存有3大問題——①概念難以區分②我到底應該選擇誰③各自適用於什麼場景segmentfault

若是這個沒弄明白,我怕是以爲你還不大行額。

本篇我將已老生常談的態度來爲你們一一揭曉,同時掌握方案與場景,設計技術選型的原理。包括一線大廠在本章節可能涉及的常考點
image緩存

何爲平臺級緩存與分佈式緩存?

平臺級緩存是指你所選擇編程語言下的緩存技術類型服務器

它是在語言的前提條件下,來採用的緩存技術,也就是你用什麼語言,就採用它存在的緩存技術。微信

緩存是工具,供編程語言調用。前者爲後者服務,得有一個主次的關係。
因此有時 你要控制你本身呀,別給本身飆車的速度,否則翻車了你都不知道

好比:
你在淘寶開了個新店鋪,這時你須要對你的店鋪進行裝飾打扮,那就須要使用淘寶這個平臺上提供的功能來進行裝飾。
像上傳商品配圖、店鋪佈局風格等。
換句話說平臺級緩存是依附於平臺的特性而決定的。

上篇也提到在不一樣的編程語言下,平臺級緩存也不相同,好比:網絡

  • PHP裏面Smarty模板庫
  • Java中如Ehcache,Cacheonix,Voldemort,JBoss Cache,OSCache等等。

並且按照應用層的定義來看,平臺級緩存可根據進程執行使用的方式劃分爲進程內緩存和進程外緩存。架構

那什麼是進程內、進程外緩存呢?
  • 進程內緩存

就是緩存數據存在於所屬應用進程以內,和應用業務代碼、變量、堆棧等類型共同享受應用進程的內存資源。 緩存就是在進程內中的數據段進行站位。併發

或者說原來你1人住1房間,如今你和別人一塊兒住。

  • 進程外緩存

指緩存數據存儲的地方不在使用應用內,而是外部的其它進程來存儲。好比像:Redis、memcache之類。

那若是緩存以文件形式保持咋辦呀? 也算應用進程外?
放心,我乃吒吒輝,而不是渣渣輝。呸,渣男

因大多數緩存都是在內存裏面來進行操做,因此經常會忽視以文件形式來保存的數據文件。像這種狀況它仍是平臺級緩存下的進程內緩存,不是進程外緩存。

由於這個文件的緩存是服務於應用進程,而你像Redis那種角色,它是獨立的進程,進程和進程自己是有隔離的,並且它們仍是不一樣軟件的進程,就更沒得啥關係。

並且文件緩存裏面的內容都是提早把邏輯處理的數據存入進取。當使用時,就能夠減小重複的讀取、計算數據的動做從而來達到緩存的效果。

那若是我把Redis獨立部署到其它服務器裏面,也是進程外緩存嗎?

image

這樣的狀況它就是了,上面提到進程外緩存是相對應用進程而言的,如今它們存在於不一樣的服務器。若是是在同一臺服務器裏面部署。那也算進程外緩存,由於進程是隔離的,但通常Redis部署到其它服務器咱們不會這樣稱呼

那它這叫啥呢?

這種狀況稱分佈式緩存,常說的分佈式緩存就是這種形式存在於世。

分佈式緩存也很好理解,首先看分佈式,它表示把不一樣的軟件分別部署在不一樣的服務器上或者同一服務器上不一樣的軟件服務。

注:這裏【分佈式緩存】是個相對概念,若是按分佈式概念看,一臺服務器上部署了PHP|JAVA和Redis。它們之間的關係也算分佈式。
但咱們如今是從 進程內外緩存的概念劃分。這樣一看,它就不屬於分佈式緩存了。你們知道統一的說法便可

哎呀,累死我的,吒男能這樣,面面俱到?有點繞,你老慢着點,細細品味

image

爲什麼使用平臺級與分佈式緩存?

不管什麼類型的緩存,使用它們的根本目標就是減小數據的邏輯運算,加快請求響應,進而提升網站的QPS。 只不過體現的地方是不同的罷了。

那平臺級和分佈式緩存都有神馬好處?

平臺級

優勢:

  • 時延更低,可以節省內網帶寬

平臺級緩存,因爲數據不須要跨網絡傳輸,直接在本地內存中操做。故性能好,時延低,消耗的帶寬也較少。

  • 不須要引入第三方類庫,開箱即用

通常平臺級緩存,都會有官方提供的相關操做類庫,並不須要引入第三方的類庫,下降了業務開發的關聯。

缺點:

  • 存儲容量有限,沒法進行大數據存儲

因爲內存佔用了應用進程的內存空間,如 Java 進程的 JVM 內存空間,故不能進行大數據量的數據存儲。

  • 微服務架構中,集羣部署數據的更新問題。

平臺緩存數據存儲於應用進程內,故沒法被其餘應用進程訪問,在集羣部署中同一緩存數據須要部署多份。

若是對應數據庫的數據,存在更新動做,則須要同步更新到不一樣部署節點的本地緩存,這樣才能保證數據一致性。這時複雜度較高而且容易出錯。

能夠採用如基於 Redis 的發佈訂閱機制來同步更新各個部署節點或者中間件進行異步數據更新。

  • 數據隨應用進程的重啓或崩潰而丟失

平臺緩存數據是存儲在應用進程的內存空間,因此當應用進程重啓時,緩存數據也會丟失。因此對於須要持久化的數據,要注意及時保存,不然可能會形成數據丟失。

分佈式緩存

優勢:

  • 性能、存儲容量無上限,理論上可作到無限擴充

雖然本地緩存快,但終究在單機上,資源性能都有上限。

而分佈式緩存是獨立部署的進程,自身擁有獨立的內存空間,不會受到應用進程重啓的影響,同時硬件資源也是獨享。

若是一臺機器性能不夠,就能夠採用集羣的方式拓展,作到線性的擴容。在配合docker容器,瞬間 beautiful

  • 數據集中存儲,保證數據一致性,也作到了業務上的解耦

image
雖然緩存是以分佈式的方式存儲,但部署模式會採用集羣來保證高可用。

這樣全部的緩存數據都維護在緩存集羣當中,故不存在像本地緩存數據更新的問題,也保證了不一樣節點應用進程的數據一致性問題。

之前緩存和業務是在一塊兒使用,如今業務和緩存剝離開來,互不影響,從而作到了業務上的拆分。

  • 數據從業務上作讀寫分離,保證網站高性能,高可用

分佈式緩存通常支持數據副本機制,從業務上課實現讀寫分離,故能夠解決高併發場景中併發讀寫性能問題。

因爲在多個緩存節點也冗餘了數據,提升了緩存數據的可用性,避免某個緩存節點宕機致使數據不可用問題。

那什麼是讀寫分離?

讀寫分離是指把網站中用戶請求,按照讀、寫請求進行劃分。經常須要配合MySQL主從,主庫針對用戶寫請求,從庫針對用戶讀請求。

若是不作讀寫分離那麼請求都會走一臺機器。因此讀寫分離在必定程度上也作到了負載均衡,還能夠針對單一類型的請求來作到專治。
image

好比:主庫針對寫請求,那能夠省去索引的建立,而從庫針對讀請求,須要索引來處理。這樣就能夠根據請求類型來選擇是否使用索引。

畢竟索引維護也是須要消耗資源的。誰讓咋的心眼兒細呢?不當心看到了

原來讀寫分離就是這樣的啊,那我知道了

這個,其實這裏小吒只是拋轉引玉了下,但大體意思都差很少,根本就是把讀寫請求分開,而後進行專治。

又好比:針對網站架構時,也能夠採用讀寫分離的機制來部署網站子系統,針對搜索的業務,能夠徹底獨立部署search_product.com。由它來提供搜索頁面。

再來好比:針對要提升業務的處理能力,我們緩存的主從架構照樣可配合讀寫分離,加速網站的處理。

還來好比:針對訪問量太高,能夠經過讀寫隊列來進行流量消費和異步批量寫機制,來提升網站的處理能力和寫負載太高等問題。
等等還有其它的,但你們要明白讀寫分離的做用,並且有時候它還會配合業務進行調整的。

你TM吒吒輝有完沒完了,一口氣說完不行了,我這個暴脾氣給你慣得。

缺點:

  • 運維和部署上成本高

因爲是分佈式部署方式,部署、運維起來仍是比較有技術難度,由於每臺服務器的運行狀況你確定都要知道,外加線上環境的不肯定因素。直接頭大

但方案能抗住大流量,方案仍是可取,同時基於Docker在部署上也會減輕不少壓力。 橫豎你都佔同樣嘛,否則咋個辦呢?

  • 技術結構複雜,須要考慮緩存雪崩、擊穿等問題

分佈式緩存中的數據量確定很多,對業務方來講須要,考慮緩存的擊穿、雪崩、穿透等問題,防止意外狀況下請求直接打到數據庫形成數據庫崩潰的問題。

  • 數據跨網絡傳輸,性能低於本地緩存

分佈式緩存部署通常都是與應用進程位於不一樣的機器,故須要經過外網來進行網絡數據傳輸,相對於平臺緩存的進程內部數據讀取操做,性能會較低。

平臺級與分佈式緩存的技術選項?

每一個技術都會有本身的立場,在什麼狀況來選擇用什麼樣的技術內容。仍是得根據你項目需求狀況來進行選擇

  • 看速度?選平臺級緩存

平臺緩存的優點就是處於應用進程內部,離程序是最近的。若是某部分數據不大,可是訪問量比較高,直接使用它來作處理。 簡直是省心有省力氣,在加上AOP切面編程,簡直舒服的不要不要的。

例如:

若是想首頁、活動頁裏面的展現一些統計或推薦的信息。有了它就不用每次都去調用相同API來進行運算操做,只要記得定時更新平臺緩存便可。

  • 看數據量?選分佈式緩存

平臺緩存受限於應用進程方,存儲有限,在大流量、海量數據的規模狀況下,確定選擇分佈式緩存,基於水平擴容、讀寫分離來知足業務場景、數據存儲、性能需求等。

  • 綜合來看,有規模選分佈式緩存,規模通常選擇進程外緩存。規模小你老看着辦?

網站上到大規模,你分佈式那都跑不脫。
爲了知足高可用、高可靠機制,通常都會採用分佈式集羣的方式部署,這樣一個業務,會有多臺機器來提供服務,就算掛了一個主機,還有其它的頂上來。

那選擇平臺級緩存有何問題?
  • 若是多機器採用平臺緩存,那緩存就有多份,一旦數據變動,就須要通知到多個上游服務方來更新數據。
  • 微服務模式下,一個頁面模塊的展現數據,在調用一個服務時可能須要拿到多個服務的數據聚合以後,才能最後返回給客戶端展現。

這樣一個服務的數據發生變化就須要通知到剛開始調的服務來更新緩存,業務上就耦合起來,並且還加入了不少附加工做,嚴重影響性能。

  • 數據的一致性問題,一個服務更新,若是網絡有延遲或意外,致使更新的請求失敗,那麼數據庫和緩存的數據就存在不一致。

總結

  • 網站規模建議採用分佈式緩存,由於業務方和緩存就不須要在業務上耦合,後期架構調整和維護都比較輕鬆。
  • 場景上選什麼仍是得根據業務需求和架構設計來綜合考慮,我的不大推薦平臺緩存,業務職責更加清晰些,可能更好些。

思考題

  1. 什麼是分佈式緩存?你用什麼來作?什麼條件下使用它?
  2. 平臺級緩存你經常使用哪一種?平臺級和分佈式緩存存在什麼優缺點?
  3. 平臺級和分佈式分別適合什麼場景?
  4. 什麼是讀寫分離?你有那些應用
若是感受文章有幫助的話,求再看、求關注、求分享、求留言。各位的點贊支持,都是我創做的最大動力。

其實還有不少優化、架構等東西未分享,怕偏提,那我們下期見。同時爲了更好的幫助你們,我也整理了以下內容:
image

須要的小夥伴可微信搜索【蓮花童子哪吒】,這些其實還須要你們一塊兒與我不斷完善,畢竟我我的是有限的,期待你的留言補充
相關文章
相關標籤/搜索