redis主從同步機制
和Mysql主從複製的原因一樣,Redis雖然讀取寫入的速度都特別快,但是也會產生讀壓力特別大的情況。
為了分擔讀壓力,Redis支援主從複製,Redis的主從結構可以採用一主多從或者級聯結構,Redis主從複製可以根據是否是全量分為全量同步和增量同步。
下圖為級聯結構。
全量同步
Redis全量複製一般發生在Slave初始化階段,這時Slave需要將Master上的所有資料都複製一份。具體步驟如下:
- 從伺服器連線主伺服器,傳送SYNC命令;
- 主伺服器接收到SYNC命名後,開始執行BGSAVE命令生成RDB檔案並使用緩衝區記錄此後執行的所有寫命令;
- 主伺服器BGSAVE執行完後,向所有從伺服器傳送快照檔案,並在傳送期間繼續記錄被執行的寫命令;
- 主伺服器快照發送完畢後開始向從伺服器傳送緩衝區中的寫命令;
- 從伺服器完成對快照的載入,開始接收命令請求,並執行來自主伺服器緩衝區的寫命令;
完成上面幾個步驟後就完成了從伺服器資料初始化的所有操作,從伺服器此時可以接收來自使用者的讀請求。
增量同步
Redis增量複製是指Slave初始化後開始正常工作時主伺服器發生的寫操作同步到從伺服器的過程。
增量複製的過程主要是主伺服器每執行一個寫命令就會向從伺服器傳送相同的寫命令,從伺服器接收並執行收到的寫命令。
Redis主從同步策略
主從剛剛連線的時候,進行全量同步;全同步結束後,進行增量同步。當然,如果有需要,slave 在任何時候都可以發起全量同步。redis 策略是,無論如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步。
注意點
如果多個Slave斷線了,需要重啟的時候,因為只要Slave啟動,就會發送sync請求和主機全量同步,當多個同時出現的時候,可能會導致Master IO劇增宕機。
Redis主從複製的配置十分簡單,它可以使從伺服器是主伺服器的完全拷貝。需要清除Redis主從複製的幾點重要內容:
5)主從複製也不阻塞從伺服器端。當從伺服器進行初始同步時,它使用舊版本的資料來應對查詢請求,假設你在redis.conf配置檔案是這麼配置的。
否則的話,你可以配置當複製流關閉時讓從伺服器給客戶端返回一個錯誤。但是,當初始同步完成後,需要刪除舊的資料集和載入新的資料集,在
這個短暫的時間內,從伺服器會阻塞連線進來的請求。 6)主從複製可以用來增強擴充套件性,使用多個從伺服器來處理只讀的請求(比如,繁重的排序操作可以放到從伺服器去做),也可以簡單的用來做資料冗餘。 7)使用主從複製可以為主伺服器免除把資料寫入磁碟的消耗:在主伺服器的redis.conf檔案中配置“避免儲存”(註釋掉所有“儲存“命令),然後連線一個配
置為“進行儲存”的從伺服器即可。但是這個配置要確保主伺服器不會自動重啟(要獲得更多資訊請閱讀下一段)
|
主從複製的一些特點:
|
Redis大概主從同步是怎麼實現的?
|
主從同步中需要注意幾個問題
|
當主伺服器不進行持久化時複製的安全性
|
Redis主從複製是如何工作的
|
部分重新同步
|
無磁碟複製
|
配置
|
只讀從伺服器
|
限制有N個以上從伺服器才允許寫入
|
====== 通過redis實現伺服器崩潰等資料恢復 ======
由於redis儲存在記憶體中且提供一般程式語言常用的資料結構儲存型別,所以經常被用於做伺服器崩潰宕機的資料恢復處理。伺服器可以在某些指定過程中將需要儲存的資料以json物件等方式儲存到redis中,也就是我們常說的快照,當伺服器執行時讀取redis來判斷是否有待需要恢復資料繼續處理的業務。當一次業務處理結束後再刪除redis的資料即可。redis提供兩種將記憶體資料匯出到硬碟實現資料備份的方法:
1)RDB方式(預設)
RDB方式的持久化是通過快照(snapshotting)完成的,當符合一定條件時Redis會自動將記憶體中的所有資料進行快照並存儲在硬碟上。進行快照的條件可以由使用者在配置檔案中自定義,由兩個引數構成:時間和改動的鍵的個數。當在指定的時間內被更改的鍵的個數大於指定的數值時就會進行快照。RDB是redis預設採用的持久化方式,在配置檔案中已經預置了3個條件:
save 900 1 #900秒內有至少1個鍵被更改則進行快照
save 300 10 #300秒內有至少10個鍵被更改則進行快照
save 60 10000 #60秒內有至少10000個鍵被更改則進行快照
可以存在多個條件,條件之間是"或"的關係,只要滿足其中一個條件,就會進行快照。 如果想要禁用自動快照,只需要將所有的save引數刪除即可。
Redis預設會將快照檔案儲存在當前目錄(可CONFIG GET dir來檢視)的dump.rdb檔案中,可以通過配置dir和dbfilename兩個引數分別指定快照檔案的儲存路徑和檔名。
Redis實現快照的過程
- Redis使用fork函式複製一份當前程序(父程序)的副本(子程序);
- 父程序繼續接收並處理客戶端發來的命令,而子程序開始將記憶體中的資料寫入硬碟中的臨時檔案;
- 當子程序寫入完所有資料後會用該臨時檔案替換舊的RDB檔案,至此一次快照操作完成。
- 在執行fork的時候作業系統(類Unix作業系統)會使用寫時複製(copy-on-write)策略,即fork函式發生的一刻父子程序共享同一記憶體資料,當父程序要更改其中某片資料時(如執行一個寫命令 ),作業系統會將該片資料複製一份以保證子程序的資料不受影響,所以新的RDB檔案儲存的是執行fork一刻的記憶體資料。
Redis在進行快照的過程中不會修改RDB檔案,只有快照結束後才會將舊的檔案替換成新的,也就是說任何時候RDB檔案都是完整的。這使得我們可以通過定時備份RDB檔案來實 現Redis資料庫備份。RDB檔案是經過壓縮(可以配置rdbcompression引數以禁用壓縮節省CPU佔用)的二進位制格式,所以佔用的空間會小於記憶體中的資料大小,更加利於傳輸。
除了自動快照,還可以手動傳送SAVE或BGSAVE命令讓Redis執行快照,兩個命令的區別在於,前者是由主程序進行快照操作,會阻塞住其他請求,後者會通過fork子程序進行快照操作。 Redis啟動後會讀取RDB快照檔案,將資料從硬碟載入到記憶體。根據資料量大小與結構和伺服器效能不同,這個時間也不同。通常將一個記錄一千萬個字串型別鍵、大小為1GB的快照檔案載入到內 存中需要花費20~30秒鐘。 通過RDB方式實現持久化,一旦Redis異常退出,就會丟失最後一次快照以後更改的所有資料。這就需要開發者根據具體的應用場合,通過組合設定自動快照條件的方式來將可能發生的資料損失控制在能夠接受的範圍。如果資料很重要以至於無法承受任何損失,則可以考慮使用AOF方式進行持久化。
2)AOF方式
預設情況下Redis沒有開啟AOF(append only file)方式的持久化,可以在redis.conf中通過appendonly引數開啟:
appendonly yes
在啟動時Redis會逐個執行AOF檔案中的命令來將硬碟中的資料載入到記憶體中,載入的速度相較RDB會慢一些
開啟AOF持久化後每執行一條會更改Redis中的資料的命令,Redis就會將該命令寫入硬碟中的AOF檔案。AOF檔案的儲存位置和RDB檔案的位置相同,都是通過dir引數設定的,預設的檔名是appendonly.aof,可以通過appendfilename引數修改:
appendfilename appendonly.aof
配置redis自動重寫AOF檔案的條件
auto-aof-rewrite-percentage 100 # 當目前的AOF檔案大小超過上一次重寫時的AOF檔案大小的百分之多少時會再次進行重寫,如果之前沒有重寫過,則以啟動時的AOF檔案大小為依據
auto-aof-rewrite-min-size 64mb # 允許重寫的最小AOF檔案大小
配置寫入AOF檔案後,要求系統重新整理硬碟快取的機制
# appendfsync always # 每次執行寫入都會執行同步,最安全也最慢
appendfsync everysec # 每秒執行一次同步操作
# appendfsync no # 不主動進行同步操作,而是完全交由作業系統來做(即每30秒一次),最快也最不安全
Redis允許同時開啟AOF和RDB,既保證了資料安全又使得進行備份等操作十分容易。此時重新啟動Redis後Redis會使用AOF檔案來恢復資料,因為AOF方式的持久化可能丟失的資料更少