上篇文章已經講了redis的經常使用功能,今天來說講redis如下知識點,若有不當請多指教!html
Redis持久化
主從複製
Sentinel機制
Redis Cluster
redis是基於內存
的,若是不想辦法將數據保存在硬盤上,一旦redis重啓(退出/故障),內存的數據將會所有丟失。redis
Redis提供了兩種持久化方法:數據庫
RDB
(基於快照),將某一時刻的全部數據保存到一個RDB文件中。AOF
(append-only-file),當Redis服務器執行寫命令的時候,將執行的寫命令保存到AOF文件中。服務器
RDB
保存某個時間點的全量數據快照網絡
手動觸發 併發
SAVE
:阻塞Redis的服務器進程,知道RDB文件被建立完畢 BGSAVE
:Fork出一個子進程來建立RDB文件,不阻塞服務器進程,使用lastsave
指令能夠查看最近的備份時間app
根據redis.conf配置裏的save m n定時觸發(用的是BGSAVE)
主從複製時,主節點自動觸發
執行Debug Relaod
執行Shutdown且沒有開啓AOF持久化異步
注意:Redis服務器在啓動的時候,若是發現有RDB文件,就會自動載入RDB文件(不須要人工干預)工具
優勢:
RDB是一個緊湊壓縮的二進制文件,表明Redis在某個時間點上的數據快照,適合備份,全量複製等場景。
且加載RDB恢復數據遠遠快於AOF的方式。spa
缺點:
沒辦法作到實時持久化/秒級持久化,由於bgsave每次運行都要執行fork操做建立子進程,屬於重量級操做,頻繁執行成本太高。
//在n秒內修改m條數據時建立RDB文件 save 900 1 save 300 10 save 60 10000 stop-writes-on-bgsave-error yes //bgsave出錯時中止寫入 rdbcompression yes //壓縮RDB文件 rdbchecksum yes //校驗文件是否損壞
AOF
與RDB不同的是,AOF
記錄的是命令,而不是數據。
如何開啓AOF?
只需在配置文件中將appendonly
設置爲yes便可。
一、全部的寫入命令追加到aof_buf
緩衝區中。
二、AOF會根據對應的策略向磁盤作同步操做。刷盤策略由appendfsync
參數決定。
三、按期對AOF文件進行重寫。重寫策略由auto-aof-rewrite-percentage
,auto-aof-rewrite-min-size
兩個參數決定。
appendfsync參數有以下取值:
appendfsync always # 每次有數據修改發生時都會寫入AOF文件。 appendfsync everysec # 每秒鐘同步一次,該策略爲AOF的默認策略。 appendfsync no # 從不一樣步。高效可是數據不會被持久化。
爲何要重寫?
重寫後能夠加快節點啓動時的加載時間
重寫後的文件爲何能夠變小?
進程內超時的數據不用再寫入到AOF文件中
多條寫命令能夠合併爲一個
一、手動觸發
直接調用bgrewriteaof
命令
二、自動觸發
先來看看有關參數:auto-aof-rewrite-min-size
:執行AOF重寫時,文件的最小體積,默認值爲64MB。 auto-aof-rewrite-percentage
:執行AOF重寫時,當前AOF大小(即aof_current_size)和上一次重寫時AOF大小(aof_base_size)的比值。
只有當auto-aof-rewrite-min-size和auto-aof-rewrite-percentage兩個參數同時知足時,纔會自動觸發AOF重寫。
Redis將AOF重寫程序放到子進程
裏執行(BGREWRITEAOF
命令),像BGSAVE
命令同樣fork出一個子進程來完成重寫AOF的操做,從而不會影響到主進程。
AOF後臺重寫是不會阻塞主進程接收請求的,新的寫命令請求可能會致使當前數據庫和重寫後的AOF文件的數據不一致!
爲了解決數據不一致的問題,Redis服務器設置了一個AOF重寫緩衝區
,當子進程完成重寫後會發送信號讓父進程將AOF重寫緩衝區的數據寫到新的AOF文件。
RDB和AOF並不互斥,它倆能夠同時使用。
RDB的優勢:載入時恢復數據快、文件體積小。
RDB的缺點:會必定程度上丟失數據(由於系統一旦在定時持久化以前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。)
AOF的優勢:丟失數據少(默認配置只丟失1秒的數據)。
AOF的缺點:恢復數據相對較慢,文件體積大
若是Redis服務器同時開啓了RDB和AOF持久化,服務器會優先使用AOF文件來還原數據
(由於AOF更新頻率比RDB更新頻率要高,還原的數據更完善)
單機即在一臺機器上部署一個redis節點,主要會存在如下問題:
一、若是發生機器故障,例如磁盤損壞,主板損壞等,未能在短期內修復好,客戶端將沒法鏈接redis
二、Redis的內存是有限的,可能放不下那麼多的數據
三、單臺Redis支持的併發量也是有限的
如圖上面是master節點
,下面是slave
節點,即主節點和從節點。從節點也是能夠對外提供服務的,主節點是有數據的,從節點能夠經過複製操做將主節點的數據同步過來,而且隨着主節點數據不斷寫入,從節點數據也會作同步的更新。
總體起到的就是數據備份的效果
除了一主一從模型以外,redis還提供了一主多從的模型,也就是一個master能夠有多個slave,也就至關於有了多份的數據副本。
除了做爲數據備份,主從模型還能作另一個功能,就是讀寫分離。
讓master節點負責提供寫服務,slave節點提供讀服務,而將數據讀取的壓力進行分流和負載,分攤給所
有的從節點。
slaveof 198.162.88.66 6379
執行該命令使當前redis節點成爲指定redis節點的從節點,此複製命令是異步
進行的,redis會自動進行後續數據複製的操做
若是想取消從節點能夠執行 slave of on one
命令
二、修改配置
# 配置主節點的IP和端口號 slaveof ip port # 從節點只作讀的操做,保證主從數據的一致性 slave-read-only yes
redis每次啓動的時候都會有一個隨機的ID,做爲一個標識,這個ID就是runid,固然重啓以後值就改變了。
假如端口爲6380的redis去複製6379,知道runid
後,在6380上作一個標識,若是runid
改變了,說明主可能重啓了或者發生了其它變化,這時候就能夠作一個全量複製把數據同步過來。或者第一次啓動時根本不知道6379的runid
,也會進行全量複製
偏移量:數據寫入量的字節
好比主執行set hello world,就會有一個偏移量,而後從同步數據,也會記錄一個偏移量
當兩個偏移量達到一致時候,實際上數據就是徹底同步的狀態。
全量複製主節點會將RDB文件也就是當前狀態去同步給slave,在此期間主節點新寫入的命令會單獨記錄起來,而後當RDB文件加載完畢以後,會經過偏移量對比將這個期間產生的寫入值同步給slave,這樣就能達到數據徹底同步的效果
全量複製過程
psync
,是作同步的命令,它能夠完成全量複製和部分複製的功能,當啓動slave節點時,它會發送psync
命令給主節點,須要傳遞兩個參數,runid
和offset
(偏移量),也就是從節點向主節點傳遞主節點的runid以及本身的偏移量,對於第一次複製而言,就直接傳遞?和 -1,固然這個參數是由slave內部傳的。bgsave
生成RDB文件,而且在此期間新產生的寫入命令會被記錄到repl_back_buffer
(複製緩衝區)執行全量複製除了開銷大以外,還會有個問題:
假如master和slave網絡發生了抖動,那一段時間內這些數據就會丟失,對於slave來講這段時間master更新的數據是不知道的。最簡單的方式就是再作一次全量複製,從而獲取到最新的數據,在redis2.8以前是這麼作的。
redis2.8以後提供部分複製,若是發生相似網絡抖動,能夠有這樣一種機制將這種損失下降到最低,如何實現的?
部分複製過程
經過部分複製有效的下降了全量複製的開銷。
Sentinel
(哨兵)是用於監控redis集羣中master狀態的工具,是Redis 的高可用性解決方案,sentinel哨兵模式已經被集成在redis2.4以後的版本中。
Sentinel系統能夠監視一個或者多個redis master服務,以及這些master服務的全部從服務;當某個master服務下線時,自動將該master下的某個從服務升級爲新的master服務,替代已下線的master服務繼續處理請求,等掛掉的主服務器重連上來,會將它變成從服務器。
Sentinel在內部有3個定時任務
1)每隔10秒——每一個sentinel會對master和slave執行info命令,這個任務主要用來發現slave節點和確認主從關係。
2)每隔2秒——每一個sentinel經過master節點的channel交換信息(pub/sub)。master節點上有一個名爲__sentinel__:hello
的發佈訂閱的頻道。sentinel節點經過__sentinel__:hello頻道進行信息交換(對節點的"見解"和自身的信息),達成共識。
3)每隔1秒——每一個sentinel對其餘sentinel和redis節點執行ping操做(相互監控),這個實際上是一個心跳檢測,是失敗斷定的依據。
判斷主服務器是否下線有兩種狀況:
主觀下線
Sentinel會以每秒一次的頻率向與它建立命令鏈接的實例(包括主從服務器和其餘的Sentinel)發送PING命令,經過PING命令返回的信息判斷實例是否在線
若是一個主服務器在down-after-milliseconds毫秒內連續向Sentinel發送無效回覆,那麼當前Sentinel就會主觀認爲該主服務器已經下線了。
客觀下線
當Sentinel將一個主服務器判斷爲主觀下線之後,爲了確認該主服務器是否真的下線,它會向一樣監視該主服務器的Sentinel詢問,看它們是否也認爲該主服務器是否下線。
若是足夠多的Sentinel認爲該主服務器是下線的,那麼就斷定該主服務爲客觀下線,並對主服務器執行故障轉移操做。
在redis-sentinel的conf文件裏有這麼兩個配置:
1)sentinel monitor <masterName> <ip> <port> <quorum>
四個參數含義:masterName
這個是對某個master+slave組合的一個區分標識。ip
和 port
就是master節點的 ip 和 端口號。quorum
這個參數是進行客觀下線的一個依據,意思是至少有 quorum 個sentinel主觀的認爲這個master有故障,纔會對這個master進行下線以及故障轉移。由於有的時候,某個sentinel節點可能由於自身網絡緣由,致使沒法鏈接master,而此時master並無出現故障,因此這就須要多個sentinel都一致認爲該master有問題,才能夠進行下一步操做,這就保證了公平性和高可用。
2)sentinel down-after-milliseconds <masterName> <timeout>
這個配置其實就是進行主觀下線的一個依據,表示:若是這臺sentinel超過timeout這個時間都沒法連通master包括slave的話,就會主觀認爲該master已經下線。
當一個主服務器被認爲客觀下線之後,此時須要一個Sentinel服務器對該服務器進行處理,所以監視這個下線的主服務器的各個Sentinel會進行協商,選舉出一個領頭的Sentinel,領頭的Sentinel會對下線的主服務器執行故障轉移操做。
選舉領頭Sentinel的規則也比較多,總的來講就是 先到先得(哪一個快,就選哪一個)
注意:挑選某一個從服務器做爲主服務器也是有策略的,大概以下:
(1)跟master斷開鏈接的時長
(2)slave優先級
(3)複製offset大小
(4)run id
Redis3.0版本以前,能夠經過Redis Sentinel(哨兵)來實現高可用,從3.0版本以後,官方推出了Redis Cluster
,它的主要用途是實現數據分片,而且實現高可用。
在Redis Sentinel模式中,每一個節點須要保存全量數據,冗餘比較多,而在Redis Cluster模式中,每一個分片只須要保存一部分的數據,
Redis Cluster每一個節點都保存各自的數據和整個集羣的狀態。每一個節點都和其餘全部節點鏈接,並且這些鏈接保持活躍,這樣就保證了咱們只須要鏈接集羣中的任意一個節點,就能夠獲取到其餘節點的數據。
Redis Cluster的具體實現細節是採用了Hash槽
的概念,集羣會預先分配16384
個槽,並將這些槽分配給具體的服務節點,經過對Key進行CRC16(key)%16384
運算獲得對應的槽是哪個,從而將讀寫操做轉發到該槽所對應的服務節點。當有新的節點加入或者移除的時候,再來遷移這些槽以及其對應的數據。在這種設計之下,咱們就能夠很方便的進行動態擴容或縮容。
Redis Cluster爲了保證數據的高可用性,加入了主從模式,一個主節點對應一個或多個從節點,主節點提供數據存取,從節點則是從主節點拉取數據備份,當這個主節點掛掉後,就會有這個從節點選取一個來充當主節點,從而保證集羣不會掛掉。
有關redis集羣的安裝配置在這裏就很少說了,在這裏對先對redis cluster有個瞭解,往後再來補充。