1. 程式人生 > >Redis持久化:RDB和AOF配置和對比

Redis持久化:RDB和AOF配置和對比

1. 前言

  1. Redis的高效能是由於其將所有資料都儲存在了記憶體中,為了使Redis在重啟之後仍能保證資料不丟失,
  2. 需要將資料從記憶體中同步到硬碟中,這一過程就是持久化。
  3. Redis支援兩種方式的持久化,一種是RDB方式,一種是AOF方式。可以單獨使用其中一種或將二者結合使用。

2. RDB持久化

  1. 持久化機制:指定的時間間隔內將記憶體中的資料集以快照寫入磁
  1. RDB方式的持久化是通過快照(snapshotting)完成的,當符合一定條件時Redis會自動將記憶體中的資料進行快照並持久化到硬碟。
  1. 進行快照的條件可以由使用者在配置檔案中自定義,由兩個引數構成:時間和改動的鍵的個數
  2. 當在指定的時間內被更改的鍵的個數大於指定的數值時就會進行快照。
  3. RDBRedis預設採用的持久化方式,在配置檔案中已經預置了3個條件:
    1. save 9001#900秒內有至少1個鍵被更改則進行快照
    2. save 30010#300秒內有至少10個鍵被更改則進行快照
    3. save 6010000#60秒內有至少10000個鍵被更改則進行快照
    1. 可以存在多個條件,條件之間是“或”的關係,只要滿足其中一個條件,就會進行快照。
    2. 如果想要禁用自動快照,只需要將所有的save引數刪除即可。
    1. Redis預設會將快照檔案儲存在當前目錄(可CONFIG GET dir來檢視)的dump.rdb檔案中,
    2. 可以通過配置dirdbfilename兩個引數分別指定快照檔案的儲存路徑和檔名。
  • RDB持久化配置(修改redis.conf檔案)
  1. RDB持久化配置(修改redis.conf檔案)注:標紅為配置檔案修改部分
  2. deamonize 已程序的形式啟動程式改為:yes
  3. timeout 客戶端沒有操作就中斷服務0不中斷
  4. RDB快照的配置
  5. database 預設有多少個庫16個庫
  6. save 9001900秒有一次操作就快照一次
  7. rdbcompression對快照進行壓縮 yes
  8. dbfilename 這裡可以修改dump.rdb的名字
  9. dir ./預設生成當前目錄(目錄可以修改)
  1. 檔案修復:redis-check-dump(突然斷電什麼的造成檔案損壞)
  1. 通過shutdwon 不會丟失快照資料,直接
    kill -9直接殺掉異常關機不會實現備份。
  • RDB實現快照的過程
  1. i.Redis使用fork函式複製一份當前程序(父程序)的副本(子程序);
  2. ii.父程序繼續接收並處理客戶端發來的命令,而子程序開始將記憶體中的資料寫入硬碟中的臨時檔案;
  3. iii.當子程序寫入完所有資料後會用該臨時檔案替換舊的RDB檔案,至此一次快照操作完成。
  1. 在執行fork的時候作業系統(類Unix作業系統)會使用寫時複製(copy-on-write)策略
  2. fork函式發生的一刻父子程序共享同一記憶體資料,當父程序要更改其中某片資料時(如執行一個寫命令),
  3. 作業系統會將該片資料複製一份以保證子程序的資料不受影響,所以新的RDB檔案儲存的是執行fork一刻的記憶體資料。
  1. Redis在進行快照的過程中不會修改RDB檔案,只有快照結束後才會將舊的檔案替換成新的,也就是說任何時候RDB檔案都是完整的。
  2. 這使得我們可以通過定時備份RDB檔案來實Redis資料庫備份。
  3. RDB檔案是經過壓縮(可以配置rdbcompression引數以禁用壓縮節省CPU佔用)的二進位制格式,所以佔用的空間會小於記憶體中的資料大小,更加利於傳輸。
  1. 除了自動快照,還可以手動傳送SAVEBGSAVE命令讓Redis執行快照
    1. 兩個命令的區別在於,SAVE是由主程序進行快照操作,會阻塞住其他請求BGSAVEredis執行fork函式複製出一個子程序來進行快照操作
  2. Redis啟動後會讀取RDB快照檔案,將資料從硬碟載入到記憶體。
  3. 根據資料量大小與結構和伺服器效能不同,這個時間也不同。通常將一個記錄一千萬個字串型別鍵、大小為1GB的快照檔案載入到內存中需要花費2030秒鐘。
  4. 通過RDB方式實現持久化,一旦Redis異常退出,就會丟失最後一次快照以後更改的所有資料。
  5. 這就需要開發者根據具體的應用場合,通過組合設定自動快照條件的方式來將可能發生的資料損失控制在能夠接受的範圍。
  6. 如果資料很重要以至於無法承受任何損失,則可以考慮使用AOF方式進行持久化。
  • RDB持久化優劣
  1. 優勢:整個Redis資料庫將只包含一個檔案,這對於檔案備份而言是非常完美的
  2. 劣勢:rdb是以每隔一段時間進行一次快照進行的資料持久,如果一旦在這一時間段出現伺服器故障,將會災難性的。
    1. 解決:這就需要開發者根據具體的應用場合,通過組合設定自動快照條件的方式來將可能發生的資料損失控制在能夠接受的範圍。
    2. 如果資料很重要以至於無法承受任何損失,則可以考慮使用AOF方式進行持久化。

3. AOF持久化

  1. 持久化機制:以日誌形式記錄伺服器每一個操作,在Redis伺服器啟動之初會讀取該檔案來重新構建資料庫,以保證啟動後資料庫中的資料是完整的。
  • AOF持久化配置(修改redis.conf檔案)
  1. 預設情況下Redis沒有開啟AOF(append only file)方式的持久化,可以在redis.conf中通過appendonly引數開啟:
    1. appendonly yes
  2. 在啟動時Redis會逐個執行AOF檔案中的命令來將硬碟中的資料載入到記憶體中,載入的速度相較RDB會慢一些
  3. 開啟AOF持久化後每執行一條會更改Redis中的資料的命令,Redis就會將該命令寫入硬碟中的AOF檔案。
  4. AOF檔案的儲存位置和RDB檔案的位置相同,都是通過dir引數設定的,預設的檔名是appendonly.aof,可以通過appendfilename引數修改:
    1. appendfilename appendonly.aof
  5. 配置redis自動重寫AOF檔案的條件
    1. auto-aof-rewrite-percentage 100#當目前的AOF檔案大小超過上一次重寫時的AOF檔案大小的百分之多少時會再次進行重寫,如果之前沒有重寫過,則以啟動時的AOF檔案大小為依據
    2. auto-aof-rewrite-min-size 64mb#允許重寫的最小AOF檔案大小
  6. 手動重寫AOF檔案
    1. 手動執行bgrewriteaof進行重寫
    1. 重寫的過程只和記憶體中的資料有關,和之前的aof檔案無關。
    2. 所謂的“重寫”其實是一個有歧義的詞語,實際上, AOF 重寫並不需要對原有的 AOF 檔案進行任何寫入和讀取,
    3. 它針對的是資料庫中鍵的當前值。

  7. 配置寫入AOF檔案後,要求系統重新整理硬碟快取的機制
    1. # appendfsync always #每次執行寫入都會執行同步,最安全也最慢
    2. appendfsync everysec #每秒執行一次同步操作
    3. # appendfsync no #不主動進行同步操作,而是完全交由作業系統來做(即每30秒一次),最快也最不安全
  8. 檔案修復
    1. redis-check-aof
  9. Redis允許同時開啟AOFRDB,既保證了資料安全又使得進行備份等操作十分容易。此時重新啟動RedisRedis會使用AOF檔案來恢復資料,因為AOF方式的持久化可能丟失的資料更少
  • AOF持久化優劣
  1. AOF持久化方式優劣勢:
  2. 優勢:Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步
  3. 1)修改同步:每修改一次同步一次,對於效能的消耗非常大。
  4. 2)每秒同步:每秒鐘進行的操作進行一次同步
  5. 3)不同步
  6. 劣勢:對於相同數量的資料集而言,AOF檔案通常要大於RDB檔案,並且根據同步策略的不同,AOF在執行效率上往往會慢於RDB
4.動態切換持久化方案
  1. 動態切換redis持久方式,從 RDB 切換到 AOF(支援Redis2.2及以上)
  2. CONFIG SET appendonly yes
  3. CONFIG SET save ""(可選)
  1. 注意:redis啟動時,如果rdb持久化和aof持久化都打開了,那麼程式會優先使用aof方式來恢復資料集,
  2. 因為aof方式所儲存的資料通常是最完整的。如果aof檔案丟失了,則啟動之後資料庫內容為空。
  1. 注意:如果想把正在執行的redis資料庫,從RDB切換到AOF,建議先使用動態切換方式,再修改配置檔案,重啟資料庫。
  2. (不能直接修改配置檔案,重啟資料庫,否則資料庫中資料就為空了。)
5.持久化後,伺服器宕機的恢復資料(主從複製)
  1. 通過持久化功能,Redis保證了即使在伺服器重啟的情況下也不會損失(或少量損失)資料。
  2. 但是由於資料是儲存在一臺伺服器上的,如果這臺伺服器的硬碟出現故障,也會導致資料丟失。
  3. 為了避免單點故障,我們希望將資料庫複製多個副本以部署在不同的伺服器上,即使有一臺伺服器出現故障其他伺服器依然可以繼續提供服務。
  4. 這就要求當一臺伺服器上的資料庫更新後,可以自動將更新的資料同步到其他伺服器上,Redis提供了複製(replication)功能可以自動實現同步的過程
  • 配置方法
  1. 通過配置檔案從資料庫的配置檔案中加入slaveof master-ip master-port主資料庫無需配置
  2. 通過命令列引數啟動redis-server的時候,使用命令列引數--slaveof master-ip master port
    1. redis-server --port 6380--slaveof 127.0.0.16379
  3. 通過命令SLAVEOF master-ip master-port
    1. redis>SLAVEOF 127.0.0.16379
  4. SLAVEOF NO ONE可以是當前資料庫停止接收其他資料庫的同步,轉成主資料庫
  • 優點及應用場景
  1. 1.讀寫分離通過複製可以實現讀寫分離以提高伺服器的負載能力。
  2. 在常見的場景中,讀的頻率大於寫,當單機的Redis無法應付大量的讀請求時(尤其是較耗資源的請求,比如SORT命令等)可以通過複製功能建立多個從資料庫,
  3. 主資料庫只進行寫操作,而從資料庫負責讀操作
  4. 2.從資料庫持久化持久化通常相對比較耗時,為了提高效能,可以通過複製功能建立一個(或若干個)從資料庫,並在從資料庫中啟用持久化,
  5. 同時在主資料庫禁用持久化。當從資料庫崩潰時重啟後主資料庫會自動將資料同步過來,所以無需擔心資料丟失。
  6. 而當主資料庫崩潰時,需要在從資料庫中使用SLAVEOF NO ONE命令將從資料庫提升成主資料庫繼續服務,
  7. 並在原來的主資料庫啟動後使用SLAVEOF命令將其設定成新的主資料庫的從資料庫,即可將資料同步回來。
6.其他相關命令
  1. redisconfig命令
  2. 使用config set可以動態設定引數資訊,伺服器重啟之後就失效了。
    1. config set appendonly yes
    2. config set save "90 1 30 10 60 100"
  3. 使用config get可以檢視所有可以使用config set命令設定的引數
    1. config get *
  4. 使用config rewrite命令對啟動Redis伺服器時所指定的 redis.conf 檔案進行改寫(Redis2.8及以上版本才可以使用),
  5. 主要是把使用config set動態指定的命令儲存到配置檔案中。
    1. config rewrite
  6. 注意:config rewrite命令對 redis.conf 檔案的重寫是原子性的,並且是一致的:
    1. 如果重寫出錯或重寫期間伺服器崩潰,那麼重寫失敗,原有 redis.conf 檔案不會被修改。
    2. 如果重寫成功,那麼 redis.conf 檔案為重寫後的新檔案。
  1. ps -ef | grep redis 檢視程序服務是否啟動
  2. kill -93004殺掉程序
  3. bgrewriteaof 手動重寫aof
  4. requirepass password 配置redis訪問密碼
  5. auth password 客戶端登陸輸入訪問密碼