99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网

歡迎加入QQ討論群258996829
麥子學(xué)院 頭像
蘋果6袋
6
麥子學(xué)院

Redis學(xué)習(xí)之持久化策略詳解

發(fā)布時間:2017-03-24 15:48  回復(fù):0  查看:2161   最后回復(fù):2017-03-24 15:48  
Redis 的強勁性能很大程度上是由于其將所有數(shù)據(jù)都存儲在了內(nèi)存中,為了使 Redis數(shù)據(jù)庫 在重啟之后仍能保證數(shù)據(jù)不丟失,需要將數(shù)據(jù)從內(nèi)存中以某種形式同步到硬盤中,這一過程就是持久化。
  Redis 支持兩種方式的持久化,一種是 RDB 方式,一種是 AOF 方式。可以單獨使用其中一種或?qū)⒍呓Y(jié)合使用。
   1RDB方式
  RDB 方式的持久化是通過快照( snapshotting )完成的,當(dāng)符合一定條件時 Redis 會自動將內(nèi)存中的所有數(shù)據(jù)進(jìn)行快照并存儲在硬盤上。進(jìn)行快照的條件可以由用戶在配置文件中自定義,由兩個參數(shù)構(gòu)成:時間和改動的鍵的個數(shù)。當(dāng)在指定的時間內(nèi)被更改的鍵的個數(shù)大于指定的數(shù)值時就會進(jìn)行快照。 RDB Redis 默認(rèn)采用的持久化方式,在配置文件中已經(jīng)預(yù)置了 3 個條件:
  **save 900 1
  save 300 10
  save 60 10000**
  save 參數(shù)指定了快照條件,可以存在多個條件,條件之間是 的關(guān)系。如上所說, save900 1 的意思是在 15 分鐘( 900 秒鐘)內(nèi)有至少一個鍵被更改則進(jìn)行快照。如果想要禁用自動快照,只需要將所有的 save 參數(shù)刪除即可。
  Redis 默認(rèn)會將快照文件存儲在當(dāng)前目錄的 dump.rdb 文件中,可以通過配置 dir dbfilename 兩個參數(shù)分別指定快照文件的存儲路徑和文件名。
  理清Redis 實現(xiàn)快照的過程對我們了解快照文件的特性有很大的幫助??煺盏倪^程如下。
  (1 Redis 使用 fork 函數(shù)復(fù)制一份當(dāng)前進(jìn)程(父進(jìn)程)的副本(子進(jìn)程);
 ?。?/span>2 )父進(jìn)程繼續(xù)接收并處理客戶端發(fā)來的命令,而子進(jìn)程開始將內(nèi)存中的數(shù)據(jù)寫入硬盤中
  的臨時文件;
  (3 )當(dāng)子進(jìn)程寫入完所有數(shù)據(jù)后會用該臨時文件替換舊的 RDB 文件,至此一次快照操作完成。
  在執(zhí)行fork 的時候操作系統(tǒng)(類 Unix 操作系統(tǒng))會使用寫時復(fù)制( copy-on-write )策略,即 fork 函數(shù)發(fā)生的一刻父子進(jìn)程共享同一內(nèi)存數(shù)據(jù),當(dāng)父進(jìn)程要更改其中某片數(shù)據(jù)時(如執(zhí)行一個寫命令),操作系統(tǒng)會將該片數(shù)據(jù)復(fù)制一份以保證子進(jìn)程的數(shù)據(jù)不受影響,所以新的 RDB 文件存儲的是執(zhí)行 fork 一刻的內(nèi)存數(shù)據(jù)。
  通過上述過程可以發(fā)現(xiàn)Redis 在進(jìn)行快照的過程中不會修改 RDB 文件,只有快照結(jié)束后才會將舊的文件替換成新的,也就是說任何時候 RDB 文件都是完整的。這使得我們可以通過定時備份 RDB 文件來實現(xiàn) Redis 數(shù)據(jù)庫備份。 RDB 文件是經(jīng)過壓縮(可以配置 rdbcompression 參數(shù)以禁用壓縮節(jié)省 CPU 占用)的二進(jìn)制格式,所以占用的空間會小于內(nèi)存中的數(shù)據(jù)大小,更加利于傳輸。
  除了自動快照,還可以手動發(fā)送SAVE BGSAVE 命令讓 Redis 執(zhí)行快照,兩個命令的區(qū)別在于,前者是由主進(jìn)程進(jìn)行快照操作,會阻塞住其他請求,后者會通過 fork 子進(jìn)程進(jìn)行快照操作。
  Redis 啟動后會讀取 RDB 快照文件,將數(shù)據(jù)從硬盤載入到內(nèi)存。根據(jù)數(shù)據(jù)量大小與結(jié)構(gòu)和服務(wù)器性能不同,這個時間也不同。通常將一個記錄一千萬個字符串類型鍵、大小為 1GB 的快照文件載入到內(nèi)存中需要花費 20 30 秒鐘。
  通過RDB 方式實現(xiàn)持久化,一旦 Redis 異常退出,就會丟失最后一次快照以后更改的所有數(shù)據(jù)。這就需要開發(fā)者根據(jù)具體的應(yīng)用場合,通過組合設(shè)置自動快照條件的方式來將可能發(fā)生的數(shù)據(jù)損失控制在能夠接受的范圍。如果數(shù)據(jù)很重要以至于無法承受任何損失,則可以考慮使用 AOF 方式進(jìn)行持久化。
   2、AOF方式
  默認(rèn)情況下Redis 沒有開啟 AOF append only file )方式的持久化,可以通過 appendonly 參數(shù)開啟:
   appendonly yes
  開啟AOF 持久化后每執(zhí)行一條會更改 Redis 中的數(shù)據(jù)的命令, Redis 就會將該命令寫入硬盤中的 AOF 文件。 AOF 文件的保存位置和 RDB 文件的位置相同,都是通過 dir 參數(shù)設(shè)置的,默認(rèn)的文件名是 appendonly.aof ,可以通過 appendfilename 參數(shù)修改:
  appendfilename appendonly.aof
  下面講解AOF 持久化的具體實現(xiàn),假設(shè)在開啟 AOF 持久化的情況下執(zhí)行了如下 4 個命令:
  SET foo 1
  SET foo 2
  SET foo 3
  GET foo
  Redis 會將前 3 條命令寫入 AOF 文件中,此時 AOF 文件中的內(nèi)容如下:
 ?。?/span>2
  6
  SELECT
  1
  0
  *3
  3
  set
  3
  foo
  1
  1
 ?。?/span>3
  3
  set
  3
  foo
  1
  2
 ?。?/span>3
  3
  set
  3
  foo
  1
  3
  可見AOF 文件是純文本文件,其內(nèi)容正是 Redis 客戶端向 Redis 發(fā)送的原始通信協(xié)議的內(nèi)容( Redis 的通信協(xié)議會在 7.4 節(jié)中介紹,為了便于閱讀,這里將實際的命令部分以粗體顯示),從中可見 Redis 確實只記錄了前 3 條命令。然而這時有一個問題是前 2 條命令其實都是冗余的,因為這兩條的執(zhí)行結(jié)果會被第三條命令覆蓋。隨著執(zhí)行的命令越來越多, AOF 文件的大小也會越來越大,即使內(nèi)存中實際的數(shù)據(jù)可能并沒有多少。很自然地,我們希望 Redis 可以自動優(yōu)化 AOF 文件,就上例而言,就是將前兩條無用的記錄刪除,只保留第三條。實際上 Redis 也正是這樣做的,每當(dāng)達(dá)到一定條件時 Redis 就會自動重寫 AOF 文件,這個條件可以在配置文件中設(shè)置:
   auto-aof-rewrite-percentage 100  auto-aof-rewrite-min-size 64mb
  auto-aof-rewrite-percentage 參數(shù)的意義是當(dāng)目前的 AOF 文件大小超過上一次重寫時的 AOF 文件大小的百分之多少時會再次進(jìn)行重寫,如果之前沒有重寫過,則以啟動時的 AOF 文件大小為依據(jù)。 auto-aof-rewrite-min-size 參數(shù)限制了允許重寫的最小 AOF 文件大小,通常在 AOF 文件很小的情況下即使其中有很多冗余的命令我們也并不太關(guān)心。除了讓 Redis 自動執(zhí)行重寫外,我們還可以主動使用 BGREWRITEAOF 命令手動執(zhí)行 AOF 重寫。
  上例中的AOF 文件重寫后的內(nèi)容為:
 ?。?/span>2
  6
  SELECT
  1
  0
 ?。?/span>3
  3
  SET
  3
  foo
  1
  3
  可見冗余的命令已經(jīng)被刪除了。重寫的過程只和內(nèi)存中的數(shù)據(jù)有關(guān),和之前的AOF 文件無關(guān),這與 RDB 很相似,只不過二者的文件格式完全不同。
  在啟動時Redis 會逐個執(zhí)行 AOF 文件中的命令來將硬盤中的數(shù)據(jù)載入到內(nèi)存中,載入的速度相較 RDB 會慢一些。需要注意的是雖然每次執(zhí)行更改數(shù)據(jù)庫內(nèi)容的操作時, AOF 都會將命令記錄在 AOF 文件中,但是事實上,由于操作系統(tǒng)的緩存機制,數(shù)據(jù)并沒有真正地寫入硬盤,而是進(jìn)入了系統(tǒng)的硬盤緩存。在默認(rèn)情況下系統(tǒng)每 30 秒會執(zhí)行一次同步操作,以便將硬盤緩存中的內(nèi)容真正地
  寫入硬盤,在這30 秒的過程中如果系統(tǒng)異常退出則會導(dǎo)致硬盤緩存中的數(shù)據(jù)丟失。一般來講啟用 AOF 持久化的應(yīng)用都無法容忍這樣的損失,這就需要 Redis 在寫入 AOF 文件后主動要求系統(tǒng)將緩存內(nèi)容同步到硬盤中。在 Redis 中我們可以通過 appendfsync 參數(shù)設(shè)置同步的時機:
   # appendfsync always  appendfsync everysec  # appendfsync no
  默認(rèn)情況下Redis 采用 everysec  規(guī)則,即每秒執(zhí)行一次同步操作。 always 表示每次執(zhí)行寫入都會執(zhí)行同步,這是最安全也是最慢的方式。 no 表示不主動進(jìn)行同步操作,而是完全交由操作系統(tǒng)來做(即每 30 秒一次),這是最快但最不安全的方式。一般情況下使用默認(rèn)值 everysec 就足夠了,既兼顧了性能又保證了安全。
  Redis 允許同時開啟 AOF RDB ,既保證了數(shù)據(jù)安全又使得進(jìn)行備份等操作十分容易。此時重新啟動 Redis Redis 會使用 AOF 文件來恢復(fù)數(shù)據(jù),因為 AOF 方式的持久化可能丟失的數(shù)據(jù)更少。
來源:CSDN

您還未登錄,請先登錄

熱門帖子

最新帖子

?