日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > 架構(gòu)師社區(qū)
[導(dǎo)讀]這篇文章我想和你聊一聊 Redis 的架構(gòu)演化之路。

閱讀本文大約需要 13 分鐘。

大家好,我是 Kaito。

這篇文章我想和你聊一聊 Redis 的架構(gòu)演化之路。

現(xiàn)如今 Redis 變得越來越流行,幾乎在很多項(xiàng)目中都要被用到,不知道你在使用 Redis 時(shí),有沒有思考過,Redis 到底是如何穩(wěn)定、高性能地提供服務(wù)的?

你也可以嘗試回答一下以下這些問題:

  • 我使用 Redis 的場景很簡單,只使用單機(jī)版 Redis 會有什么問題嗎?
  • 我的 Redis 故障宕機(jī)了,數(shù)據(jù)丟失了怎么辦?如何能保證我的業(yè)務(wù)應(yīng)用不受影響?
  • 為什么需要主從集群?它有什么優(yōu)勢?
  • 什么是分片集群?我真的需要分片集群嗎?
  • ...

如果你對 Redis 已經(jīng)有些了解,肯定也聽說過數(shù)據(jù)持久化、主從復(fù)制、哨兵這些概念,它們之間又有什么區(qū)別和聯(lián)系呢?

如果你存在這樣的疑惑,這篇文章,我會從 0 到 1,再從 1 到 N,帶你一步步構(gòu)建出一個穩(wěn)定、高性能的 Redis 集群。

在這個過程中,你可以了解到 Redis 為了做到穩(wěn)定、高性能,都采取了哪些優(yōu)化方案,以及為什么要這么做?

掌握了這些原理,這樣平時(shí)你在使用 Redis 時(shí),就能夠做到「游刃有余」。

這篇文章干貨很多,希望你可以耐心讀完。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

從最簡單的開始:單機(jī)版 Redis

首先,我們從最簡單的場景開始。

假設(shè)現(xiàn)在你有一個業(yè)務(wù)應(yīng)用,需要引入 Redis 來提高應(yīng)用的性能,此時(shí)你可以選擇部署一個單機(jī)版的 Redis 來使用,就像這樣:

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

這個架構(gòu)非常簡單,你的業(yè)務(wù)應(yīng)用可以把 Redis 當(dāng)做緩存來使用,從 MySQL 中查詢數(shù)據(jù),然后寫入到 Redis 中,之后業(yè)務(wù)應(yīng)用再從 Redis 中讀取這些數(shù)據(jù),由于 Redis 的數(shù)據(jù)都存儲在內(nèi)存中,所以這個速度飛快。

如果你的業(yè)務(wù)體量并不大,那這樣的架構(gòu)模型基本可以滿足你的需求。是不是很簡單?

隨著時(shí)間的推移,你的業(yè)務(wù)體量逐漸發(fā)展起來了,Redis 中存儲的數(shù)據(jù)也越來越多,此時(shí)你的業(yè)務(wù)應(yīng)用對 Redis 的依賴也越來越重。

但是,突然有一天,你的 Redis 因?yàn)槟承┰蝈礄C(jī)了,這時(shí)你的所有業(yè)務(wù)流量,都會打到后端 MySQL 上,這會導(dǎo)致你的 MySQL 壓力劇增,嚴(yán)重的話甚至?xí)嚎?MySQL。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

這時(shí)你應(yīng)該怎么辦?

我猜你的方案肯定是,趕緊重啟 Redis,讓它可以繼續(xù)提供服務(wù)。

但是,因?yàn)橹?Redis 中的數(shù)據(jù)都在內(nèi)存中,盡管你現(xiàn)在把 Redis 重啟了,之前的數(shù)據(jù)也都丟失了。重啟后的 Redis 雖然可以正常工作,但是由于 Redis 中沒有任何數(shù)據(jù),業(yè)務(wù)流量還是都會打到后端 MySQL 上,MySQL 的壓力還是很大。

這可怎么辦?你陷入了沉思。

有沒有什么好的辦法解決這個問題?

既然 Redis 只把數(shù)據(jù)存儲在內(nèi)存中,那是否可以把這些數(shù)據(jù)也寫一份到磁盤上呢?

如果采用這種方式,當(dāng) Redis 重啟時(shí),我們把磁盤中的數(shù)據(jù)快速恢復(fù)到內(nèi)存中,這樣它就可以繼續(xù)正常提供服務(wù)了。

是的,這是一個很好的解決方案,這個把內(nèi)存數(shù)據(jù)寫到磁盤上的過程,就是「數(shù)據(jù)持久化」。

數(shù)據(jù)持久化:有備無患

現(xiàn)在,你設(shè)想的 Redis 數(shù)據(jù)持久化是這樣的:

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

但是,數(shù)據(jù)持久化具體應(yīng)該怎么做呢?

我猜你最容易想到的一個方案是,Redis 每一次執(zhí)行寫操作,除了寫內(nèi)存之外,同時(shí)也寫一份到磁盤上,就像這樣:

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

沒錯,這是最簡單直接的方案。

但仔細(xì)想一下,這個方案有個問題:客戶端的每次寫操作,既需要寫內(nèi)存,又需要寫磁盤,而寫磁盤的耗時(shí)相比于寫內(nèi)存來說,肯定要慢很多!這勢必會影響到 Redis 的性能。

如何規(guī)避這個問題?

我們可以這樣優(yōu)化:Redis 寫內(nèi)存由主線程來做,寫內(nèi)存完成后就給客戶端返回結(jié)果,然后 Redis 用另一個線程去寫磁盤,這樣就可以避免主線程寫磁盤對性能的影響。

這確實(shí)是一個好方案。除此之外,我們可以換個角度,思考一下還有什么方式可以持久化數(shù)據(jù)?

這時(shí)你就要結(jié)合 Redis 的使用場景來考慮了。

回憶一下,我們在使用 Redis 時(shí),通常把它用作什么場景?

是的,緩存。

把 Redis 當(dāng)做緩存來用,意味著盡管 Redis 中沒有保存全量數(shù)據(jù),對于不在緩存中的數(shù)據(jù),我們的業(yè)務(wù)應(yīng)用依舊可以通過查詢后端數(shù)據(jù)庫得到結(jié)果,只不過查詢后端數(shù)據(jù)的速度會慢一點(diǎn)而已,但對業(yè)務(wù)結(jié)果其實(shí)是沒有影響的。

基于這個特點(diǎn),我們的 Redis 數(shù)據(jù)持久化還可以用「數(shù)據(jù)快照」的方式來做。

那什么是數(shù)據(jù)快照呢?

簡單來講,你可以這么理解:

  1. 你把 Redis 想象成一個水杯,向 Redis 寫入數(shù)據(jù),就相當(dāng)于往這個杯子里倒水
  2. 此時(shí)你拿一個相機(jī)給這個水杯拍一張照片,拍照的這一瞬間,照片中記錄到這個水杯中水的容量,就是水杯的數(shù)據(jù)快照
如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

也就是說,Redis 的數(shù)據(jù)快照,是記錄某一時(shí)刻下 Redis 中的數(shù)據(jù),然后只需要把這個數(shù)據(jù)快照寫到磁盤上就可以了。

它的優(yōu)勢在于,只在需要持久化時(shí),把數(shù)據(jù)「一次性」寫入磁盤,其它時(shí)間都不需要操作磁盤。

基于這個方案,我們可以定時(shí)給 Redis 做數(shù)據(jù)快照,把數(shù)據(jù)持久化到磁盤上。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

其實(shí),上面說的這些持久化方案,就是 Redis 的「RDB」和「AOF」:

  • RDB:只持久化某一時(shí)刻的數(shù)據(jù)快照到磁盤上(創(chuàng)建一個子進(jìn)程來做)
  • AOF:每一次寫操作都持久到磁盤(主線程寫內(nèi)存,根據(jù)策略可以配置由主線程還是子線程進(jìn)行數(shù)據(jù)持久化)

它們的區(qū)別除了上面講到的,還有以下特點(diǎn):

  1. RDB 采用二進(jìn)制 + 數(shù)據(jù)壓縮的方式寫磁盤,這樣文件體積小,數(shù)據(jù)恢復(fù)速度也快
  2. AOF 記錄的是每一次寫命令,數(shù)據(jù)最全,但文件體積大,數(shù)據(jù)恢復(fù)速度慢

如果讓你來選擇持久化方案,你可以這樣選擇:

  1. 如果你的業(yè)務(wù)對于數(shù)據(jù)丟失不敏感,采用 RDB 方案持久化數(shù)據(jù)
  2. 如果你的業(yè)務(wù)對數(shù)據(jù)完整性要求比較高,采用 AOF 方案持久化數(shù)據(jù)

假設(shè)你的業(yè)務(wù)對 Redis 數(shù)據(jù)完整性要求比較高,選擇了 AOF 方案,那此時(shí)你又會遇到這些問題:

  1. AOF 記錄每一次寫操作,隨著時(shí)間增長,AOF 文件體積會越來越大
  2. 這么大的 AOF 文件,在數(shù)據(jù)恢復(fù)時(shí)變得非常慢

這怎么辦?數(shù)據(jù)完整性要求變高了,恢復(fù)數(shù)據(jù)也變困難了?有沒有什么方法,可以縮小文件體積?提升恢復(fù)速度呢?

我們繼續(xù)來分析 AOF 的特點(diǎn)。

由于 AOF 文件中記錄的都是每一次寫操作,但對于同一個 key 可能會發(fā)生多次修改,我們只保留最后一次被修改的值,是不是也可以?

是的,這就是我們經(jīng)常聽到的「AOF rewrite」,你也可以把它理解為 AOF 「瘦身」。

我們可以對 AOF 文件定時(shí) rewrite,避免這個文件體積持續(xù)膨脹,這樣在恢復(fù)時(shí)就可以縮短恢復(fù)時(shí)間了。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

再進(jìn)一步思考一下,還有沒有辦法繼續(xù)縮小 AOF 文件?

回顧一下我們前面講到的,RDB 和 AOF 各自的特點(diǎn):

  1. RDB 以二進(jìn)制 + 數(shù)據(jù)壓縮方式存儲,文件體積小
  2. AOF 記錄每一次寫命令,數(shù)據(jù)最全

我們可否利用它們各自的優(yōu)勢呢?

當(dāng)然可以,這就是 Redis 的「混合持久化」。

具體來說,當(dāng) AOF rewrite 時(shí),Redis 先以 RDB 格式在 AOF 文件中寫入一個數(shù)據(jù)快照,再把在這期間產(chǎn)生的每一個寫命令,追加到 AOF 文件中。因?yàn)?RDB 是二進(jìn)制壓縮寫入的,這樣 AOF 文件體積就變得更小了。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

此時(shí),你在使用 AOF 文件恢復(fù)數(shù)據(jù)時(shí),這個恢復(fù)時(shí)間就會更短了!

Redis 4.0 以上版本才支持混合持久化。

這么一番優(yōu)化,你的 Redis 再也不用擔(dān)心實(shí)例宕機(jī)了,當(dāng)發(fā)生宕機(jī)時(shí),你就可以用持久化文件快速恢復(fù) Redis 中的數(shù)據(jù)。

但這樣就沒問題了嗎?

仔細(xì)想一下,雖然我們已經(jīng)把持久化的文件優(yōu)化到最小了,但在恢復(fù)數(shù)據(jù)時(shí)依舊是需要時(shí)間的,在這期間你的業(yè)務(wù)應(yīng)用還是會受到影響,這怎么辦?

我們來分析有沒有更好的方案。

一個實(shí)例宕機(jī),只能用恢復(fù)數(shù)據(jù)來解決,那我們是否可以部署多個 Redis 實(shí)例,然后讓這些實(shí)例數(shù)據(jù)保持實(shí)時(shí)同步,這樣當(dāng)一個實(shí)例宕機(jī)時(shí),我們在剩下的實(shí)例中選擇一個繼續(xù)提供服務(wù)就好了。

沒錯,這個方案就是接下來要講的「主從復(fù)制:多副本」。

主從復(fù)制:多副本

此時(shí),你可以部署多個 Redis 實(shí)例,架構(gòu)模型就變成了這樣:

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

我們這里把實(shí)時(shí)讀寫的節(jié)點(diǎn)叫做 master,另一個實(shí)時(shí)同步數(shù)據(jù)的節(jié)點(diǎn)叫做 slave。

采用多副本的方案,它的優(yōu)勢是:

  1. 縮短不可用時(shí)間:master 發(fā)生宕機(jī),我們可以手動把 slave 提升為 master 繼續(xù)提供服務(wù)
  2. 提升讀性能:讓 slave 分擔(dān)一部分讀請求,提升應(yīng)用的整體性能

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

這個方案不錯,不僅節(jié)省了數(shù)據(jù)恢復(fù)的時(shí)間,還能提升性能,那它有什么問題嗎?

你可以思考一下。

其實(shí),它的問題在于:當(dāng) master 宕機(jī)時(shí),我們需要「手動」把 slave 提升為 master,這個過程也是需要花費(fèi)時(shí)間的。

雖然比恢復(fù)數(shù)據(jù)要快得多,但還是需要人工介入處理。一旦需要人工介入,就必須要算上人的反應(yīng)時(shí)間、操作時(shí)間,所以,在這期間你的業(yè)務(wù)應(yīng)用依舊會受到影響。

怎么解決這個問題?我們是否可以把這個切換的過程,變成自動化呢?

對于這種情況,我們需要一個「故障自動切換」機(jī)制,這就是我們經(jīng)常聽到的「哨兵」所具備的能力。

哨兵:故障自動切換

現(xiàn)在,我們可以引入一個「觀察者」,讓這個觀察者去實(shí)時(shí)監(jiān)測 master 的健康狀態(tài),這個觀察者就是「哨兵」。

具體如何做?

  1. 哨兵每間隔一段時(shí)間,詢問 master 是否正常
  2. master 正?;貜?fù),表示狀態(tài)正常,回復(fù)超時(shí)表示異常
  3. 哨兵發(fā)現(xiàn)異常,發(fā)起主從切換

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

有了這個方案,就不需要人去介入處理了,一切就變得自動化了,是不是很爽?

但這里還有一個問題,如果 master 狀態(tài)正常,但這個哨兵在詢問 master 時(shí),它們之間的網(wǎng)絡(luò)發(fā)生了問題,那這個哨兵可能會誤判。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

這個問題怎么解決?

答案是,我們可以部署多個哨兵,讓它們分布在不同的機(jī)器上,它們一起監(jiān)測 master 的狀態(tài),流程就變成了這樣:

  1. 多個哨兵每間隔一段時(shí)間,詢問 master 是否正常
  2. master 正?;貜?fù),表示狀態(tài)正常,回復(fù)超時(shí)表示異常
  3. 一旦有一個哨兵判定 master 異常(不管是否是網(wǎng)絡(luò)問題),就詢問其它哨兵,如果多個哨兵(設(shè)置一個閾值)都認(rèn)為 master 異常了,這才判定 master 確實(shí)發(fā)生了故障
  4. 多個哨兵經(jīng)過協(xié)商后,判定 master 故障,則發(fā)起主從切換

所以,我們用多個哨兵互相協(xié)商來判定 master 的狀態(tài),這樣一來,就可以大大降低誤判的概率。

哨兵協(xié)商判定 master 異常后,這里還有一個問題:由哪個哨兵來發(fā)起主從切換呢?

答案是,選出一個哨兵「領(lǐng)導(dǎo)者」,由這個領(lǐng)導(dǎo)者進(jìn)行主從切換。

問題又來了,這個領(lǐng)導(dǎo)者怎么選?

想象一下,在現(xiàn)實(shí)生活中,選舉是怎么做的?

是的,投票。

在選舉哨兵領(lǐng)導(dǎo)者時(shí),我們可以制定這樣一個選舉規(guī)則:

  1. 每個哨兵都詢問其它哨兵,請求對方為自己投票
  2. 每個哨兵只投票給第一個請求投票的哨兵,且只能投票一次
  3. 首先拿到超過半數(shù)投票的哨兵,當(dāng)選為領(lǐng)導(dǎo)者,發(fā)起主從切換

其實(shí),這個選舉的過程就是我們經(jīng)常聽到的:分布式系統(tǒng)領(lǐng)域中的「共識算法」。

什么是共識算法?

我們在多個機(jī)器部署哨兵,它們需要共同協(xié)作完成一項(xiàng)任務(wù),所以它們就組成了一個「分布式系統(tǒng)」。

在分布式系統(tǒng)領(lǐng)域,多個節(jié)點(diǎn)如何就一個問題達(dá)成共識的算法,就叫共識算法。

在這個場景下,多個哨兵共同協(xié)商,選舉出一個都認(rèn)可的領(lǐng)導(dǎo)者,就是使用共識算法完成的。

這個算法還規(guī)定節(jié)點(diǎn)的數(shù)量必須是奇數(shù)個,這樣可以保證系統(tǒng)中即使有節(jié)點(diǎn)發(fā)生了故障,剩余超過「半數(shù)」的節(jié)點(diǎn)狀態(tài)正常,依舊可以提供正確的結(jié)果,也就是說,這個算法還兼容了存在故障節(jié)點(diǎn)的情況。

共識算法在分布式系統(tǒng)領(lǐng)域有很多,例如 Paxos、Raft,哨兵選舉領(lǐng)導(dǎo)者這個場景,使用的是 Raft 共識算法,因?yàn)樗銐蚝唵危乙子趯?shí)現(xiàn)。

現(xiàn)在,我們用多個哨兵共同監(jiān)測 Redis 的狀態(tài),這樣一來,就可以避免誤判的問題了,架構(gòu)模型就變成了這樣:

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

好了,到這里我們先小結(jié)一下。

你的 Redis 從最簡單的單機(jī)版,經(jīng)過數(shù)據(jù)持久化、主從多副本、哨兵集群,這一路優(yōu)化下來,你的 Redis 不管是性能還是穩(wěn)定性,都越來越高,就算節(jié)點(diǎn)發(fā)生故障,也不用擔(dān)心了。

你的 Redis 以這樣的架構(gòu)模式部署,基本上就可以穩(wěn)定運(yùn)行很長時(shí)間了。

...

隨著時(shí)間的發(fā)展,你的業(yè)務(wù)體量開始迎來了爆炸性增長,此時(shí)你的架構(gòu)模型,還能夠承擔(dān)這么大的流量嗎?

我們一起來分析一下:

  1. 穩(wěn)定性:Redis 故障宕機(jī),我們有哨兵 + 副本,可以自動完成主從切換
  2. 性能:讀請求量增長,我們可以再部署多個 slave,讀寫分離,分擔(dān)讀壓力
  3. 性能:寫請求量增長,但我們只有一個 master 實(shí)例,這個實(shí)例達(dá)到瓶頸怎么辦?

看到了么,當(dāng)你的寫請求量越來越大時(shí),一個 master 實(shí)例可能就無法承擔(dān)這么大的寫流量了。

要想完美解決這個問題,此時(shí)你就需要考慮使用「分片集群」了。

分片集群:橫向擴(kuò)展

什么是「分片集群」?

簡單來講,一個實(shí)例扛不住寫壓力,那我們是否可以部署多個實(shí)例,然后把這些實(shí)例按照一定規(guī)則組織起來,把它們當(dāng)成一個整體,對外提供服務(wù),這樣不就可以解決集中寫一個實(shí)例的瓶頸問題嗎?

所以,現(xiàn)在的架構(gòu)模型就變成了這樣:

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

現(xiàn)在問題又來了,這么多實(shí)例如何組織呢?

我們制定規(guī)則如下:

  1. 每個節(jié)點(diǎn)各自存儲一部分?jǐn)?shù)據(jù),所有節(jié)點(diǎn)數(shù)據(jù)之和才是全量數(shù)據(jù)
  2. 制定一個路由規(guī)則,對于不同的 key,把它路由到固定一個實(shí)例上進(jìn)行讀寫

而分片集群根據(jù)路由規(guī)則所在位置的不同,還可以分為兩大類:

  1. 客戶端分片
  2. 服務(wù)端分片

客戶端分片指的是,key 的路由規(guī)則放在客戶端來做,就是下面這樣:

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

這個方案的缺點(diǎn)是,客戶端需要維護(hù)這個路由規(guī)則,也就是說,你需要把路由規(guī)則寫到你的業(yè)務(wù)代碼中。

如何做到不把路由規(guī)則耦合在業(yè)務(wù)代碼中呢?

你可以這樣優(yōu)化,把這個路由規(guī)則封裝成一個模塊,當(dāng)需要使用時(shí),集成這個模塊就可以了。

這就是 Redis Cluster 的采用的方案。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

Redis Cluster 內(nèi)置了哨兵邏輯,無需再部署哨兵。

當(dāng)你使用 Redis Cluster 時(shí),你的業(yè)務(wù)應(yīng)用需要使用配套的 Redis SDK,這個 SDK 內(nèi)就集成好了路由規(guī)則,不需要你自己編寫了。

再來看服務(wù)端分片。

這種方案指的是,路由規(guī)則不放在客戶端來做,而是在客戶端和服務(wù)端之間增加一個「中間代理層」,這個代理就是我們經(jīng)常聽到的 Proxy。

而數(shù)據(jù)的路由規(guī)則,就放在這個 Proxy 層來維護(hù)。

這樣一來,你就無需關(guān)心服務(wù)端有多少個 Redis 節(jié)點(diǎn)了,只需要和這個 Proxy 交互即可。

Proxy 會把你的請求根據(jù)路由規(guī)則,轉(zhuǎn)發(fā)到對應(yīng)的 Redis 節(jié)點(diǎn)上,而且,當(dāng)集群實(shí)例不足以支撐更大的流量請求時(shí),還可以橫向擴(kuò)容,添加新的 Redis 實(shí)例提升性能,這一切對于你的客戶端來說,都是透明無感知的。

業(yè)界開源的 Redis 分片集群方案,例如 Twemproxy、Codis 就是采用的這種方案。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

分片集群在數(shù)據(jù)擴(kuò)容時(shí),還涉及到了很多細(xì)節(jié),這塊內(nèi)容不是本文章重點(diǎn),所以暫不詳述。

至此,當(dāng)你使用分片集群后,對于未來更大的流量壓力,都可以從容面對了!

總結(jié)

好了,我們來總結(jié)一下,我們是如何一步步構(gòu)建一個穩(wěn)定、高性能的 Redis 集群的。

首先,在使用最簡單的單機(jī)版 Redis 時(shí),我們發(fā)現(xiàn)當(dāng) Redis 故障宕機(jī)后,數(shù)據(jù)無法恢復(fù)的問題,因此我們想到了「數(shù)據(jù)持久化」,把內(nèi)存中的數(shù)據(jù)也持久化到磁盤上一份,這樣 Redis 重啟后就可以從磁盤上快速恢復(fù)數(shù)據(jù)。

在進(jìn)行數(shù)據(jù)持久化時(shí),我們又面臨如何更高效地將數(shù)據(jù)持久化到磁盤的問題。之后我們發(fā)現(xiàn) Redis 提供了 RDB 和 AOF 兩種方案,分別對應(yīng)了數(shù)據(jù)快照和實(shí)時(shí)的命令記錄。當(dāng)我們對數(shù)據(jù)完整性要求不高時(shí),可以選擇 RDB 持久化方案。如果對于數(shù)據(jù)完整性要求較高,那么可以選擇 AOF 持久化方案。

但是我們又發(fā)現(xiàn),AOF 文件體積會隨著時(shí)間增長變得越來越大,此時(shí)我們想到的優(yōu)化方案是,使用 AOF rewrite 的方式對其進(jìn)行瘦身,減小文件體積,再后來,我們發(fā)現(xiàn)可以結(jié)合 RDB 和 AOF 各自的優(yōu)勢,在 AOF rewrite 時(shí)使用兩者結(jié)合的「混合持久化」方式,又進(jìn)一步減小了 AOF 文件體積。

之后,我們發(fā)現(xiàn)盡管可以通過數(shù)據(jù)恢復(fù)的方式還原數(shù)據(jù),但恢復(fù)數(shù)據(jù)也是需要花費(fèi)時(shí)間的,這意味著業(yè)務(wù)應(yīng)用還是會受到影響。我們進(jìn)一步優(yōu)化,采用「多副本」的方案,讓多個實(shí)例保持實(shí)時(shí)同步,當(dāng)一個實(shí)例故障時(shí),可以手動把其它實(shí)例提升上來繼續(xù)提供服務(wù)。

但是這樣也有問題,手動提升實(shí)例上來,需要人工介入,人工介入操作也需要時(shí)間,我們開始想辦法把這個流程變得自動化,所以我們又引入了「哨兵」集群,哨兵集群通過互相協(xié)商的方式,發(fā)現(xiàn)故障節(jié)點(diǎn),并可以自動完成切換,這樣就大幅降低了對業(yè)務(wù)應(yīng)用的影響。

最后,我們把關(guān)注點(diǎn)聚焦在如何支撐更大的寫流量上,所以,我們又引入了「分片集群」來解決這個問題,讓多個 Redis 實(shí)例分?jǐn)倢憠毫?,未來面對更大的流量,我們還可以添加新的實(shí)例,橫向擴(kuò)展,進(jìn)一步提升集群的性能。

至此,我們的 Redis 集群才得以長期穩(wěn)定、高性能的為我們的業(yè)務(wù)提供服務(wù)。

這里我畫了一個思維導(dǎo)圖,方便你更好地去理解它們之間的關(guān)系,以及演化的過程。

如何從0到1構(gòu)建一個穩(wěn)定、高性能的Redis集群?(附16張圖解)

后記

看到這里,我想你對如何構(gòu)建一個穩(wěn)定、高性能的 Redis 集群問題時(shí),應(yīng)該會有自己的見解了。

其實(shí),這篇文章所講的優(yōu)化思路,圍繞的主題就是「架構(gòu)設(shè)計(jì)」的核心思想:

  • 高性能:讀寫分離、分片集群
  • 高可用:數(shù)據(jù)持久化、多副本、故障自動切換
  • 易擴(kuò)展:分片集群、橫向擴(kuò)展

當(dāng)我們講到哨兵集群、分片集群時(shí),這還涉及到了「分布式系統(tǒng)」相關(guān)的知識:

  • 分布式共識:哨兵領(lǐng)導(dǎo)者選舉
  • 負(fù)載均衡:分片集群數(shù)據(jù)分片、數(shù)據(jù)路由

當(dāng)然,除了 Redis 之外,對于構(gòu)建任何一個數(shù)據(jù)集群,你都可以沿用這個思路去思考、去優(yōu)化,看看它們到底是如何做的。

例如當(dāng)你在使用 MySQL 時(shí),你可以思考一下 MySQL 與 Redis 有哪些不同?MySQL 為了做到高性能、高可用,又是如何做的?其實(shí)思路都是類似的。

我們現(xiàn)在到處可見分布式系統(tǒng)、數(shù)據(jù)集群,我希望通過這篇文章,你可以理解這些軟件是如何一步步演化過來的,在演化過程中,它們遇到了哪些問題,為了解決這些問題,這些軟件的設(shè)計(jì)者設(shè)計(jì)了怎樣的方案,做了哪些取舍?

你只有了解了其中的原理,掌握了分析問題、解決問題的能力,這樣在以后的開發(fā)過程中,或是學(xué)習(xí)其它優(yōu)秀軟件時(shí),就能快速地找到「重點(diǎn)」,在最短的時(shí)間掌握它,并能在實(shí)際應(yīng)用中發(fā)揮它們的優(yōu)勢。

其實(shí)這個思考過程,也是做「架構(gòu)設(shè)計(jì)」的思路。在做軟件架構(gòu)設(shè)計(jì)時(shí),你面臨的場景就是發(fā)現(xiàn)問題、分析問題、解決問題,一步步去演化、升級你的架構(gòu),最后在性能、可靠性方面達(dá)到一個平衡。雖然各種軟件層出不窮,但架構(gòu)設(shè)計(jì)的思想不會變,我希望你真正吸收的是這些思想,這樣才可以做到以不變應(yīng)萬變。


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: 驅(qū)動電源

在工業(yè)自動化蓬勃發(fā)展的當(dāng)下,工業(yè)電機(jī)作為核心動力設(shè)備,其驅(qū)動電源的性能直接關(guān)系到整個系統(tǒng)的穩(wěn)定性和可靠性。其中,反電動勢抑制與過流保護(hù)是驅(qū)動電源設(shè)計(jì)中至關(guān)重要的兩個環(huán)節(jié),集成化方案的設(shè)計(jì)成為提升電機(jī)驅(qū)動性能的關(guān)鍵。

關(guān)鍵字: 工業(yè)電機(jī) 驅(qū)動電源

LED 驅(qū)動電源作為 LED 照明系統(tǒng)的 “心臟”,其穩(wěn)定性直接決定了整個照明設(shè)備的使用壽命。然而,在實(shí)際應(yīng)用中,LED 驅(qū)動電源易損壞的問題卻十分常見,不僅增加了維護(hù)成本,還影響了用戶體驗(yàn)。要解決這一問題,需從設(shè)計(jì)、生...

關(guān)鍵字: 驅(qū)動電源 照明系統(tǒng) 散熱

根據(jù)LED驅(qū)動電源的公式,電感內(nèi)電流波動大小和電感值成反比,輸出紋波和輸出電容值成反比。所以加大電感值和輸出電容值可以減小紋波。

關(guān)鍵字: LED 設(shè)計(jì) 驅(qū)動電源

電動汽車(EV)作為新能源汽車的重要代表,正逐漸成為全球汽車產(chǎn)業(yè)的重要發(fā)展方向。電動汽車的核心技術(shù)之一是電機(jī)驅(qū)動控制系統(tǒng),而絕緣柵雙極型晶體管(IGBT)作為電機(jī)驅(qū)動系統(tǒng)中的關(guān)鍵元件,其性能直接影響到電動汽車的動力性能和...

關(guān)鍵字: 電動汽車 新能源 驅(qū)動電源

在現(xiàn)代城市建設(shè)中,街道及停車場照明作為基礎(chǔ)設(shè)施的重要組成部分,其質(zhì)量和效率直接關(guān)系到城市的公共安全、居民生活質(zhì)量和能源利用效率。隨著科技的進(jìn)步,高亮度白光發(fā)光二極管(LED)因其獨(dú)特的優(yōu)勢逐漸取代傳統(tǒng)光源,成為大功率區(qū)域...

關(guān)鍵字: 發(fā)光二極管 驅(qū)動電源 LED

LED通用照明設(shè)計(jì)工程師會遇到許多挑戰(zhàn),如功率密度、功率因數(shù)校正(PFC)、空間受限和可靠性等。

關(guān)鍵字: LED 驅(qū)動電源 功率因數(shù)校正

在LED照明技術(shù)日益普及的今天,LED驅(qū)動電源的電磁干擾(EMI)問題成為了一個不可忽視的挑戰(zhàn)。電磁干擾不僅會影響LED燈具的正常工作,還可能對周圍電子設(shè)備造成不利影響,甚至引發(fā)系統(tǒng)故障。因此,采取有效的硬件措施來解決L...

關(guān)鍵字: LED照明技術(shù) 電磁干擾 驅(qū)動電源

開關(guān)電源具有效率高的特性,而且開關(guān)電源的變壓器體積比串聯(lián)穩(wěn)壓型電源的要小得多,電源電路比較整潔,整機(jī)重量也有所下降,所以,現(xiàn)在的LED驅(qū)動電源

關(guān)鍵字: LED 驅(qū)動電源 開關(guān)電源

LED驅(qū)動電源是把電源供應(yīng)轉(zhuǎn)換為特定的電壓電流以驅(qū)動LED發(fā)光的電壓轉(zhuǎn)換器,通常情況下:LED驅(qū)動電源的輸入包括高壓工頻交流(即市電)、低壓直流、高壓直流、低壓高頻交流(如電子變壓器的輸出)等。

關(guān)鍵字: LED 隧道燈 驅(qū)動電源
關(guān)閉