Redis入門必備指南

這篇文章為大家?guī)碛嘘P(guān)redis入門必備指南的詳細(xì)介紹。大部分命令行知識點(diǎn)都是大家經(jīng)常用到的,為此分享給大家做個參考。一起跟隨小編過來看看吧。

創(chuàng)新互聯(lián)是專業(yè)的隆化網(wǎng)站建設(shè)公司,隆化接單;提供網(wǎng)站建設(shè)、網(wǎng)站制作,網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行隆化網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!

由于數(shù)據(jù)庫的緩存一般是針對查詢的內(nèi)容,而且粒度也比較小,一般只有表中的數(shù)據(jù)沒有發(fā)生變動的時候,數(shù)據(jù)庫的緩存才會產(chǎn)生作用。

但這并不能減少業(yè)務(wù)邏輯對數(shù)據(jù)庫的增刪改操作的 IO 壓力,因此緩存技術(shù)應(yīng)運(yùn)而生,該技術(shù)實(shí)現(xiàn)了對熱點(diǎn)數(shù)據(jù)的高速緩存,可以大大緩解后端數(shù)據(jù)庫的壓力。

主流應(yīng)用架構(gòu)

Redis入門必備指南

客戶端在對數(shù)據(jù)庫發(fā)起請求時,先到緩存層查看是否有所需的數(shù)據(jù),如果緩存層存有客戶端所需的數(shù)據(jù),則直接從緩存層返回,否則進(jìn)行穿透查詢,對數(shù)據(jù)庫進(jìn)行查詢。

如果在數(shù)據(jù)庫中查詢到該數(shù)據(jù),則將該數(shù)據(jù)回寫到緩存層,以便下次客戶端再次查詢能夠直接從緩存層獲取數(shù)據(jù)。

緩存中間件 Memcache 和 Redis 的區(qū)別

Memcache 的代碼層類似 Hash,特點(diǎn)如下:

  • 支持簡單數(shù)據(jù)類型

  • 不支持?jǐn)?shù)據(jù)持久化存儲

  • 不支持主從

  • 不支持分片

Redis 特點(diǎn)如下:

  • 數(shù)據(jù)類型豐富

  • 支持?jǐn)?shù)據(jù)磁盤持久化存儲

  • 支持主從

  • 支持分片

為什么 Redis 能這么快

Redis 的效率很高,官方給出的數(shù)據(jù)是 100000+QPS,這是因?yàn)椋?/p>

  • Redis 完全基于內(nèi)存,絕大部分請求是純粹的內(nèi)存操作,執(zhí)行效率高。

  • Redis 使用單進(jìn)程單線程模型的(K,V)數(shù)據(jù)庫,將數(shù)據(jù)存儲在內(nèi)存中,存取均不會受到硬盤 IO 的限制,因此其執(zhí)行速度極快。另外單線程也能處理高并發(fā)請求,還可以避免頻繁上下文切換和鎖的競爭,如果想要多核運(yùn)行也可以啟動多個實(shí)例。

  • 數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作也簡單,Redis 不使用表,不會強(qiáng)制用戶對各個關(guān)系進(jìn)行關(guān)聯(lián),不會有復(fù)雜的關(guān)系限制,其存儲結(jié)構(gòu)就是鍵值對,類似于 HashMap,HashMap 最大的優(yōu)點(diǎn)就是存取的時間復(fù)雜度為 O(1)。

  • Redis 使用多路 I/O 復(fù)用模型,為非阻塞 IO。

注:Redis 采用的 I/O 多路復(fù)用函數(shù):epoll/kqueue/evport/select。

選用策略:

  • 因地制宜,優(yōu)先選擇時間復(fù)雜度為 O(1) 的 I/O 多路復(fù)用函數(shù)作為底層實(shí)現(xiàn)。

  • 由于 Select 要遍歷每一個 IO,所以其時間復(fù)雜度為 O(n),通常被作為保底方案。

  • 基于 React 設(shè)計(jì)模式監(jiān)聽 I/O 事件。

Redis 的數(shù)據(jù)類型

String

最基本的數(shù)據(jù)類型,其值最大可存儲 512M,二進(jìn)制安全(Redis 的 String 可以包含任何二進(jìn)制數(shù)據(jù),包含 jpg 對象等)。

Redis入門必備指南

注:如果重復(fù)寫入 key 相同的鍵值對,后寫入的會將之前寫入的覆蓋。

Hash

String 元素組成的字典,適用于存儲對象。

Redis入門必備指南

List

列表,按照 String 元素插入順序排序。其順序?yàn)楹筮M(jìn)先出。由于其具有棧的特性,所以可以實(shí)現(xiàn)如“最新消息排行榜”這類的功能。

Redis入門必備指南

Set

String 元素組成的無序集合,通過哈希表實(shí)現(xiàn)(增刪改查時間復(fù)雜度為 O(1)),不允許重復(fù)。

Redis入門必備指南

另外,當(dāng)我們使用 Smembers 遍歷 Set 中的元素時,其順序也是不確定的,是通過 Hash 運(yùn)算過后的結(jié)果。

Redis 還對集合提供了求交集、并集、差集等操作,可以實(shí)現(xiàn)如同共同關(guān)注,共同好友等功能。

Sorted Set

通過分?jǐn)?shù)來為集合中的成員進(jìn)行從小到大的排序。

Redis入門必備指南

更高級的 Redis 類型

用于計(jì)數(shù)的 HyperLogLog、用于支持存儲地理位置信息的 Geo。

從海量 Key 里查詢出某一個固定前綴的 Key

假設(shè) Redis 中有十億條 Key,如何從這么多 Key 中找到固定前綴的 Key?

方法 1:使用 Keys [pattern]:查找所有符合給定模式 Pattern 的 Key

使用 Keys [pattern] 指令可以找到所有符合 Pattern 條件的 Key,但是 Keys 會一次性返回所有符合條件的 Key,所以會造成 Redis 的卡頓。

假設(shè) Redis 此時正在生產(chǎn)環(huán)境下,使用該命令就會造成隱患,另外如果一次性返回所有 Key,對內(nèi)存的消耗在某些條件下也是巨大的。

例:

keys test* //返回所有以test為前綴的key

方法 2:使用 SCAN cursor [MATCH pattern] [COUNT count]

注:

  • cursor:游標(biāo)

  • MATCH pattern:查詢 Key 的條件

  • Count:返回的條數(shù)

SCAN 是一個基于游標(biāo)的迭代器,需要基于上一次的游標(biāo)延續(xù)之前的迭代過程。

SCAN 以 0 作為游標(biāo),開始一次新的迭代,直到命令返回游標(biāo) 0 完成一次遍歷。

此命令并不保證每次執(zhí)行都返回某個給定數(shù)量的元素,甚至?xí)祷?0 個元素,但只要游標(biāo)不是 0,程序都不會認(rèn)為 SCAN 命令結(jié)束,但是返回的元素?cái)?shù)量大概率符合 Count 參數(shù)。另外,SCAN 支持模糊查詢。

例:

SCAN 0 MATCH test* COUNT 10 //每次返回10條以test為前綴的key

如何通過 Redis 實(shí)現(xiàn)分布式鎖

分布式鎖

分布式鎖是控制分布式系統(tǒng)之間共同訪問共享資源的一種鎖的實(shí)現(xiàn)。如果一個系統(tǒng),或者不同系統(tǒng)的不同主機(jī)之間共享某個資源時,往往需要互斥,來排除干擾,滿足數(shù)據(jù)一致性。

分布式鎖需要解決的問題如下:

  • 互斥性:任意時刻只有一個客戶端獲取到鎖,不能有兩個客戶端同時獲取到鎖。

  • 安全性:鎖只能被持有該鎖的客戶端刪除,不能由其他客戶端刪除。

  • 死鎖:獲取鎖的客戶端因?yàn)槟承┰蚨礄C(jī)繼而無法釋放鎖,其他客戶端再也無法獲取鎖而導(dǎo)致死鎖,此時需要有特殊機(jī)制來避免死鎖。

  • 容錯:當(dāng)各個節(jié)點(diǎn),如某個 Redis 節(jié)點(diǎn)宕機(jī)的時候,客戶端仍然能夠獲取鎖或釋放鎖。

如何使用 Redis 實(shí)現(xiàn)分布式鎖

使用 SETNX 實(shí)現(xiàn),SETNX key value:如果 Key 不存在,則創(chuàng)建并賦值。

該命令時間復(fù)雜度為 O(1),如果設(shè)置成功,則返回 1,否則返回 0。

Redis入門必備指南

由于 SETNX 指令操作簡單,且是原子性的,所以初期的時候經(jīng)常被人們作為分布式鎖,我們在應(yīng)用的時候,可以在某個共享資源區(qū)之前先使用 SETNX 指令,查看是否設(shè)置成功。

如果設(shè)置成功則說明前方?jīng)]有客戶端正在訪問該資源,如果設(shè)置失敗則說明有客戶端正在訪問該資源,那么當(dāng)前客戶端就需要等待。

但是如果真的這么做,就會存在一個問題,因?yàn)?SETNX 是長久存在的,所以假設(shè)一個客戶端正在訪問資源,并且上鎖,那么當(dāng)這個客戶端結(jié)束訪問時,該鎖依舊存在,后來者也無法成功獲取鎖,這個該如何解決呢?

由于 SETNX 并不支持傳入 EXPIRE 參數(shù),所以我們可以直接使用 EXPIRE 指令來對特定的 Key 來設(shè)置過期時間。

用法:

EXPIRE key seconds

Redis入門必備指南

程序:

RedisService redisService = SpringUtils.getBean(RedisService.class);
long status = redisService.setnx(key,"1");if(status == 1){
 redisService.expire(key,expire);
 doOcuppiedWork();
}

這段程序存在的問題:假設(shè)程序運(yùn)行到第二行出現(xiàn)異常,那么程序來不及設(shè)置過期時間就結(jié)束了,則 Key 會一直存在,等同于鎖一直被持有無法釋放。

出現(xiàn)此問題的根本原因?yàn)椋涸有缘貌坏綕M足。

解決:從 Redis 2.6.12 版本開始,我們就可以使用 Set 操作,將 SETNX 和 EXPIRE 融合在一起執(zhí)行,具體做法如下:

  • EX second:設(shè)置鍵的過期時間為 Second 秒。

  • PX millisecond:設(shè)置鍵的過期時間為 MilliSecond 毫秒。

  • NX:只在鍵不存在時,才對鍵進(jìn)行設(shè)置操作。

  • XX:只在鍵已經(jīng)存在時,才對鍵進(jìn)行設(shè)置操作。

SET KEY value [EX seconds] [PX milliseconds] [NX|XX]

注:SET 操作成功完成時才會返回 OK,否則返回 nil。

有了 SET 我們就可以在程序中使用類似下面的代碼實(shí)現(xiàn)分布式鎖了:

RedisService redisService = SpringUtils.getBean(RedisService.class);
String result = redisService.set(lockKey,requestId,SET_IF_NOT_EXIST,SET_WITH_EXPIRE_TIME,expireTime);if("OK.equals(result)"){
 doOcuppiredWork();
}

如何實(shí)現(xiàn)異步隊(duì)列

①使用 Redis 中的 List 作為隊(duì)列

使用上文所說的 Redis 的數(shù)據(jù)結(jié)構(gòu)中的 List 作為隊(duì)列 Rpush 生產(chǎn)消息,LPOP 消費(fèi)消息。

Redis入門必備指南

此時我們可以看到,該隊(duì)列是使用 Rpush 生產(chǎn)隊(duì)列,使用 LPOP 消費(fèi)隊(duì)列。

在這個生產(chǎn)者-消費(fèi)者隊(duì)列里,當(dāng) LPOP 沒有消息時,證明該隊(duì)列中沒有元素,并且生產(chǎn)者還沒有來得及生產(chǎn)新的數(shù)據(jù)。

缺點(diǎn):LPOP 不會等待隊(duì)列中有值之后再消費(fèi),而是直接進(jìn)行消費(fèi)。

彌補(bǔ):可以通過在應(yīng)用層引入 Sleep 機(jī)制去調(diào)用 LPOP 重試。

②使用 BLPOP key [key…] timeout

BLPOP key [key …] timeout:阻塞直到隊(duì)列有消息或者超時。

Redis入門必備指南

Redis入門必備指南

Redis入門必備指南

缺點(diǎn):按照此種方法,我們生產(chǎn)后的數(shù)據(jù)只能提供給各個單一消費(fèi)者消費(fèi)。能否實(shí)現(xiàn)生產(chǎn)一次就能讓多個消費(fèi)者消費(fèi)呢?

③Pub/Sub:主題訂閱者模式

發(fā)送者(Pub)發(fā)送消息,訂閱者(Sub)接收消息。訂閱者可以訂閱任意數(shù)量的頻道。

Redis入門必備指南

Pub/Sub模式的缺點(diǎn):消息的發(fā)布是無狀態(tài)的,無法保證可達(dá)。對于發(fā)布者來說,消息是“即發(fā)即失”的。

此時如果某個消費(fèi)者在生產(chǎn)者發(fā)布消息時下線,重新上線之后,是無法接收該消息的,要解決該問題需要使用專業(yè)的消息隊(duì)列,如 Kafka…此處不再贅述。

Redis 持久化

什么是持久化

持久化,即將數(shù)據(jù)持久存儲,而不因斷電或其他各種復(fù)雜外部環(huán)境影響數(shù)據(jù)的完整性。

由于 Redis 將數(shù)據(jù)存儲在內(nèi)存而不是磁盤中,所以內(nèi)存一旦斷電,Redis 中存儲的數(shù)據(jù)也隨即消失,這往往是用戶不期望的,所以 Redis 有持久化機(jī)制來保證數(shù)據(jù)的安全性。

Redis 如何做持久化

Redis 目前有兩種持久化方式,即 RDB 和 AOF,RDB 是通過保存某個時間點(diǎn)的全量數(shù)據(jù)快照實(shí)現(xiàn)數(shù)據(jù)的持久化,當(dāng)恢復(fù)數(shù)據(jù)時,直接通過 RDB 文件中的快照,將數(shù)據(jù)恢復(fù)。

RDB(快照)持久化

RDB持久化會在某個特定的間隔保存那個時間點(diǎn)的全量數(shù)據(jù)的快照。

RDB 配置文件,redis.conf:

 save 900 1 #在900s內(nèi)如果有1條數(shù)據(jù)被寫入,則產(chǎn)生一次快照。
 save 300 10 #在300s內(nèi)如果有10條數(shù)據(jù)被寫入,則產(chǎn)生一次快照
 save 60 10000 #在60s內(nèi)如果有10000條數(shù)據(jù)被寫入,則產(chǎn)生一次快照
 stop-writes-on-bgsave-error yes 
 #stop-writes-on-bgsave-error :
 如果為yes則表示,當(dāng)備份進(jìn)程出錯的時候,
 主進(jìn)程就停止進(jìn)行接受新的寫入操作,這樣是為了保護(hù)持久化的數(shù)據(jù)一致性的問題。

①RDB 的創(chuàng)建與載入

SAVE:阻塞 Redis 的服務(wù)器進(jìn)程,直到 RDB 文件被創(chuàng)建完畢。SAVE 命令很少被使用,因?yàn)槠鋾枞骶€程來保證快照的寫入,由于 Redis 是使用一個主線程來接收所有客戶端請求,這樣會阻塞所有客戶端請求。

BGSAVE:該指令會 Fork 出一個子進(jìn)程來創(chuàng)建 RDB 文件,不阻塞服務(wù)器進(jìn)程,子進(jìn)程接收請求并創(chuàng)建 RDB 快照,父進(jìn)程繼續(xù)接收客戶端的請求。

子進(jìn)程在完成文件的創(chuàng)建時會向父進(jìn)程發(fā)送信號,父進(jìn)程在接收客戶端請求的過程中,在一定的時間間隔通過輪詢來接收子進(jìn)程的信號。

我們也可以通過使用 lastsave 指令來查看 BGSAVE 是否執(zhí)行成功,lastsave 可以返回最后一次執(zhí)行成功 BGSAVE 的時間。

②自動化觸發(fā) RDB 持久化的方式

自動化觸發(fā)RDB持久化的方式如下:

  • 根據(jù) redis.conf 配置里的 SAVE m n 定時觸發(fā)(實(shí)際上使用的是 BGSAVE)。

  • 主從復(fù)制時,主節(jié)點(diǎn)自動觸發(fā)。

  • 執(zhí)行 Debug Reload。

  • 執(zhí)行 Shutdown 且沒有開啟 AOF 持久化。

③BGSAVE 的原理

Redis入門必備指南

啟動:

  • 檢查是否存在子進(jìn)程正在執(zhí)行 AOF 或者 RDB 的持久化任務(wù)。如果有則返回 false。

  • 調(diào)用 Redis 源碼中的 rdbSaveBackground 方法,方法中執(zhí)行 fork() 產(chǎn)生子進(jìn)程執(zhí)行 RDB 操作。

  • 關(guān)于 fork() 中的 Copy-On-Write。

fork() 在 Linux 中創(chuàng)建子進(jìn)程采用 Copy-On-Write(寫時拷貝技術(shù)),即如果有多個調(diào)用者同時要求相同資源(如內(nèi)存或磁盤上的數(shù)據(jù)存儲)。

他們會共同獲取相同的指針指向相同的資源,直到某個調(diào)用者試圖修改資源的內(nèi)容時,系統(tǒng)才會真正復(fù)制一份專用副本給調(diào)用者,而其他調(diào)用者所見到的最初的資源仍然保持不變。

④RDB 持久化方式的缺點(diǎn)

RDB 持久化方式的缺點(diǎn)如下:

  • 內(nèi)存數(shù)據(jù)全量同步,數(shù)據(jù)量大的狀況下,會由于 I/O 而嚴(yán)重影響性能。

  • 可能會因?yàn)?Redis 宕機(jī)而丟失從當(dāng)前至最近一次快照期間的數(shù)據(jù)。

AOF 持久化:保存寫狀態(tài)

AOF 持久化是通過保存 Redis 的寫狀態(tài)來記錄數(shù)據(jù)庫的。

相對 RDB 來說,RDB 持久化是通過備份數(shù)據(jù)庫的狀態(tài)來記錄數(shù)據(jù)庫,而 AOF 持久化是備份數(shù)據(jù)庫接收到的指令:

  • AOF 記錄除了查詢以外的所有變更數(shù)據(jù)庫狀態(tài)的指令。

  • 以增量的形式追加保存到 AOF 文件中。

開啟 AOF 持久化

①打開 redis.conf 配置文件,將 appendonly 屬性改為 yes。

②修改 appendfsync 屬性,該屬性可以接收三種參數(shù),分別是 always,everysec,no。

always 表示總是即時將緩沖區(qū)內(nèi)容寫入 AOF 文件當(dāng)中,everysec 表示每隔一秒將緩沖區(qū)內(nèi)容寫入 AOF 文件,no 表示將寫入文件操作交由操作系統(tǒng)決定。

一般來說,操作系統(tǒng)考慮效率問題,會等待緩沖區(qū)被填滿再將緩沖區(qū)數(shù)據(jù)寫入 AOF 文件中。

 appendonly yes

 #appendsync always
 appendfsync everysec # appendfsync no

日志重寫解決 AOF 文件不斷增大

隨著寫操作的不斷增加,AOF 文件會越來越大。假設(shè)遞增一個計(jì)數(shù)器 100 次,如果使用 RDB 持久化方式,我們只要保存最終結(jié)果 100 即可。

而 AOF 持久化方式需要記錄下這 100 次遞增操作的指令,而事實(shí)上要恢復(fù)這條記錄,只需要執(zhí)行一條命令就行,所以那一百條命令實(shí)際可以精簡為一條。

Redis 支持這樣的功能,在不中斷前臺服務(wù)的情況下,可以重寫 AOF 文件,同樣使用到了 COW(寫時拷貝)。

重寫過程如下:

  • 調(diào)用 fork(),創(chuàng)建一個子進(jìn)程。

  • 子進(jìn)程把新的 AOF 寫到一個臨時文件里,不依賴原來的 AOF 文件。

  • 主進(jìn)程持續(xù)將新的變動同時寫到內(nèi)存和原來的 AOF 里。

  • 主進(jìn)程獲取子進(jìn)程重寫 AOF 的完成信號,往新 AOF 同步增量變動。

  • 使用新的 AOF 文件替換掉舊的 AOF 文件。

AOF 和 RDB 的優(yōu)缺點(diǎn)

AOF 和 RDB 的優(yōu)缺點(diǎn)如下:

  • RDB 優(yōu)點(diǎn):全量數(shù)據(jù)快照,文件小,恢復(fù)快。

  • RDB 缺點(diǎn):無法保存最近一次快照之后的數(shù)據(jù)。

  • AOF 優(yōu)點(diǎn):可讀性高,適合保存增量數(shù)據(jù),數(shù)據(jù)不易丟失。

  • AOF 缺點(diǎn):文件體積大,恢復(fù)時間長。

RDB-AOF 混合持久化方式

Redis 4.0 之后推出了此種持久化方式,RDB 作為全量備份,AOF 作為增量備份,并且將此種方式作為默認(rèn)方式使用。

在上述兩種方式中,RDB 方式是將全量數(shù)據(jù)寫入 RDB 文件,這樣寫入的特點(diǎn)是文件小,恢復(fù)快,但無法保存最近一次快照之后的數(shù)據(jù),AOF 則將 Redis 指令存入文件中,這樣又會造成文件體積大,恢復(fù)時間長等弱點(diǎn)。

在 RDB-AOF 方式下,持久化策略首先將緩存中數(shù)據(jù)以 RDB 方式全量寫入文件,再將寫入后新增的數(shù)據(jù)以 AOF 的方式追加在 RDB 數(shù)據(jù)的后面,在下一次做 RDB 持久化的時候?qū)?AOF 的數(shù)據(jù)重新以 RDB 的形式寫入文件。

這種方式既可以提高讀寫和恢復(fù)效率,也可以減少文件大小,同時可以保證數(shù)據(jù)的完整性。

在此種策略的持久化過程中,子進(jìn)程會通過管道從父進(jìn)程讀取增量數(shù)據(jù),在以 RDB 格式保存全量數(shù)據(jù)時,也會通過管道讀取數(shù)據(jù),同時不會造成管道阻塞。

可以說,在此種方式下的持久化文件,前半段是 RDB 格式的全量數(shù)據(jù),后半段是 AOF 格式的增量數(shù)據(jù)。此種方式是目前較為推薦的一種持久化方式。

Redis 數(shù)據(jù)的恢復(fù)

RDB 和 AOF 文件共存情況下的恢復(fù)流程如下圖:

Redis入門必備指南

從圖可知,Redis 啟動時會先檢查 AOF 是否存在,如果 AOF 存在則直接加載 AOF,如果不存在 AOF,則直接加載 RDB 文件。

Pineline

Pipeline 和 Linux 的管道類似,它可以讓 Redis 批量執(zhí)行指令。

Redis 基于請求/響應(yīng)模型,單個請求處理需要一一應(yīng)答。如果需要同時執(zhí)行大量命令,則每條命令都需要等待上一條命令執(zhí)行完畢后才能繼續(xù)執(zhí)行,這中間不僅僅多了 RTT,還多次使用了系統(tǒng) IO。

Pipeline 由于可以批量執(zhí)行指令,所以可以節(jié)省多次 IO 和請求響應(yīng)往返的時間。但是如果指令之間存在依賴關(guān)系,則建議分批發(fā)送指令。

Redis 的同步機(jī)制

主從同步原理

Redis 一般是使用一個 Master 節(jié)點(diǎn)來進(jìn)行寫操作,而若干個 Slave 節(jié)點(diǎn)進(jìn)行讀操作,Master 和 Slave 分別代表了一個個不同的 Redis Server 實(shí)例。

另外定期的數(shù)據(jù)備份操作也是單獨(dú)選擇一個 Slave 去完成,這樣可以最大程度發(fā)揮 Redis 的性能,為的是保證數(shù)據(jù)的弱一致性和最終一致性。

另外,Master 和 Slave 的數(shù)據(jù)不是一定要即時同步的,但是在一段時間后 Master 和 Slave 的數(shù)據(jù)是趨于同步的,這就是最終一致性。

Redis入門必備指南

全同步過程如下:

  • Slave 發(fā)送 Sync 命令到 Master。

  • Master 啟動一個后臺進(jìn)程,將 Redis 中的數(shù)據(jù)快照保存到文件中。

  • Master 將保存數(shù)據(jù)快照期間接收到的寫命令緩存起來。

  • Master 完成寫文件操作后,將該文件發(fā)送給 Slave。

  • 使用新的 AOF 文件替換掉舊的 AOF 文件。

  • Master 將這期間收集的增量寫命令發(fā)送給 Slave 端。

增量同步過程如下:

  • Master 接收到用戶的操作指令,判斷是否需要傳播到 Slave。

  • 將操作記錄追加到 AOF 文件。

  • 將操作傳播到其他 Slave:對齊主從庫;往響應(yīng)緩存寫入指令。

  • 將緩存中的數(shù)據(jù)發(fā)送給 Slave。

Redis Sentinel(哨兵)

主從模式弊端:當(dāng) Master 宕機(jī)后,Redis 集群將不能對外提供寫入操作。Redis Sentinel 可解決這一問題。

解決主從同步 Master 宕機(jī)后的主從切換問題:

  • 監(jiān)控:檢查主從服務(wù)器是否運(yùn)行正常。

  • 提醒:通過 API 向管理員或者其它應(yīng)用程序發(fā)送故障通知。

  • 自動故障遷移:主從切換(在 Master 宕機(jī)后,將其中一個 Slave 轉(zhuǎn)為 Master,其他的 Slave 從該節(jié)點(diǎn)同步數(shù)據(jù))。

Redis 集群

如何從海量數(shù)據(jù)里快速找到所需?

①分片

按照某種規(guī)則去劃分?jǐn)?shù)據(jù),分散存儲在多個節(jié)點(diǎn)上。通過將數(shù)據(jù)分到多個 Redis 服務(wù)器上,來減輕單個 Redis 服務(wù)器的壓力。

②一致性 Hash 算法

既然要將數(shù)據(jù)進(jìn)行分片,那么通常的做法就是獲取節(jié)點(diǎn)的 Hash 值,然后根據(jù)節(jié)點(diǎn)數(shù)求模。

但這樣的方法有明顯的弊端,當(dāng) Redis 節(jié)點(diǎn)數(shù)需要動態(tài)增加或減少的時候,會造成大量的 Key 無法被命中。所以 Redis 中引入了一致性 Hash 算法。

該算法對 2^32 取模,將 Hash 值空間組成虛擬的圓環(huán),整個圓環(huán)按順時針方向組織,每個節(jié)點(diǎn)依次為 0、1、2…2^32-1。

之后將每個服務(wù)器進(jìn)行 Hash 運(yùn)算,確定服務(wù)器在這個 Hash 環(huán)上的地址,確定了服務(wù)器地址后,對數(shù)據(jù)使用同樣的 Hash 算法,將數(shù)據(jù)定位到特定的 Redis 服務(wù)器上。

如果定位到的地方?jīng)]有 Redis 服務(wù)器實(shí)例,則繼續(xù)順時針尋找,找到的第一臺服務(wù)器即該數(shù)據(jù)最終的服務(wù)器位置。

Redis入門必備指南

③Hash 環(huán)的數(shù)據(jù)傾斜問題

Hash 環(huán)在服務(wù)器節(jié)點(diǎn)很少的時候,容易遇到服務(wù)器節(jié)點(diǎn)不均勻的問題,這會造成數(shù)據(jù)傾斜,數(shù)據(jù)傾斜指的是被緩存的對象大部分集中在 Redis 集群的其中一臺或幾臺服務(wù)器上。

Redis入門必備指南

如上圖,一致性 Hash 算法運(yùn)算后的數(shù)據(jù)大部分被存放在 A 節(jié)點(diǎn)上,而 B 節(jié)點(diǎn)只存放了少量的數(shù)據(jù),久而久之 A 節(jié)點(diǎn)將被撐爆。

針對這一問題,可以引入虛擬節(jié)點(diǎn)解決。簡單地說,就是為每一個服務(wù)器節(jié)點(diǎn)計(jì)算多個 Hash,每個計(jì)算結(jié)果位置都放置一個此服務(wù)器節(jié)點(diǎn),稱為虛擬節(jié)點(diǎn),可以在服務(wù)器 IP 或者主機(jī)名后放置一個編號實(shí)現(xiàn)。

Redis入門必備指南

例如上圖:將 NodeA 和 NodeB 兩個節(jié)點(diǎn)分為 Node A#1-A#3,NodeB#1-B#3。

讀者福利

加微信:haolagui521備注51CTO領(lǐng)取附送學(xué)習(xí)進(jìn)階架構(gòu)資料、PDF書籍文檔、面試資料

Redis入門必備指南

Redis入門必備指南

Redis入門必備指南Redis入門必備指南

以上就是Redis實(shí)用干貨分享的詳細(xì)內(nèi)容了,看完之后是否Redis有新的認(rèn)識呢?如果想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊!

當(dāng)前名稱:Redis入門必備指南
分享路徑:http://muchs.cn/article20/ihjjco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、ChatGPT、手機(jī)網(wǎng)站建設(shè)、虛擬主機(jī)、全網(wǎng)營銷推廣、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)