1. 程式人生 > 資料庫 >redis筆記

redis筆記

 

redis的持久化機制

說白了,就是在指定的時間間隔內,將記憶體當中的資料集快照寫入磁碟,它恢復時是將快照檔案直接讀到記憶體

什麼意思呢?我們都知道,記憶體當中的資料,如果我們一斷電,那麼資料必然會丟失,但是玩過redis的同學應該都知道,我們一關機之後再啟動的時候資料是還在的,所以它必然是在redis啟動的時候重新去載入了持久化的檔案

redis提供兩種方式進行持久化,

RDB預設持久化,可以在指定的時間間隔內生成資料集的時間點快照(point-in-time snapshot)

AOF(append only file)持久化,記錄伺服器執行的所有寫操作命令,並在伺服器啟動時,通過重新執行這些命令來還原資料集。 AOF 檔案中的命令全部以 Redis 協議的格式來儲存,新命令會被追加到檔案的末尾。 Redis 還可以在後臺對 AOF 檔案進行重寫(rewrite),使得 AOF 檔案的體積不會超出儲存資料集狀態所需的實際大小。

Redis 還可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, 當 Redis 重啟時, 它會優先使用 AOF 檔案來還原資料集, 因為 AOF 檔案儲存的資料集通常比 RDB 檔案所儲存的資料集更完整。

你甚至可以關閉持久化功能,讓資料只在伺服器執行時存在。

1.RDB

RDB是一次的全量備份,即週期性的把redis當前記憶體中的全量資料寫入到一個快照檔案中。redis是單執行緒程式,這個執行緒要同時負責多個客戶端的讀寫請求,還要負責週期性的把當前記憶體中的資料寫到快照檔案中RDB中,資料寫到RDB檔案是IO操作,IO操作會嚴重影響redis的效能,甚至在持久化的過程中,讀寫請求會阻塞,為了解決這些問題,redis需要同時進行讀寫請求和持久化操作,這樣又會導致另外的問題,持久化的過程中,記憶體中的資料還在改變,假如redis正在進行持久化一個大的資料結構,在這個過程中客戶端傳送一個刪除請求,把這個大的資料結構刪掉了,這時候持久化的動作還沒有完成,那麼redis該怎麼辦呢?

redis使用作業系統的多程序COW機制(Copy On Write)機制來實現快照的持久化,在持久化過程中呼叫 glibc(Linux下的C函式庫) 的函式fork()產生一個子程序,快照持久化完全交給子程序來處理,父程序繼續處理客戶端的讀寫請求。子程序剛剛產生時,和父程序共享記憶體裡面的程式碼段和資料段,這是Linux作業系統的機制,為了節約記憶體資源,所以儘可能讓父子程序共享記憶體,這樣在程序分離的一瞬間,記憶體的增長几乎沒有明顯變化。

子程序對當前記憶體中的資料進行持久化,並不會修改當前的資料結構,如果父程序收到了讀寫請求,那麼會把處理的那一部分資料複製一份到記憶體,對複製後的資料進行修改,所以即使對某個資料進行了修改,redis持久化到RDB中的資料也是未修改的資料,這也是把RDB檔案稱為"快照"檔案的原因,子程序所看到的資料在它被建立的一瞬間就固定下來了,父程序修改的某個資料只是該資料的複製品。子程序是先將資料寫入到一個臨時檔案中,待持久化結束了,再用這個臨時檔案替換上次持久化好的檔案,整個過程中,主程序不進行任何的io操作,這就確保了極高的效能。

實際上,記憶體中的全量資料由一個個的"資料段頁面"組成,每個資料段頁面的大小為4K,客戶端要修改的資料在哪個頁面中,就會複製一份這個頁面到記憶體中,這個複製的過程稱為"頁面分離",在持久化過程中,隨著分離出的頁面越來越多,記憶體就會持續增長,但是不會超過原記憶體的2倍,因為在一次持久化的過程中,幾乎不會出現所有的頁面都會分離的情況,讀寫請求針對的只是原資料中的小部分,大部分redis資料還是"冷資料"。

如果需要進行大規模的資料恢復,且對於資料恢復的完整性不是非常敏感,那 RDB 方法要比 AOF 方式更加的高效。RDB 的缺點是最後一次持久化後的資料可能丟失。

隱患:若當前的程序的資料量龐大,那麼 fork 之後資料量*2,此時就會造成伺服器壓力大,執行效能降低

如何觸發RDB快照

可以配置符合快照觸發條件,預設的是 1 分鐘內改動 1 萬次,或者 5 分鐘改動 10 次,或者是 15 分鐘改動一次;

Save:save 時只管儲存,其他不管,全部阻塞。

Bgsave:redis 會在後臺進行快照操作,快照操作的同時還可以響應客戶端的請求,可以通過 lastsave 命令獲取最後一次成功執行快照的時間。

執行 fluhall 命令,也會產生 dump.rdb 檔案,但裡面是空的。

2.AOF

AOF日誌儲存的是redis伺服器的順序指令序列,即對記憶體中資料進行修改的指令記錄。當redis收到客戶端修改指令後,先進行引數校驗,如果校驗通過,先把該指令儲存到AOF日誌檔案中,也就是先存到磁碟,然後再執行該修改指令。

當redis宕機後重啟後,可以讀取該AOF檔案中的指令,進行資料恢復,恢復的過程就是把記錄的指令再順序執行一次,這樣就可以恢復到宕機之前的狀態。

redis在長期執行過程中,AOF日誌會越來越大,如果redis服務重啟後根據很大的AOF檔案來順序執行指令,將會非常耗時,導致redis服務長時間無法對外提供服務,所以需要對AOF檔案進行"瘦身"。"瘦身"的過程稱作AOF重寫(rewrite)。

AOF Rewrite 的原理是,主程序fork一個子程序,對當前記憶體中的資料進行遍歷,轉換成一系列的redis操作指令,並序列化到一個新的AOF日誌中,然後把序列化操作期間新收到的操作指令追加到新的AOF檔案中,追加完畢後就立即替換舊的AOF檔案,這樣就完成了"瘦身"工作,即AOF Rewrite。

redis把操作指令追加到AOF檔案這個過程,並不是直接寫到AOF檔案中,而是先寫到作業系統的記憶體快取中,這個記憶體快取是由作業系統核心分配的,然後作業系統核心會非同步地把記憶體快取中的redis操作指令刷寫到AOF檔案中。

一個新問題是,假如記憶體快取中的redis指令還沒有來得及刷寫到AOF檔案中就宕機了,那麼這部分未刷寫的指令就會丟失,不過,glibc函式庫提供了 fsync() 函式,該函式可以將指定檔案的內容強制從記憶體快取中刷寫到磁碟上。fsync操作的週期對redis的效能有很大影響,如何配置將在本文後續的內容中給出建議。

 

4.redis4.0後混合持久化機制

開啟混合持久化

4.0版本的混合持久化預設關閉的,通過aof-use-rdb-preamble配置引數控制,yes則表示開啟,no表示禁用,5.0之後預設開啟。

重啟redis時,我們很少使用RDB來恢復記憶體狀態,因為會丟失大量資料。我們通常使用AOF日誌重放,但是重放AOF日誌效能相對RDB來說要慢很多,這樣在redis例項很大的情況下,啟動需要花費很長的時間。redis-4.0為了解決這個問題,帶來了一個新的持久化選項——混合持久化。將RDB檔案的內容和增量的AOF日誌檔案存在一起。這裡的AOF日誌不再是全量
的日誌,而是自持久化開始到持久化結束的這段時間發生的增量AOF日誌,通常這部分AOF日誌很小。

混合持久化是通過bgrewriteaof完成的,不同的是當開啟混合持久化時,fork出的子程序先將共享的記憶體副本全量的以RDB方式寫入aof檔案,然後在將重寫緩衝區的增量命令以AOF方式寫入到檔案,寫入完成後通知主程序更新統計資訊,並將新的含有RDB格式和AOF格式的AOF檔案替換舊的的AOF檔案。簡單的說:新的AOF檔案前半段是RDB格式的全量資料後半段是AOF格式的增量資料。redis重啟的時候,可以先載入RDB的內容,然後再重放增量AOF日誌,就可以完全替代之前的AOF全量檔案重放,恢復效率因此大幅得到提升。

redis 持久化機制對比

(1) RDB的優缺點

優點:

  • RDB會生成多個數據檔案,每個資料檔案都代表了某一個時刻中redis的資料,這種多個數據檔案的方式,非常適合做冷備,可以將這種完整的資料檔案傳送到一些遠端的安全儲存上去。
  • 當進行RDB持久化時,對redis服務處理讀寫請求的影響非常小,可以讓redis保持高效能,因為redis主程序只需要fork一個子程序,讓子程序執行磁碟IO操作來進行RDB持久化即可。生成一次RDB檔案的過程就是把當前時刻記憶體中的資料一次性寫入檔案中,而AOF則需要先把當前記憶體中的小量資料轉換為操作指令,然後把指令寫到記憶體快取中,然後再刷寫入磁碟。
  • 相對於AOF持久化機制來說,直接基於RDB資料檔案來重啟和恢復redis的資料會更加快速。AOF,存放的是指令日誌,做資料恢復的時候,要回放和執行所有的指令日誌,從而恢復記憶體中的所有資料。而RDB,就是一份資料檔案,恢復的時候,直接載入到記憶體中即可。

缺點:

  • 如果想要在redis故障時,儘可能少的丟失資料,那麼RDB沒有AOF好。一般來說,RDB資料快照檔案,都是每隔5分鐘,或者更長時間生成一次,這個時候就得接受一旦redis程序宕機,那麼會丟失最近5分鐘的資料。這個問題,也是RDB最大的缺點,就是不適合做第一優先的恢復方案,如果你依賴RDB做第一優先恢復方案,會導致資料丟失的比較多。
  • RDB每次在fork子程序來執行RDB快照資料檔案生成的時候,如果資料檔案特別大,可能會導致對客戶端提供的服務暫停數毫秒,甚至數秒。所以一般不要讓生成RDB檔案的間隔太長,否則每次生成的RDB檔案太大了,對redis本身的效能會有影響。

(2) AOF的優缺點

優點:

  • AOF可以更好的保護資料不丟失,一般AOF會每隔1秒,通過一個後臺執行緒執行一次fsync操作,最多丟失1秒鐘的資料。
  • AOF日誌檔案以append-only模式寫入,所以沒有任何磁碟定址的開銷,寫入效能非常高,而且檔案不容易破損,即使檔案尾部破損,也很容易修復。
  • AOF日誌檔案即使過大的時候,出現後臺重寫操作,也不會影響客戶端的讀寫。因為在rewrite的時候,會對其中的指令進行壓縮,會創建出一份需要恢復資料的最小日誌出來。
  • AOF日誌檔案的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有資料,只要這個時候後臺rewrite還沒有發生,那麼就可以立即拷貝AOF檔案,將最後一條flushall命令給刪了,然後再將該AOF檔案放回去,就可以通過恢復機制,自動恢復所有資料。

缺點:

  • 對於同一份資料來說,AOF日誌檔案通常比RDB資料快照檔案更大。
  • AOF的寫效能比RDB的寫效能低,因為AOF一般會配置成每秒fsync一次日誌檔案,當然,每秒一次fsync,效能也還是很高的,只不過比起RDB來說效能低,如果要保證一條資料都不丟,也是可以的,AOF的fsync設定成每寫入一條資料,fsync一次,但是這樣,redis的效能會大大下降。
  • 基於AOF檔案做恢復的速度不如基於RDB檔案做恢復的速度。

(3) 混合持久化的優缺點

優點:結合了RDB和AOF的優點,使得資料恢復的效率大幅提升

缺點:相容性不好,redis-4.x新增,雖然最終的檔案也是.aof格式的檔案,但在4.0之前版本都不識別該aof檔案,同時由於前部分是RDB格式,閱讀性較差。

(4) 如何選擇redis持久化機制

RDB和AOF到底該如何選擇

  • 不要僅僅使用RDB,因為那樣會導致你丟失很多資料
  • 也不要僅僅使用AOF,一是資料恢復慢,二是可靠性也不如RDB,畢竟RDB檔案中儲存的就是某一時刻實實在在的資料,而AOF只是操作指令,把資料轉換為操作指令不一定是百分百沒問題的。
  • 綜合使用AOF和RDB兩種持久化機制,用AOF來保證資料不丟失,作為資料恢復的第一選擇; 用RDB來做不同程度的冷備,在AOF檔案都丟失或損壞不可用的時候,還可以使用RDB來進行快速的資料恢復。

(5) AOF和RDB同時工作

  • redis在寫RDB檔案的時候不會執行AOF rewrite; redis在執行AOF rewrite的時候不會生成新的RDB;
  • 如果redis正在生成新的RDB檔案,此時使用者執行bgrewriteaof命令手動重寫AOF檔案,那麼等RDB快照生成之後,才會去執行AOF rewrite;
  • 同時有RDB檔案和AOF日誌檔案,那麼redis重啟的時候,會優先使用AOF進行資料恢復,因為其中的日誌更完整。

效能建議(這裡只針對單機版redis持久化做效能建議):

因為RDB檔案只用作後備用途,只要15分鐘備份一次就夠了,只保留save 900 1這條規則。

如果Enalbe AOF,好處是在最惡劣情況下也只會丟失不超過兩秒資料,啟動指令碼較簡單隻load自己的AOF檔案就可以了。 代價一是帶來了持續的IO,二是AOF rewrite的最後將rewrite過程中產生的新資料寫到新檔案造成的阻塞幾乎是不可避免的。 只要硬碟許可,應該儘量減少AOF rewrite的頻率,AOF重寫的基礎大小預設值64M太小了,可以設到5G以上。 預設超過原大小100%大小時重寫可以改到適當的數值。


redis叢集專題

Redis主從複製

單機有什麼問題:單機故障,容量瓶頸,qps瓶頸

主從複製:主節點負責寫資料,從節點負責讀資料,主節點定期把資料同步到從節點保證資料的一致性。達到了1.讀寫分離,2.容災備份

主從複製的方式

  • // 命令列使用
    slaveof ip port // 使用命令後自身資料會被清空,但取消slave只是停止複製,並不清空
    
    優點:無需重啟。缺點:不便於管理
  • // 配置檔案中配置
    slaveof ip port
    slave-read-only yes //只允許從節點進行讀操作
    優點:統一配置。缺點:需要重啟

從節點建議用只讀模式slave-read-only=yes,若從節點修改資料,主從資料不一致

拓撲結構

a)一主一從:用於主節點故障轉移從節點,當主節點的“寫”命令併發高且需要持久化,可以只在從節點開啟AOF(主節點不需要),這樣即保證了資料的安全性,也避免持久化對主節點的影響 

b)一主多從:針對“讀”較多的場景,“讀”由多個從節點來分擔,但節點越多,主節點同步到多節點的次數也越多,影響頻寬,也加重主節點的穩定

c)樹狀主從:一主多從的缺點(主節點推送次數多壓力大)可用些方案解決,主節點只推送一次資料到從節點B,再由從節點B推送到C,減輕主節點推送的壓力。

主從複製

全量複製

一般用於初次複製場景(第一次建立SLAVE後全量)或其它無法進行部分複製的情況,將主節點中的所有資料都發送給從節點,是一個非常重型的操作,當資料量較大時,會對主從節點和網路造成很大的開銷

全量複製過程

  1. Redis內部會發出一個同步命令,剛開始是Psync命令,Psync ? -1表示要求master主機同步資料
  2. 主機會向從機發送run_id和offset,因為slave並沒有對應的 offset,所以是全量複製
  3. 從機slave會儲存主機master的基本資訊
  4. 主節點收到全量複製的命令後,執行bgsave(非同步執行),在後臺生成RDB檔案(快照),並使用一個緩衝區(稱為複製緩衝區)記錄從現在開始執行的所有寫命令
  5. 主機發送RDB檔案給從機
  6. 傳送緩衝區資料
  7. 重新整理舊的資料。從節點在載入主節點的資料之前要先將老資料清除
  8. 載入RDB檔案將資料庫狀態更新至主節點執行bgsave時的資料庫狀態和緩衝區資料的載入。

全量複製開銷

  • 主節點需要bgsave
  • RDB檔案網路傳輸佔用網路io
  • 從節點要清空資料
  • 從節點載入RDB
  • 全量複製會觸發從節點AOF重寫

部分複製

https://blog.csdn.net/u010013573/article/details/88288941

部分複製是Redis 2.8以後出現的,用於處理在主從複製中因網路閃斷等原因造成的資料丟失場景,當從節點再次連上主節點後,如果條件允許,主節點會補發丟失資料給從節點。因為補發的資料遠遠小於全量資料,可以有效避免全量複製的過高開銷,需要注意的是,如果網路中斷時間過長,造成主節點沒有能夠完整地儲存中斷期間執行的寫命令,則無法進行部分複製,仍使用全量複製

部分複製過程

  1. 如果網路抖動(連線斷開 connection lost)
  2. 主機master 還是會寫 repl_back_buffer(複製緩衝區)
  3. 從機slave 會繼續嘗試連線主機
  4. 從機slave 會把自己當前 run_id 和偏移量傳輸給主機 master,並且執行 pysnc 命令同步
  5. 如果master發現你的偏移量是在緩衝區的範圍內,就會返回 continue命令
  6. 同步了offset的部分資料,所以部分複製的基礎就是偏移量 offset。

伺服器執行ID(run_id):每個Redis節點(無論主從),在啟動時都會自動生成一個隨機ID(每次啟動都不一樣),由40個隨機的十六進位制字元組成;run_id用來唯一識別一個Redis節點。 通過info server命令,可以檢視節點的run_id。

 

心跳

主從有長連線心跳,主節點預設每10S向從節點發ping命令,repl-ping-slave-period控制傳送頻率

 

缺點

1.由於所有的寫操作都是先在Master上操作,然後同步更新到Slave上,所以從Master同步到Slave機器有一定的延遲,當系統很繁忙的時候,延遲問題會更加嚴重,Slave機器數量的增加也會使這個問題更加嚴重。

2.當主機宕機之後,將不能進行寫操作,需要手動將從機升級為主機,從機需要重新制定master

redis哨兵模式

在Redis 2.8版本開始引入。哨兵的核心功能是主節點的自動故障轉移。

通俗來講哨兵模式的出現是就是為了解決我們主從複製模式中需要我們人為操作的東西變為自動版,並且它比人為要更及時。當主節點出現故障時,由Redis Sentinel自動完成故障發現和轉移,並通知應用方,實現高可用性。整個過程只需要一個哨兵節點來完成,首先使用Raft演算法(選舉演算法)實現選舉機制,選出一個哨兵節點來完成轉移和通知

監控(Monitoring):哨兵會不斷地檢查主節點和從節點是否運作正常。

自動故障轉移(Automatic Failover):當主節點不能正常工作時,哨兵會開始自動故障轉移操作,它會將失效主節點的其中一個從節點升級為新的主節點,並讓其他從節點改為複製新的主節點。

配置提供者(Configuration Provider):客戶端在初始化時,通過連線哨兵來獲得當前Redis服務的主節點地址。

通知(Notification):哨兵可以將故障轉移的結果傳送給客戶端。

其中,監控和自動故障轉移功能,使得哨兵可以及時發現主節點故障並完成轉移;而配置提供者和通知功能,則需要在與客戶端的互動中才能體現。

架構

哨兵節點:哨兵系統由一個或多個哨兵節點組成,哨兵節點是特殊的Redis節點,不儲存資料。

資料節點:主節點和從節點都是資料節點。

基本原理

關於哨兵的原理,關鍵是瞭解以下幾個概念:

主觀下線:在心跳檢測的定時任務中,如果其他節點超過一定時間沒有回覆,哨兵節點就會將其進行主觀下線。顧名思義,主觀下線的意思是一個哨兵節點“主觀地”判斷下線;與主觀下線相對應的是客觀下線。

客觀下線:哨兵節點在對主節點進行主觀下線後,會通過sentinel is-master-down-by-addr命令詢問其他哨兵節點該主節點的狀態;如果判斷主節點下線的哨兵數量達到一定數值,則對該主節點進行客觀下線。

需要特別注意的是,客觀下線是主節點才有的概念;如果從節點和哨兵節點發生故障,被哨兵主觀下線後,不會再有後續的客觀下線和故障轉移操作。

定時任務

每個哨兵節點維護了3個定時任務。定時任務的功能分別如下:

1.每10秒通過向主從節點發送info命令獲取最新的主從結構;發現slave節點,確定主從關係

2.每2秒通過釋出訂閱功能獲取其他哨兵節點的資訊;SUBSCRIBE c2 PUBLISH c2 hello-redis,互動對節點的“看法”和自身情況

3.每1秒通過向其他節點發送ping命令進行心跳檢測,判斷是否下線(monitor)。心跳檢測,失敗判斷依據

領導者哨兵選舉流程

a)每個線上的哨兵節點都可以成為領導者,當它確認(比如哨兵3)主節點下線時,會向其它哨兵發is-master-down-by-addr命令,徵求判斷並要求將自己設定為領導者,由領導者處理故障轉移;
b)當其它哨兵收到此命令時,可以同意或者拒絕它成為領導者;
c)如果哨兵3發現自己在選舉的票數大於等於num(sentinels)/2+1時,將成為領導者,如果沒有超過,繼續選舉…………

故障轉移

選舉出的領導者哨兵,開始進行故障轉移操作,該操作大體可以分為3個步驟:

a)由Sentinel節點定期監控發現主節點是否出現了故障

sentinel會向master傳送心跳PING來確認master是否存活,如果master在“一定時間範圍”內不迴應PONG 或者是回覆了一個錯誤訊息,那麼這個sentinel會主觀地(單方面地)認為這個master已經不可用了

 b) 當主節點出現故障,此時3個Sentinel節點共同選舉了Sentinel3節點為領導,負載處理主節點的故障轉移

c) 由Sentinel3領導者節點執行故障轉移,過程和主從複製一樣,但是自動執行

流程:

    1. 將slave-1脫離原從節點,升級主節點,

         2. 將從節點slave-2指向新的主節點

         3. 通知客戶端主節點已更換

         4. 將原主節點(oldMaster)變成從節點,指向新的主節點

 d) 故障轉移後的redis sentinel的拓撲結構圖

 

在從節點中選擇新的主節點:選擇的原則是,

1.首先過濾掉不健康的從節點;

2.然後選擇優先順序最高的從節點(由replica-priority指定);如果優先順序無法區分,

3.則選擇複製偏移量最大的從節點;如果仍無法區分,

4.則選擇runid最小的從節點。

更新主從狀態:通過slaveof no one命令,讓選出來的從節點成為主節點;並通過slaveof命令讓其他節點成為其從節點。

將已經下線的主節點(即6379)保持關注,當6379從新上線後設置為新的主節點的從節點

8.實踐建議

哨兵節點的數量應不止一個。一方面增加哨兵節點的冗餘,避免哨兵本身成為高可用的瓶頸;另一方面減少對下線的誤判。此外,這些不同的哨兵節點應部署在不同的物理機上。

哨兵節點的數量應該是奇數,便於哨兵通過投票做出“決策”:領導者選舉的決策、客觀下線的決策等。

各個哨兵節點的配置應一致,包括硬體、引數等;此外應保證時間準確、一致。

 

9.總結

在主從複製的基礎上,哨兵引入了主節點的自動故障轉移,進一步提高了Redis的高可用性;但是哨兵的缺陷同樣很明顯:哨兵無法對從節點進行自動故障轉移,在讀寫分離場景下,從節點故障會導致讀服務不可用,需要我們對從節點做額外的監控、切換操作。此外,哨兵仍然沒有解決寫操作無法負載均衡、及儲存能力受到單機限制的問題

 


redis cluster高可用叢集

Redis有三種叢集模式,分別是:

* 主從模式

* Sentinel模式

* Cluster模式

redis cluster叢集是一個由多個主從節點群組成的分散式伺服器群,它具有複製、高可用和分片特 性。Redis cluster叢集不需要sentinel哨兵也能完成節點移除和故障轉移的功能。需要將每個節點 設定成叢集模式,這種叢集模式沒有中心節點,可水平擴充套件,據官方文件稱可以線性擴充套件到 1000節點。redis cluster叢集的效能和高可用性均優於之前版本的哨兵模式,且叢集配置非常簡單

redis cluster叢集搭建

1.原生搭建

1.配置開啟cluster節點

cluster-enabled yes(啟動叢集模式)

cluster-config-file nodes-8001.conf(這裡800x最好和port對應上)

2.meet

cluster meet ip port

3.指派槽

檢視crc16 演算法算出key的槽位命令 cluster keyslot key

16384/3 0-5461 5462-10922 10923-16383 16384/4 4096

cluster addslots slot(槽位下標)

4.分配主從

cluster replicate node-id

2.使用redis提供的rb指令碼

redis cluster叢集需要至少要三個master節點,我們這裡搭建三個master節點,並且給每個 master再搭建一個slave節點,總共6個redis節點,由於節點數較多,這裡採用在一臺機器 上建立6個redis例項,並將這6個redis例項配置成叢集模式,所以這裡搭建的是偽叢集模 式,當然真正的分散式叢集的配置方法幾乎一樣,搭建偽叢集的步驟如下: 第一步:在/usr/local下建立資料夾redis-cluster,然後在其下面分別建立6個資料夾如下 (1)mkdir -p /usr/local/redis-cluster (2)mkdir 8001、 mkdir 8002、 mkdir 8003、 mkdir 8004、 mkdir 8005、 mkdir 8006 第一步:把之前的redis.conf配置檔案copy到8001下,修改如下內容: (1)daemonize yes (2)port 8001(分別對每個機器的埠號進行設定) (3)bind 127.0.0.1(如果只在本機玩則可以指定為127.0.0.1 如果需要外網訪問則需要指定本機真實ip) 定可能會出現迴圈查詢叢集節點機器的情況) (4)dir /usr/local/redis-cluster/8001/(指定資料檔案存放位置,必須要指定不同的目 錄位置,不然會丟失資料) (5)cluster-enabled yes(啟動叢集模式) (6)cluster-config-file nodes-8001.conf(這裡800x最好和port對應上) (7)cluster-node-timeout 5000 (8)appendonly yes 第三步:把修改後的配置檔案,分別 copy到各個文夾下,注意每個檔案要修改第2、4、6 項裡的埠號,可以用批量替換: :%s/源字串/目的字串/g 第四步:由於 redis叢集需要使用 ruby命令,所以我們需要安裝 ruby(redis5.0之後省略) (1)yum install ruby (2)yum install rubygems (3)gem install redis --version 3.0.0(安裝redis和 ruby的接囗) 第五步:分別啟動6個redis例項,然後檢查是否啟動成功 (1)/usr/local/redis/bin/redis-server /usr/local/redis-cluster/800*/redis.conf (2)ps -ef | grep redis 檢視是否啟動成功

第六步:在redis3的安裝目錄下執行 redis-trib.rb命令建立整個redis叢集 (1)cd /usr/local/redis3/src (2)./redis-trib.rb create --replicas 1 127.0.0.1:9000 127.0.0.1:9001 127.0.0.1:9002 127.0.0.1:9003 127.0.0.1:9004 127.0.0.1:9005

redis5.0使用/usr/local/bin/redis-cli --cluster create 192.168.0.104:7000 192.168.0.104:7001 192.168.0.104:7002 192.168.0.104:7003 192.168.0.104 :7004 192.168.0.104:7005 --cluster-replicas 1

第七步:驗證叢集: (1)連線任意一個客戶端即可:./redis-cli -c -h -p (-c表示叢集模式,指定ip地址和埠 號)如:/usr/local/redis/bin/redis-cli -c -h 127.0.0.1 -p 800* (2)進行驗證: cluster info(檢視叢集資訊)、cluster nodes(檢視節點列表) (3)進行資料操作驗證 (4)關閉叢集則需要逐個進行關閉,使用命令: /usr/local/redis/bin/redis-cli -c -h 127.0.0.1 -p 800* shutdown

叢集伸縮

1.擴容叢集

1.準備新節點

2.加入叢集

使用redis-cli 語法:add-node 新節點ip 埠 已存在節點ip 埠

使用原生命令 語法:cluster meet ip port

指定主從

使用redis-cli 語法(加入時指定):add-node 新節點ip 埠 已存在節點ip 埠 --cluster-slave --cluster-master-id masterID

使用原生命令 語法:cluster replicate node-id

3.遷移槽和資料

1.槽遷移計劃

語法:/redis-cli --cluster reshard 已存在節點ip : 埠

/usr/local/bin/redis-cli --cluster reshard 192.168.0.104:7000

2.遷移資料

執行流程:提示要分配多少槽-》接收節點ID-》all/done

3.新增從節點

2.縮容叢集

1.下線遷移槽

語法:redis-cli --cluster reshard --cluster-from 要遷出節點ID --cluster-to 接收槽節點ID --cluster-slots 遷出槽數量 已存在節點ip 埠

/usr/local/bin/redis-cli --cluster reshard --cluster-from a2fdd1359d03acacf2a6e558acbc006639445d53 --cluster-to 1794864d5f8af79e88cfc0f699f02b6341c78b5c --cluster-slots 1366 192.168.0.104 7000

2.忘記節點.關閉節點

語法: redis-cli --cluster del-node 已存在節點IP:埠 要刪除的節點ID

/usr/local/bin/redis-cli --cluster del-node 192.168.0.104:7000 8de55e2a7419983184cede9daab5d36ee9da1fa3

cluster客戶端

1.moved重定向:指我們傳送命令時,會對傳送的key進行crc16演算法,得到一個數字,然而我們連線的客戶端並不是管理這個數字的範圍,所以會返回錯誤並告訴你此key應該對應的槽位,然後客戶端需要捕獲此異常,重新發起請求到對應的槽位

2.asx重定向:指在我們送發命令時,對應的客戶端正在遷移槽位中,所以此時我們不能確定這個key是還在舊的節點中還是新的節點中

3.smart客戶端

1.從叢集中選取一個可執行節點,使用cluster slots初始化槽和節點對映。

2.將cluster slots的結果對映到本地,為每個節點建立jedispool

3.準備執行命令

故障轉移(與哨兵相似)

1.故障發現: 通過ping/pong訊息實現故障發現(不依賴sentinel)

2.故障恢復

1.檢查資格

1.每個從節點檢查與主節點的斷開時間

超過cluster-node-timeout * cluster-replica-validity-factor 時間取消資格

2.選擇偏移量最大的

替換主節點

1.當前從節點取消複製變為主節點(slaveof no one)

2.撤銷以前主節點的槽位,給新的主節點

3.向叢集廣播訊息,表明已經替換了故障節點

redis叢集演變過程

1.單機版

核心技術:持久化

持久化是最簡單的高可用方法(有時甚至不被歸為高可用的手段),主要作用是資料備份,即將資料儲存在硬碟,保證資料不會因程序退出而丟失。

2.主從複製

複製是高可用Redis的基礎,哨兵和叢集都是在複製基礎上實現高可用的。複製主要實現了資料的多機備份,以及對於讀操作的負載均衡和簡單的故障恢復。缺陷是故障恢復無法自動化;寫操作無法負載均衡;儲存能力受到單機的限制。

3.哨兵

在複製的基礎上,哨兵實現了自動化的故障恢復。缺陷是寫操作無法負載均衡;儲存能力受到單機的限制。

4.叢集

通過叢集,Redis解決了寫操作無法負載均衡,以及儲存能力受到單機限制的問題,實現了較為完善的高可用方案