自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

分布式緩存的高可用方案,我們都是這么做的

存儲 存儲軟件 分布式
我們講到了當(dāng)我們的系統(tǒng)面臨持續(xù)增加的并發(fā)給我們的數(shù)據(jù)庫磁盤IO帶了了性能瓶頸,特此為我們的系統(tǒng)引入了緩存,并且學(xué)習(xí)了我們在開發(fā)中該怎么去正確的使用緩存的讀寫策略,同時結(jié)合案例給出一些建議防止數(shù)據(jù)不一致的情況,那我們的系統(tǒng)現(xiàn)在就是這樣的架構(gòu)了。

 [[284637]]

我們講到了當(dāng)我們的系統(tǒng)面臨持續(xù)增加的并發(fā)給我們的數(shù)據(jù)庫磁盤IO帶了了性能瓶頸,特此為我們的系統(tǒng)引入了緩存,并且學(xué)習(xí)了我們在開發(fā)中該怎么去正確的使用緩存的讀寫策略,同時結(jié)合案例給出一些建議防止數(shù)據(jù)不一致的情況,那我們的系統(tǒng)現(xiàn)在就是這樣的架構(gòu)了。 

分布式緩存的高可用方案,我們都是這么做的

如上圖所示,我們在服務(wù)層和數(shù)據(jù)庫層之間增加一個緩存層,現(xiàn)在我們讀取數(shù)據(jù)的時候,先從緩存里面讀取,讀不到的再去讀數(shù)據(jù)庫。

既然我們引入了緩存,那肯定是想更多的請求盡量落在緩存上,也就是說我們必須要關(guān)注緩存命中率,命中率越高就代表我們的后端存儲就越不容易被拖垮成為性瓶頸,如果我們的緩存命中率下降一定要看是什么原因,因為對于高并發(fā)請求哪怕下降1% 都是災(zāi)難。

比如,現(xiàn)在的系統(tǒng)QPS是10000,每次請求會查詢10次的緩存,現(xiàn)在命中率突然下降了1%,也就是我有 10000 * 10 * 1% =1000次的請求落到了我們后端數(shù)據(jù)庫MySql上了。這就代表了MySQL數(shù)據(jù)庫面臨突然增加的1000的并發(fā),這是很危險的,基本普通機(jī)器mysql也只能抗大概2000的并發(fā)。所以,緩存命中率是要我們關(guān)注的。

現(xiàn)在只是下降1%就對系統(tǒng)影響這么大,那要是我們的緩存節(jié)點(diǎn)掛了,不可用了,那豈不是又回到了原點(diǎn),請求都會打到我們的數(shù)據(jù)庫中的。所以,我們在使用緩存一定要搭建高可用緩存,避免上面的單點(diǎn)緩存架構(gòu)。今天,我們就來學(xué)習(xí)該怎么做緩存的高可用方案即搭建分布式緩存的高可用方案。

依據(jù)經(jīng)驗來說,對于分布式緩存高可用方案目前一般采用應(yīng)用端、中間代理層以及服務(wù)端這三大方案。

  • 應(yīng)用端方案,在應(yīng)用端自己配置緩存節(jié)點(diǎn),通過緩存寫入和讀取算法策略來實現(xiàn)分布式,從而提高緩存的可用性。
  • 代理層方案,在應(yīng)用代碼和緩存節(jié)點(diǎn)之間增加一個獨(dú)立的代理層,應(yīng)用端就直接喝代理層連接,代理層自己內(nèi)置高可用策略,以提升緩存的可用性。
  • 服務(wù)端方案,即為緩存服務(wù)自身提供的高可用,例如Redis Sentinel

接下來我們就來分別學(xué)習(xí)下這三種方案

應(yīng)用端方案

在應(yīng)用端也就是代碼層面上,我們就需要自己管理緩存的讀和寫,也就是通過寫代碼方式來進(jìn)行分布式緩存的寫入和讀取,主要是下面這兩模塊:

  1. 寫緩存時,我們需要將數(shù)據(jù)分散到緩存的各個節(jié)點(diǎn)中,即要實現(xiàn)數(shù)據(jù)分片。
  2. 讀緩存時,需考慮主從或者多副本粗略以及使用多組緩存進(jìn)行容錯。

下面我們來看看該怎么進(jìn)行設(shè)計,其實這種設(shè)計思路不一定局限在緩存上,我們大部分的底層開發(fā)都能用上,希望大家好好掌握

緩存數(shù)據(jù)如何分片

我們知道單節(jié)點(diǎn)的緩存因受到各種原因如本身機(jī)器內(nèi)存、網(wǎng)絡(luò)帶寬等,從而不能承受更高的并發(fā),所以我們需要將數(shù)據(jù)進(jìn)行分片存儲,即將數(shù)據(jù)通過分片算法打散到各個緩存節(jié)點(diǎn)中。其實這塊大家有沒有注意到和我們前面的分庫分表很類似,所以大部分架構(gòu)思想都是相通的。

現(xiàn)在我們的數(shù)據(jù)就在各個緩存節(jié)點(diǎn)都有一部分,即使部分故障,也是不影響我們整個業(yè)務(wù)的。那這個時候,你可能在想,既然數(shù)據(jù)需要被均勻分散到各個節(jié)點(diǎn),那我該怎么來寫這個分片算法呢?別急,我們下面就來看怎么寫這個分片算法。

數(shù)據(jù)分片算法

一般做數(shù)據(jù)分片算法的有兩種,大家應(yīng)該都清楚吧,前面分庫分表就有用到的

  • Hash分片算法
  • 一致性Hash分片算法

Hash分片算法

Hash分片算法就是我們拿到緩存的key,然后對其做hash運(yùn)算,最后將hash運(yùn)算的結(jié)果對緩存總節(jié)點(diǎn)數(shù)取余,得到的數(shù)字則為具體的分片節(jié)點(diǎn)。比如,現(xiàn)在我們緩存節(jié)點(diǎn)一共有 3 個,當(dāng)我們寫入數(shù)據(jù)的時候,將key進(jìn)行hash運(yùn)算hash(key),然后將結(jié)果對3取余就行了,如下圖所示: 

分布式緩存的高可用方案,我們都是這么做的

這種分片算法優(yōu)點(diǎn)就是開發(fā)簡單且容易理解,缺點(diǎn)就是當(dāng)我們的緩存總節(jié)點(diǎn)數(shù)改變的時候,就會導(dǎo)致數(shù)據(jù)不均勻,則會造成大量緩存失效不可用的情況。但是這種算法我們開發(fā)中也是會使用的,比如我們的業(yè)務(wù)對于緩存的命中率不是那么太在意的,就可以使用這種hash分片算法。

一致性Hash分片算法

上面簡單的Hash分片算法對緩存命中率要求較高的業(yè)務(wù)會有一定影響,所以一致性Hash分片算法就出來了,它很好的解決了因緩存節(jié)點(diǎn)的增加或減少帶來的緩存命中率下降的問題。那我們就來看看它是怎么做的。

  1. 首先維護(hù)一個2^32的hash環(huán)。
  2. 然后將各個緩存節(jié)點(diǎn)的IP或者機(jī)器名稱計算hash值,是每個節(jié)點(diǎn)計算多個hash出來,也就是所謂的虛擬節(jié)點(diǎn)。為了數(shù)據(jù)能更加的均勻,且能避免節(jié)點(diǎn)雪崩的發(fā)生。
  3. 將計算出來的hash值即虛擬節(jié)點(diǎn)放到hash環(huán)上。
  4. 當(dāng)我們要寫入一個key的時候,就可以先對這個key做hash計算出hash值,,確定在hash環(huán)上的位置。
  5. 最后在環(huán)上按照順時針的方式查找,遇到的第一個緩存節(jié)點(diǎn)就是它要存放的節(jié)點(diǎn)。

例如,下面key1 和 key2 就會進(jìn)到 Node 1 里面,key3和key4 就會進(jìn)到 Node 2 里面,key5 進(jìn)到 Node3 中,key 6 則進(jìn)到 Node 4 中去。 

分布式緩存的高可用方案,我們都是這么做的

如上圖所示,如果在 Node 1 和 Node 2 之間再加一個 Node 5,我們可以看到之前命中 Node 2 的 Key 3 現(xiàn)在就會命中到 Node 5,而其它的 Key 都沒有變化;同樣的道理,如果我們把 Node 3 從集群中移除,那么只會影響到 Key 5 。因此,在增加和刪除節(jié)點(diǎn)時,只有少量的 Key 會跑到其它節(jié)點(diǎn)上,而大部分的 Key 命中的節(jié)點(diǎn)還是會保持不變,從而可以保證命中率不會大幅下降。 

分布式緩存的高可用方案,我們都是這么做的

生產(chǎn)開發(fā)建議

我們在使用一致性哈希算法的時候,一定要設(shè)置緩存的過期時間,為什么這么說的呢?現(xiàn)在假設(shè)集群里面有兩個節(jié)點(diǎn)分別為node1和node2,node1里面存放的(k,5),然后一客戶端請求過來需要將5變成8,這個時候node1節(jié)點(diǎn)服務(wù)和客戶端因網(wǎng)絡(luò)問題斷開連接了,那么這次的寫入操作就會被路由到node2上了,等到node1網(wǎng)絡(luò)好了恢復(fù)連接的話,客戶端讀取到node1 中k就為5,而其實這個k已經(jīng)是8了,就造成了臟數(shù)據(jù),所以我們需要設(shè)置過期時間。 

分布式緩存的高可用方案,我們都是這么做的

Memcached 如何做主從機(jī)制

memcached不像redis本身支持主從復(fù)制機(jī)制,那我們該怎么保證memcached的高可用呢?其實和我們前面的數(shù)據(jù)庫方案差不多的。

  1. 我們?yōu)槊恳唤Mmemcached的Master配置一組Slave。
  2. 數(shù)據(jù)更新的時候,我們就主從同步更新。
  3. 數(shù)據(jù)讀取的時候,先從Slave中讀取,讀不到就穿透到Master中,再將數(shù)據(jù)寫回到Slave中。

其主從復(fù)制優(yōu)點(diǎn)就是當(dāng)某一個 Slave 宕機(jī)時,還會有 Master 作為兜底,不會有大量請求穿透到數(shù)據(jù)庫的情況發(fā)生,提升了緩存系統(tǒng)的高可用性。 

分布式緩存的高可用方案,我們都是這么做的

中間代理層方案

上面的應(yīng)用端方案基本能解決我們絕大部分問題了,現(xiàn)在主要是像有些公司技術(shù)語言比較多的話,這種就得每種語言都得開發(fā)一套,比如我們公司有Java PHP 還有.

net之類的,那么這個時候就需要中間代理層來最好不過了,不需要業(yè)務(wù)方進(jìn)行考慮這些復(fù)雜情況,直接連接代理層就行了

代理層自己管理緩存節(jié)點(diǎn)高可用,通過某種協(xié)議,如redis協(xié)議,來和各種語言業(yè)務(wù)端連接。業(yè)界也有很多中間代理層方案,比如 Facebook 的Mcrouter,Twitter 的Twemproxy,豌豆莢的Codis?;炯軜?gòu)如下:

分布式緩存的高可用方案,我們都是這么做的

如上圖所示,中間層代理方案即所有緩存讀寫的操作都直接通過代理層完成,代理層自己完成上面應(yīng)用端所有的操作。

服務(wù)端方案

服務(wù)端方案主要是緩存服務(wù)自己管理的,對于我們開發(fā)人員不用自己寫代碼管理也不用引入中間層,就是需要相關(guān)運(yùn)維配置支持,比如redis的sentinel模式就是用來解決redis部署時高可用問題,它可以在主節(jié)點(diǎn)掛了以后自動將從節(jié)點(diǎn)提升為主節(jié)點(diǎn),保證整體集群的可用。所以服務(wù)端對于我們開發(fā)影響不是太大,redis的sentinel我們還得需要知道的,后面會專門進(jìn)行講解。

總結(jié),今天我們講到了在使用緩存的時候為了避免單節(jié)點(diǎn)所帶來的各種問題,所以我們需要搭建高可用緩存架構(gòu),共講到了三種方案,應(yīng)用端、中間代理層以及服務(wù)端方案,大家可以根據(jù)公司的資源情況來選擇合適的方案。

 

責(zé)任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2020-11-26 09:38:19

分布式架構(gòu)系統(tǒng)

2015-08-05 10:50:01

Facebook緩存網(wǎng)頁

2022-05-11 13:55:18

高可用性分布式彈性

2021-09-23 12:14:50

Redis分布式優(yōu)化

2017-12-12 14:51:15

分布式緩存設(shè)計

2018-11-28 16:00:41

2018-12-12 15:20:27

2018-11-02 14:00:20

2019-10-16 10:34:33

數(shù)據(jù)庫大數(shù)據(jù)腳本語言

2022-04-07 17:13:09

緩存算法服務(wù)端

2013-11-27 12:40:21

鮑爾默微軟

2019-10-08 12:32:07

運(yùn)維架構(gòu)技術(shù)

2022-01-10 19:45:40

微服務(wù)GO系統(tǒng)

2019-01-22 14:19:04

2022-05-09 09:42:24

高可用分布式數(shù)據(jù)庫

2021-06-05 07:33:09

ID分布式架構(gòu)

2024-05-20 08:08:00

分布式系統(tǒng)緩存C#

2018-12-14 10:06:22

緩存分布式系統(tǒng)

2024-01-10 08:02:03

分布式技術(shù)令牌,

2025-04-01 01:04:00

Redis集群緩存
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號