至此,咱們瞭解並動手實踐了redis的安裝,redis單點,redis主從,redis 哨兵 sentinel,redis 集羣cluster。
咱們來梳理一下redis主從,redis哨兵,redis機器的區別和關係。html
redis主從:是備份關係, 咱們操做主庫,數據也會同步到從庫。 若是主庫機器壞了,從庫能夠上。就比如你 D盤的片丟了,可是你移動硬盤裏邊備份有。
redis哨兵:哨兵保證的是HA,保證特殊狀況故障自動切換,哨兵盯着你的「redis主從集羣」,若是主庫死了,它會告訴你新的老大是誰。
redis集羣:集羣保證的是高併發,由於多了一些兄弟幫忙一塊兒扛。同時集羣會致使數據的分散,整個redis集羣會分紅一堆數據槽,即不一樣的key會放到不不一樣的槽中。node
主從保證了數據備份,哨兵保證了HA 即故障時切換,集羣保證了高併發性。redis
一切動手作了纔會熟悉。。算法
談到Redis服務器的高可用,如何保證備份的機器是原始服務器的完整備份呢?這時候就須要哨兵和複製。 數據庫
Redis正是利用這兩個功能來保證Redis的高可用。緩存
哨兵是Redis集羣架構中很是重要的一個組件,哨兵的出現主要是解決了主從複製出現故障時須要人爲干預的問題。 服務器
1.Redis哨兵主要功能 架構
(1)集羣監控:負責監控Redis master和slave進程是否正常工做 併發
(2)消息通知:若是某個Redis實例有故障,那麼哨兵負責發送消息做爲報警通知給管理員 app
(3)故障轉移:若是master node掛掉了,會自動轉移到slave node上
(4)配置中心:若是故障轉移發生了,通知client客戶端新的master地址
2.Redis哨兵的高可用
原理:當主節點出現故障時,由Redis Sentinel自動完成故障發現和轉移,並通知應用方,實現高可用性。
這個就是哨兵用來判斷節點是否正常的重要依據,涉及兩個新的概念:主觀下線和客觀下線。
1. 主觀下線:一個哨兵節點斷定主節點down掉是主觀下線。
2.客觀下線:只有半數哨兵節點都主觀斷定主節點down掉,此時多個哨兵節點交換主觀斷定結果,纔會斷定主節點客觀下線。
3.原理:基本上哪一個哨兵節點最早判斷出這個主節點客觀下線,就會在各個哨兵節點中發起投票機制Raft算法(選舉算法),最終被投爲領導者的哨兵節點完成主從自動化切換的過程。
Redis爲了解決單點數據庫問題,會把數據複製多個副本部署到其餘節點上,經過複製,實現Redis的高可用性,實現對數據的冗餘備份,保證數據和服務的高度可靠性。
1.數據複製原理(執行步驟)
①從數據庫向主數據庫發送sync(數據同步)命令。
②主數據庫接收同步命令後,會保存快照,建立一個RDB文件。
③當主數據庫執行完保持快照後,會向從數據庫發送RDB文件,而從數據庫會接收並載入該文件。
④主數據庫將緩衝區的全部寫命令發給從服務器執行。
⑤以上處理完以後,以後主數據庫每執行一個寫命令,都會將被執行的寫命令發送給從數據庫。
注意:在Redis2.8以後,主從斷開重連後會根據斷開以前最新的命令偏移量進行增量複製。
1.主從模式:讀寫分離,備份,一個Master能夠有多個Slaves。
2.哨兵sentinel:監控,自動轉移,哨兵發現主服務器掛了後,就會從slave中從新選舉一個主服務器。
3.集羣:爲了解決單機Redis容量有限的問題,將數據按必定的規則分配到多臺機器,內存/QPS不受限於單機,可受益於分佈式集羣高擴展性。
哨兵做用於高可用,集羣提升併發量,具體Redis集羣方案詳情,能夠參考:高併發架構系列:詳解Redis的存儲類型、集羣架構、以及應用場景
2、持久化 那麼這麼多,這麼重要的數據都存儲在內存中,若是忽然斷電,豈不是很糟糕,因而就有了數據的持久化機制,這個其實就是把內存中的數據存儲到硬盤中,方便數據的持續存在,也能夠減小斷電形成的損失。 那麼咱們怎麼持久化數據呢?多長時間進行一次持久化呢?redis 支持兩種持久化方式,一種是 Snapshotting(快照)也是默認方式,另外一種是 Append-only file(縮寫 aof)的方式。下面分別介紹: 一)、Snapshotting 快照是默認的持久化方式。這種方式是就是將內存中數據以快照的方式寫入到二進制文件中,默認的文件名爲dump.rdb。能夠經過配置設置自動作快照持久化的方式。咱們能夠配置 redis在 n 秒內若是超過 m 個 key 被修改就自動作快照,下面是默認的快照保存配置: save 900 1 #900 秒內若是超過 1 個 key 被修改,則發起快照保存 save 300 10 #300 秒內容如超過 10 個 key 被修改,則發起快照保存 save 60 10000下面介紹詳細的快照保存過程: 1.redis 調用 fork,如今有了子進程和父進程。 2. 父進程繼續處理 client 請求,子進程負責將內存內容寫入到臨時文件。因爲 os 的實時複製機制( copy on write)父子進程會共享相同的物理頁面,當父進程處理寫請求時 os 會爲父進程要修改的頁面建立副本,而不是寫共享的頁面。因此子進程地址空間內的數據是 fork時刻整個數據庫的一個快照。 3.當子進程將快照寫入臨時文件完畢後,用臨時文件替換原來的快照文件,而後子進程退出。client 也可使用 save 或者 bgsave 命令通知 redis 作一次快照持久化。 save 操做是在主線程中保存快照的,因爲 redis 是用一個主線程來處理全部 client 的請求,這種方式會阻塞全部client 請求。因此不推薦使用。另外一點須要注意的是,每次快照持久化都是將內存數據完整寫入到磁盤一次,並非增量的只同步變動數據。若是數據量大的話,並且寫操做比較多,必然會引發大量的磁盤 io 操做,可能會嚴重影響性能。 二)、AOF方式 因爲快照方式是在必定間隔時間作一次的,因此若是 redis 意外 down 掉的話,就會丟失最後一次快照後的全部修改。若是應用要求不能丟失任何修改的話,能夠採用 aof 持久化方式。下面介紹 Append-only file:aof 比快照方式有更好的持久化性,是因爲在使用 aof 持久化方式時,redis 會將每個收到的寫命令都經過 write 函數追加到文件中(默認是 appendonly.aof)。當 redis 重啓時會經過從新執行文件中保存的寫命令來在內存中重建整個數據庫的內容。固然因爲 os 會在內核中緩存 write 作的修改,因此可能不是當即寫到磁盤上。這樣 aof 方式的持久化也仍是有可能會丟失部分修改。不過咱們能夠經過配置文件告訴 redis 咱們想要經過 fsync 函數強制 os 寫入到磁盤的時機。有三種方式以下(默認是:每秒 fsync 一次) appendonly yes //啓用 aof 持久化方式 # appendfsync always //收到寫命令就當即寫入磁盤,最慢,可是保證徹底的持久化 appendfsync everysec //每秒鐘寫入磁盤一次,在性能和持久化方面作了很好的折中 # appendfsync no //徹底依賴 os,性能最好,持久化沒保證 aof 的方式也同時帶來了另外一個問題。持久化文件會變的愈來愈大。例如咱們調用 incr test命令 100 次,文件中必須保存所有的 100 條命令,其實有 99 條都是多餘的。由於要恢復數據庫的狀態其實文件中保存一條 set test 100 就夠了。爲了壓縮 aof 的持久化文件。 redis 提供了 bgrewriteaof 命令。收到此命令 redis 將使用與快照相似的方式將內存中的數據以命令的方式保存到臨時文件中,最後替換原來的文件。