日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

分布式架構(gòu)原理解析

 甘甘灰 2019-05-15

1. 分布式術語

1.1. 異常

服務器宕機

內(nèi)存錯誤、服務器停電等都會導致服務器宕機,此時節(jié)點無法正常工作,稱為不可用。

服務器宕機會導致節(jié)點失去所有內(nèi)存信息,因此需要將內(nèi)存信息保存到持久化介質(zhì)上。

網(wǎng)絡異常

有一種特殊的網(wǎng)絡異常稱為——網(wǎng)絡分區(qū) ,即集群的所有節(jié)點被劃分為多個區(qū)域,每個區(qū)域內(nèi)部可以通信,但是區(qū)域之間無法通信。

磁盤故障

磁盤故障是一種發(fā)生概率很高的異常。

使用冗余機制,將數(shù)據(jù)存儲到多臺服務器。

1.2. 超時

在分布式系統(tǒng)中,一個請求除了成功和失敗兩種狀態(tài),還存在著超時狀態(tài)。

可以將服務器的操作設計為具有 冪等性 ,即執(zhí)行多次的結(jié)果與執(zhí)行一次的結(jié)果相同。如果使用這種方式,當出現(xiàn)超時的時候,可以不斷地重新請求直到成功。

1.3. 衡量指標

性能

常見的性能指標有:吞吐量、響應時間。

其中,吞吐量指系統(tǒng)在某一段時間可以處理的請求總數(shù),通常為每秒的讀操作數(shù)或者寫操作數(shù);響應時間指從某個請求發(fā)出到接收到返回結(jié)果消耗的時間。

這兩個指標往往是矛盾的,追求高吞吐的系統(tǒng),往往很難做到低響應時間,解釋如下:

  • 在無并發(fā)的系統(tǒng)中,吞吐量為響應時間的倒數(shù),例如響應時間為 10 ms,那么吞吐量為 100 req/s,因此高吞吐也就意味著低響應時間。

  • 但是在并發(fā)的系統(tǒng)中,由于一個請求在調(diào)用 I/O 資源的時候,需要進行等待。服務器端一般使用的是異步等待方式,即等待的請求被阻塞之后不需要一直占用 CPU 資源。這種方式能大大提高 CPU 資源的利用率,例如上面的例子中,單個請求在無并發(fā)的系統(tǒng)中響應時間為 10 ms,如果在并發(fā)的系統(tǒng)中,那么吞吐量將大于 100 req/s。因此為了追求高吞吐量,通常會提高并發(fā)程度。但是并發(fā)程度的增加,會導致請求的平均響應時間也增加,因為請求不能馬上被處理,需要和其它請求一起進行并發(fā)處理,響應時間自然就會增高。

可用性

可用性指系統(tǒng)在面對各種異常時可以提供正常服務的能力。可以用系統(tǒng)可用時間占總時間的比值來衡量,4 個 9 的可用性表示系統(tǒng) 99.99% 的時間是可用的。

一致性

可以從兩個角度理解一致性:從客戶端的角度,讀寫操作是否滿足某種特性;從服務器的角度,多個數(shù)據(jù)副本之間是否一致。

可擴展性

指系統(tǒng)通過擴展集群服務器規(guī)模來提高性能的能力。理想的分布式系統(tǒng)需要實現(xiàn)“線性可擴展”,即隨著集群規(guī)模的增加,系統(tǒng)的整體性能也會線性增加。

2. 數(shù)據(jù)分布

分布式存儲系統(tǒng)的數(shù)據(jù)分布在多個節(jié)點中,常用的數(shù)據(jù)分布方式有哈希分布和順序分布。

數(shù)據(jù)庫的水平切分(Sharding)也是一種分布式存儲方法,下面的數(shù)據(jù)分布方法同樣適用于 Sharding。

2.1. 哈希分布

哈希分布就是將數(shù)據(jù)計算哈希值之后,按照哈希值分配到不同的節(jié)點上。例如有 N 個節(jié)點,數(shù)據(jù)的主鍵為 key,則將該數(shù)據(jù)分配的節(jié)點序號為:hash(key)%N。

傳統(tǒng)的哈希分布算法存在一個問題:當節(jié)點數(shù)量變化時,也就是 N 值變化,那么幾乎所有的數(shù)據(jù)都需要重新分布,將導致大量的數(shù)據(jù)遷移。

一致性哈希

Distributed Hash Table(DHT):對于哈希空間 [0, 2n-1],將該哈??臻g看成一個哈希環(huán),將每個節(jié)點都配置到哈希環(huán)上。每個數(shù)據(jù)對象通過哈希取模得到哈希值之后,存放到哈希環(huán)中順時針方向第一個大于等于該哈希值的節(jié)點上。

一致性哈希的優(yōu)點是在增加或者刪除節(jié)點時只會影響到哈希環(huán)中相鄰的節(jié)點,例如下圖中新增節(jié)點 X,只需要將數(shù)據(jù)對象 C 重新存放到節(jié)點 X 上即可,對于節(jié)點 A、B、D 都沒有影響。

2.2. 順序分布

哈希分布式破壞了數(shù)據(jù)的有序性,順序分布則不會。

順序分布的數(shù)據(jù)劃分為多個連續(xù)的部分,按數(shù)據(jù)的 ID 或者時間分布到不同節(jié)點上。例如下圖中,User 表的 ID 范圍為 1 ~ 7000,使用順序分布可以將其劃分成多個子表,對應的主鍵范圍為 1 ~ 1000,1001 ~ 2000,...,6001 ~ 7000。

順序分布的優(yōu)點是可以充分利用每個節(jié)點的空間,而哈希分布很難控制一個節(jié)點存儲多少數(shù)據(jù)。

但是順序分布需要使用一個映射表來存儲數(shù)據(jù)到節(jié)點的映射,這個映射表通常使用單獨的節(jié)點來存儲。當數(shù)據(jù)量非常大時,映射表也隨著變大,那么一個節(jié)點就可能無法存放下整個映射表。并且單個節(jié)點維護著整個映射表的開銷很大,查找速度也會變慢。為了解決以上問題,引入了一個中間層,也就是 Meta 表,從而分擔映射表的維護工作。

2.3. 負載均衡

衡量負載的因素很多,如 CPU、內(nèi)存、磁盤等資源使用情況、讀寫請求數(shù)等。

分布式系統(tǒng)存儲應當能夠自動負載均衡,當某個節(jié)點的負載較高,將它的部分數(shù)據(jù)遷移到其它節(jié)點。

每個集群都有一個總控節(jié)點,其它節(jié)點為工作節(jié)點,由總控節(jié)點根據(jù)全局負載信息進行整體調(diào)度,工作節(jié)點定時發(fā)送心跳包(Heartbeat)將節(jié)點負載相關的信息發(fā)送給總控節(jié)點。

一個新上線的工作節(jié)點,由于其負載較低,如果不加控制,總控節(jié)點會將大量數(shù)據(jù)同時遷移到該節(jié)點上,造成該節(jié)點一段時間內(nèi)無法工作。因此負載均衡操作需要平滑進行,新加入的節(jié)點需要較長的一段時間來達到比較均衡的狀態(tài)。

3. 分布式理論

3.1. CAP

分布式系統(tǒng)不可能同時滿足一致性(C:Consistency)、可用性(A:Availability)和分區(qū)容忍性(P:Partition Tolerance),最多只能同時滿足其中兩項。

一致性

一致性指的是多個數(shù)據(jù)副本是否能保持一致的特性。

在一致性的條件下,系統(tǒng)在執(zhí)行數(shù)據(jù)更新操作之后能夠從一致性狀態(tài)轉(zhuǎn)移到另一個一致性狀態(tài)。

對系統(tǒng)的一個數(shù)據(jù)更新成功之后,如果所有用戶都能夠讀取到最新的值,該系統(tǒng)就被認為具有強一致性。

可用性

可用性指分布式系統(tǒng)在面對各種異常時可以提供正常服務的能力,可以用系統(tǒng)可用時間占總時間的比值來衡量,4 個 9 的可用性表示系統(tǒng) 99.99% 的時間是可用的。

在可用性條件下,系統(tǒng)提供的服務一直處于可用的狀態(tài),對于用戶的每一個操作請求總是能夠在有限的時間內(nèi)返回結(jié)果。

分區(qū)容忍性

網(wǎng)絡分區(qū)指分布式系統(tǒng)中的節(jié)點被劃分為多個區(qū)域,每個區(qū)域內(nèi)部可以通信,但是區(qū)域之間無法通信。

在分區(qū)容忍性條件下,分布式系統(tǒng)在遇到任何網(wǎng)絡分區(qū)故障的時候,仍然需要能對外提供一致性和可用性的服務,除非是整個網(wǎng)絡環(huán)境都發(fā)生了故障。

權衡

在分布式系統(tǒng)中,分區(qū)容忍性必不可少,因為需要總是假設網(wǎng)絡是不可靠的。因此,CAP 理論實際在是要在可用性和一致性之間做權衡。

可用性和一致性往往是沖突的,很難都使它們同時滿足。在多個節(jié)點之間進行數(shù)據(jù)同步時,

  • 為了保證一致性(CP),就需要讓所有節(jié)點下線成為不可用的狀態(tài),等待同步完成;
  • 為了保證可用性(AP),在同步過程中允許讀取所有節(jié)點的數(shù)據(jù),但是數(shù)據(jù)可能不一致。

3.2. BASE

BASE 是基本可用(Basically Available)、軟狀態(tài)(Soft State)和最終一致性(Eventually Consistent)三個短語的縮寫。

BASE 理論是對 CAP 中一致性和可用性權衡的結(jié)果,它的理論的核心思想是:即使無法做到強一致性,但每個應用都可以根據(jù)自身業(yè)務特點,采用適當?shù)姆绞絹硎瓜到y(tǒng)達到最終一致性。

基本可用

指分布式系統(tǒng)在出現(xiàn)故障的時候,保證核心可用,允許損失部分可用性。

例如,電商在做促銷時,為了保證購物系統(tǒng)的穩(wěn)定性,部分消費者可能會被引導到一個降級的頁面。

軟狀態(tài)

指允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認為該中間狀態(tài)不會影響系統(tǒng)整體可用性,即允許系統(tǒng)不同節(jié)點的數(shù)據(jù)副本之間進行同步的過程存在延時。

最終一致性

最終一致性強調(diào)的是系統(tǒng)中所有的數(shù)據(jù)副本,在經(jīng)過一段時間的同步后,最終能達到一致的狀態(tài)。

ACID 要求強一致性,通常運用在傳統(tǒng)的數(shù)據(jù)庫系統(tǒng)上。而 BASE 要求最終一致性,通過犧牲強一致性來達到可用性,通常運用在大型分布式系統(tǒng)中。

在實際的分布式場景中,不同業(yè)務單元和組件對一致性的要求是不同的,因此 ACID 和 BASE 往往會結(jié)合在一起使用。

4. 分布式事務問題

4.1. 兩階段提交(2PC)

兩階段提交(Two-phase Commit,2PC)

主要用于實現(xiàn)分布式事務,分布式事務指的是事務操作跨越多個節(jié)點,并且要求滿足事務的 ACID 特性。

通過引入?yún)f(xié)調(diào)者(Coordinator)來調(diào)度參與者的行為,并最終決定這些參與者是否要真正執(zhí)行事務。

運行過程

準備階段

協(xié)調(diào)者詢問參與者事務是否執(zhí)行成功,參與者發(fā)回事務執(zhí)行結(jié)果。

提交階段

如果事務在每個參與者上都執(zhí)行成功,事務協(xié)調(diào)者發(fā)送通知讓參與者提交事務;否則,協(xié)調(diào)者發(fā)送通知讓參與者回滾事務。

需要注意的是,在準備階段,參與者執(zhí)行了事務,但是還未提交。只有在提交階段接收到協(xié)調(diào)者發(fā)來的通知后,才進行提交或者回滾。

問題

同步阻塞

所有事務參與者在等待其它參與者響應的時候都處于同步阻塞狀態(tài),無法進行其它操作。

單點問題

協(xié)調(diào)者在 2PC 中起到非常大的作用,發(fā)生故障將會造成很大影響,特別是在階段二發(fā)生故障,所有參與者會一直等待狀態(tài),無法完成其它操作。

數(shù)據(jù)不一致

在階段二,如果協(xié)調(diào)者只發(fā)送了部分 Commit 消息,此時網(wǎng)絡發(fā)生異常,那么只有部分參與者接收到 Commit 消息,也就是說只有部分參與者提交了事務,使得系統(tǒng)數(shù)據(jù)不一致。

太過保守

任意一個節(jié)點失敗就會導致整個事務失敗,沒有完善的容錯機制。

2PC 優(yōu)缺點

優(yōu)點:盡量保證了數(shù)據(jù)的強一致,適合對數(shù)據(jù)強一致要求很高的關鍵領域。(其實也不能 100%保證強一致) 缺點:實現(xiàn)復雜,犧牲了可用性,對性能影響較大,不適合高并發(fā)高性能場景。

4.2. 補償事務(TCC)

補償事務(TCC)其核心思想是:針對每個操作,都要注冊一個與其對應的確認和補償(撤銷)操作。它分為三個階段:

  1. Try 階段主要是對業(yè)務系統(tǒng)做檢測及資源預留。
  2. Confirm 階段主要是對業(yè)務系統(tǒng)做確認提交,Try 階段執(zhí)行成功并開始執(zhí)行 Confirm 階段時,默認 Confirm 階段是不會出錯的。即:只要 Try 成功,Confirm 一定成功。
  3. Cancel 階段主要是在業(yè)務執(zhí)行錯誤,需要回滾的狀態(tài)下執(zhí)行的業(yè)務取消,預留資源釋放。

舉個例子,假設 Bob 要向 Smith 轉(zhuǎn)賬,思路大概是:

  1. 首先在 Try 階段,要先調(diào)用遠程接口把 Smith 和 Bob 的錢給凍結(jié)起來。
  2. 在 Confirm 階段,執(zhí)行遠程調(diào)用的轉(zhuǎn)賬的操作,轉(zhuǎn)賬成功進行解凍。
  3. 如果第 2 步執(zhí)行成功,那么轉(zhuǎn)賬成功,如果第二步執(zhí)行失敗,則調(diào)用遠程凍結(jié)接口對應的解凍方法 (Cancel)。

TCC 優(yōu)缺點

  • 優(yōu)點:跟 2PC 比起來,實現(xiàn)以及流程相對簡單了一些,但數(shù)據(jù)的一致性比 2PC 也要差一些。
  • 缺點:缺點還是比較明顯的,在 2,3 步中都有可能失敗。TCC 屬于應用層的一種補償方式,所以需要程序員在實現(xiàn)的時候多寫很多補償?shù)拇a,在一些場景中,一些業(yè)務流程可能用 TCC 不太好定義及處理。

4.3. 本地消息表(異步確保)

本地消息表與業(yè)務數(shù)據(jù)表處于同一個數(shù)據(jù)庫中,這樣就能利用本地事務來保證在對這兩個表的操作滿足事務特性。

  1. 在分布式事務操作的一方完成寫業(yè)務數(shù)據(jù)的操作之后向本地消息表發(fā)送一個消息,本地事務能保證這個消息一定會被寫入本地消息表中。
  2. 之后將本地消息表中的消息轉(zhuǎn)發(fā)到 Kafka 等消息隊列(MQ)中,如果轉(zhuǎn)發(fā)成功則將消息從本地消息表中刪除,否則繼續(xù)重新轉(zhuǎn)發(fā)。
  3. 在分布式事務操作的另一方從消息隊列中讀取一個消息,并執(zhí)行消息中的操作。

這種方案遵循 BASE 理論,采用的是最終一致性。

本地消息表利用了本地事務來實現(xiàn)分布式事務,并且使用了消息隊列來保證最終一致性。

本地消息表優(yōu)缺點

  • 優(yōu)點:一種非常經(jīng)典的實現(xiàn),避免了分布式事務,實現(xiàn)了最終一致性。
  • 缺點:消息表會耦合到業(yè)務系統(tǒng)中,如果沒有封裝好的解決方案,會有很多雜活需要處理。

4.4. MQ 事務消息

有一些第三方的 MQ 是支持事務消息的,比如 RocketMQ,他們支持事務消息的方式也是類似于采用的二階段提交。但是市面上一些主流的 MQ 都是不支持事務消息的,比如 RabbitMQ 和 Kafka 都不支持。

以阿里的 RocketMQ 中間件為例,其思路大致為:

  1. Prepared 消息,會拿到消息的地址。
  2. 執(zhí)行本地事務。
  3. 通過第一階段拿到的地址去訪問消息,并修改狀態(tài)。

也就是說在業(yè)務方法內(nèi)要想消息隊列提交兩次請求,一次發(fā)送消息和一次確認消息。如果確認消息發(fā)送失敗了 RocketMQ 會定期掃描消息集群中的事務消息,這時候發(fā)現(xiàn)了 Prepared 消息,它會向消息發(fā)送者確認,所以生產(chǎn)方需要實現(xiàn)一個 check 接口,RocketMQ 會根據(jù)發(fā)送端設置的策略來決定是回滾還是繼續(xù)發(fā)送確認消息。這樣就保證了消息發(fā)送與本地事務同時成功或同時失敗。

MQ 事務消息優(yōu)缺點

  • 優(yōu)點:實現(xiàn)了最終一致性,不需要依賴本地數(shù)據(jù)庫事務。
  • 缺點:實現(xiàn)難度大,主流 MQ 不支持。

5. 共識性問題

5.1. Paxos

用于達成共識性問題,即對多個節(jié)點產(chǎn)生的值,該算法能保證只選出唯一一個值。

主要有三類節(jié)點:

  • 提議者(Proposer):提議一個值;
  • 接受者(Acceptor):對每個提議進行投票;
  • 告知者(Learner):被告知投票的結(jié)果,不參與投票過程。

算法需要滿足 safety 和 liveness 兩方面的約束要求(實際上這兩個基礎屬性是大部分分布式算法都該考慮的):

  • safety:保證決議結(jié)果是對的,無歧義的,不會出現(xiàn)錯誤情況。
    • 決議(value)只有在被 proposers 提出的 proposal 才能被最終批準;
    • 在一次執(zhí)行實例中,只批準(chosen)一個最終決議,意味著多數(shù)接受(accept)的結(jié)果能成為決議;
  • liveness:保證決議過程能在有限時間內(nèi)完成。
    • 決議總會產(chǎn)生,并且 learners 能獲得被批準(chosen)的決議。

基本過程包括 proposer 提出提案,先爭取大多數(shù) acceptor 的支持,超過一半支持時,則發(fā)送結(jié)案結(jié)果給所有人進行確認。一個潛在的問題是 proposer 在此過程中出現(xiàn)故障,可以通過超時機制來解決。極為湊巧的情況下,每次新的一輪提案的 proposer 都恰好故障,系統(tǒng)則永遠無法達成一致(概率很?。?。

Paxos 能保證在超過 1/2 的正常節(jié)點存在時,系統(tǒng)能達成共識。

單個提案者+多接收者

如果系統(tǒng)中限定只有某個特定節(jié)點是提案者,那么一致性肯定能達成(只有一個方案,要么達成,要么失?。L岚刚咧灰盏搅藖碜远鄶?shù)接收者的投票,即可認為通過,因為系統(tǒng)中不存在其他的提案。

但一旦提案者故障,則系統(tǒng)無法工作。

多個提案者+單個接收者

限定某個節(jié)點作為接收者。這種情況下,共識也很容易達成,接收者收到多個提案,選第一個提案作為決議,拒絕掉后續(xù)的提案即可。

缺陷也是容易發(fā)生單點故障,包括接收者故障或首個提案者節(jié)點故障。

以上兩種情形其實類似主從模式,雖然不那么可靠,但因為原理簡單而被廣泛采用。

當提案者和接收者都推廣到多個的情形,會出現(xiàn)一些挑戰(zhàn)。

多個提案者+多個接收者

既然限定單提案者或單接收者都會出現(xiàn)故障,那么就得允許出現(xiàn)多個提案者和多個接收者。問題一下子變得復雜了。

一種情況是同一時間片段(如一個提案周期)內(nèi)只有一個提案者,這時可以退化到單提案者的情形。需要設計一種機制來保障提案者的正確產(chǎn)生,例如按照時間、序列、或者大家猜拳(出一個數(shù)字來比較)之類。考慮到分布式系統(tǒng)要處理的工作量很大,這個過程要盡量高效,滿足這一條件的機制非常難設計。

另一種情況是允許同一時間片段內(nèi)可以出現(xiàn)多個提案者。那同一個節(jié)點可能收到多份提案,怎么對他們進行區(qū)分呢?這個時候采用只接受第一個提案而拒絕后續(xù)提案的方法也不適用。很自然的,提案需要帶上不同的序號。節(jié)點需要根據(jù)提案序號來判斷接受哪個。比如接受其中序號較大(往往意味著是接受新提出的,因為舊提案者故障概率更大)的提案。

如何為提案分配序號呢?一種可能方案是每個節(jié)點的提案數(shù)字區(qū)間彼此隔離開,互相不沖突。為了滿足遞增的需求可以配合用時間戳作為前綴字段。

此外,提案者即便收到了多數(shù)接收者的投票,也不敢說就一定通過。因為在此過程中系統(tǒng)可能還有其它的提案。

5.2. Raft

Raft 算法是 Paxos 算法的一種簡化實現(xiàn)。

包括三種角色:leader、candidate 和 follower,其基本過程為:

  • Leader 選舉 - 每個 candidate 隨機經(jīng)過一定時間都會提出選舉方案,最近階段中得票最多者被選為 leader;
  • 同步 log - leader 會找到系統(tǒng)中 log 最新的記錄,并強制所有的 follower 來刷新到這個記錄;

注:此處 log 并非是指日志消息,而是各種事件的發(fā)生記錄。

單個 Candidate 的競選

有三種節(jié)點:Follower、Candidate 和 Leader。Leader 會周期性的發(fā)送心跳包給 Follower。每個 Follower 都設置了一個隨機的競選超時時間,一般為 150ms~300ms,如果在這個時間內(nèi)沒有收到 Leader 的心跳包,就會變成 Candidate,進入競選階段。

  • 下圖表示一個分布式系統(tǒng)的最初階段,此時只有 Follower,沒有 Leader。Follower A 等待一個隨機的競選超時時間之后,沒收到 Leader 發(fā)來的心跳包,因此進入競選階段。
  • 此時 A 發(fā)送投票請求給其它所有節(jié)點。
  • 其它節(jié)點會對請求進行回復,如果超過一半的節(jié)點回復了,那么該 Candidate 就會變成 Leader。
  • 之后 Leader 會周期性地發(fā)送心跳包給 Follower,F(xiàn)ollower 接收到心跳包,會重新開始計時。

多個 Candidate 競選

  • 如果有多個 Follower 成為 Candidate,并且所獲得票數(shù)相同,那么就需要重新開始投票,例如下圖中 Candidate B 和 Candidate D 都獲得兩票,因此需要重新開始投票。
  • 當重新開始投票時,由于每個節(jié)點設置的隨機競選超時時間不同,因此能下一次再次出現(xiàn)多個 Candidate 并獲得同樣票數(shù)的概率很低。

同步日志

  • 來自客戶端的修改都會被傳入 Leader。注意該修改還未被提交,只是寫入日志中。
  • Leader 會把修改復制到所有 Follower。
  • Leader 會等待大多數(shù)的 Follower 也進行了修改,然后才將修改提交。
  • 此時 Leader 會通知的所有 Follower 讓它們也提交修改,此時所有節(jié)點的值達成一致。

6. 分布式緩存問題

6.1. 緩存雪崩

緩存雪崩是指:在高并發(fā)場景下,由于原有緩存失效,新緩存未到期間(例如:我們設置緩存時采用了相同的過期時間,在同一時刻出現(xiàn)大面積的緩存過期),所有原本應該訪問緩存的請求都去查詢數(shù)據(jù)庫了,而對數(shù)據(jù)庫 CPU 和內(nèi)存造成巨大壓力,嚴重的會造成數(shù)據(jù)庫宕機。從而形成一系列連鎖反應,造成整個系統(tǒng)崩潰。

解決方案:

  • 用加鎖或者隊列的方式保證來保證不會有大量的線程對數(shù)據(jù)庫一次性進行讀寫,從而避免失效時大量的并發(fā)請求落到底層存儲系統(tǒng)上。
  • 還有一個簡單的方案,就是將緩存失效時間分散開,不要所有緩存時間長度都設置成 5 分鐘或者 10 分鐘;比如我們可以在原有的失效時間基礎上增加一個隨機值,比如 1-5 分鐘隨機,這樣每一個緩存的過期時間的重復率就會降低,就很難引發(fā)集體失效的事件。

緩存失效時產(chǎn)生的雪崩效應,將所有請求全部放在數(shù)據(jù)庫上,這樣很容易就達到數(shù)據(jù)庫的瓶頸,導致服務無法正常提供。盡量避免這種場景的發(fā)生。

6.2. 緩存穿透

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

當在流量較大時,出現(xiàn)這樣的情況,一直請求 DB,很容易導致服務掛掉。

解決方案:

  1. 在封裝的緩存 SET 和 GET 部分增加個步驟,如果查詢一個 KEY 不存在,就以這個 KEY 為前綴設定一個標識 KEY;以后再查詢該 KEY 的時候,先查詢標識 KEY,如果標識 KEY 存在,就返回一個協(xié)定好的非 false 或者 NULL 值,然后 APP 做相應的處理,這樣緩存層就不會被穿透。當然這個驗證 KEY 的失效時間不能太長。
  2. 如果一個查詢返回的數(shù)據(jù)為空(不管是數(shù)據(jù)不存在,還是系統(tǒng)故障),我們?nèi)匀话堰@個空結(jié)果進行緩存,但它的過期時間會很短,一般只有幾分鐘。
  3. 采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的 bitmap 中,一個一定不存在的數(shù)據(jù)會被這個 bitmap 攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力。

6.3. 緩存預熱

緩存預熱這個應該是一個比較常見的概念,相信很多小伙伴都應該可以很容易的理解,緩存預熱就是系統(tǒng)上線后,將相關的緩存數(shù)據(jù)直接加載到緩存系統(tǒng)。這樣就可以避免在用戶請求的時候,先查詢數(shù)據(jù)庫,然后再將數(shù)據(jù)緩存的問題!用戶直接查詢事先被預熱的緩存數(shù)據(jù)!

解決方案:

  1. 直接寫個緩存刷新頁面,上線時手工操作下;
  2. 數(shù)據(jù)量不大,可以在項目啟動的時候自動進行加載;
  3. 定時刷新緩存;

6.4. 緩存更新

除了緩存服務器自帶的緩存失效策略之外(Redis 默認的有 6 中策略可供選擇),我們還可以根據(jù)具體的業(yè)務需求進行自定義的緩存淘汰,常見的策略有兩種:

  1. 定時去清理過期的緩存;
  2. 當有用戶請求過來時,再判斷這個請求所用到的緩存是否過期,過期的話就去底層系統(tǒng)得到新數(shù)據(jù)并更新緩存。

兩者各有優(yōu)劣,第一種的缺點是維護大量緩存的 key 是比較麻煩的,第二種的缺點就是每次用戶請求過來都要判斷緩存失效,邏輯相對比較復雜!具體用哪種方案,大家可以根據(jù)自己的應用場景來權衡。

6.5. 緩存降級

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

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


喜歡這篇文章的朋友可以點個喜歡,也可以關注一下我的個人專題:Java成長之路

針對于上面所涉及到的知識點我總結(jié)出了有1到5年開發(fā)經(jīng)驗的程序員在面試中涉及到的絕大部分架構(gòu)面試題及答案做成了文檔和架構(gòu)視頻資料免費分享給大家(包括Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并發(fā)等架構(gòu)技術資料),希望能幫助到您面試前的復習且找到一個好的工作,也節(jié)省大家在網(wǎng)上搜索資料的時間來學習,也可以關注我一下以后會有更多干貨分享。

資料獲取方式: QQ群搜索“708-701-457” 即可免費領取



? 著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多