亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

學習Redis持久化

發布時間:2020-03-03 16:15:41 來源:網絡 閱讀:1257 作者:hbxztc 欄目:關系型數據庫

        Redis支持RDB和AOF兩種持久化機制,持久化功能有效地避免因進程退出造成的數據丟失問題,當下次重啟時利用之前持久化的文件即可實現數據恢復。理解掌握持久化機制對于Redis運維非常重要。

    首先介紹RDB、AOF的配置和運行流程,以及控制持久化的相關命令,如bgsave和bgrewriteaof。

RDB

RDB持久化是把當前進程數據生成快照保存到硬盤的過程,觸發RDB持久化過程分為手動觸發和自動觸發。

觸發機制

手動觸發分別對應save和bgsave命令:

save命令:阻塞當前Redis服務器,直到RDB過程完成為止,對于內存比較大的實例會造成長時間阻塞,線上環境不建議使用。運行save命令對應的Redis日志如下:

1283:M 04 Apr 21:39:03.035 * DB saved on disk

bgsave命令:Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成后自動結束。阻塞只發生在fork階段,一般時間很短。運行bgsave命令對應的Redis日志如下:

1283:M 04 Apr 21:40:33.849 * Background saving started by pid 1429
1429:C 04 Apr 21:40:33.874 * DB saved on disk
1429:C 04 Apr 21:40:33.875 * RDB: 6 MB of memory used by copy-on-write
1283:M 04 Apr 21:40:33.929 * Background saving terminated with success

顯然bgsave命令是針對save阻塞問題做的優化。因此Redis內部所有的涉及RDB的操作都采用bgsave的方式,而save命令已經廢棄。

除了執行命令手動觸發之外,Redis內部還存在自動觸發RDB的持久化機制,例如以下場景:

1)使用save相關配置,如"save m n"。表示m秒內數據集存在n次修改時,自動觸發bgsave。

2)如果從節點執行全量復制操作,主節點自動執行bgsave生成RDB文件并發送給從節點。

3)執行debug reload命令重新加載Redis時,也會自動觸發save操作。

4)默認情況下執行shutdown命令時,如果沒有開啟AOF持久化功能則自動執行bgsave。

                注:如果想關閉自動RDB持久化,在配置文件刪除"save m n"的配置

流程說明

bgsave是主流的觸發RDB持久化方式,下面根據下圖了解它的運作流程。

學習Redis持久化

1)執行bgsave命令,Redis父進程判斷當前是否存在正在執行的子進程,如RDB/AOF子進程,如果存在bgsave命令直接返回。

2)父進程執行fork操作創建子進程,fork操作過程中父進程會阻塞,通過info stats命令查看latest_fork_usec選項,可以獲取最近一個ork操作的耗時,單位為微秒。

3)父進程fork完成后,bgsave命令返回"Background saving started"信息并不再阻塞父進程,可以繼續響應其他命令。

4)子進程創建RDB文件,根據父進程內存生成臨時快照文件,完成對原有文件執行原子替換。執行lastsave命令可以獲取最后一次生成RDB的時間,對應info統計的rdb_last_save_time選項。

5)進程發送信號給父進程表示完成,父進程更新統計信息,具體見info Persistence下的rdb_*相關選項。

RDB文件的處理

保存:RDB文件保存在dir配置指定的目錄下,文件名通過dbfilename配置指定。可以通過執行config set dir {newDir}和config set dbfilename {newFileName}運行期動態執行,當下次運行時RDB會保存到新目錄。

當遇到壞盤或磁盤寫滿等待情況時,可以通過config set dir {newDir}在線修改文件路徑到可用的磁盤路徑,之后執行bgsave進行bgsave進程磁盤切換,同樣適用于AOF持久化文件。

壓縮:Redis默認采用LZF算法對生成的RDB文件做壓縮處理,壓縮后的文件遠遠小于內存大小,默認開啟,可以通過config set rdbcompression {yes|no}動態修改。

雖然壓縮RDB會消耗CPU,但可大幅降低文件的體積,方便保存到硬盤或通過網絡發送給從節點,因此線上建議開啟。

校驗:如果Redis加載損壞的RDB文件時拒絕啟動,并打印如下日志:

2740:M 04 Apr 22:06:42.835 # Short read or OOM loading DB. Unrecoverable error, aborting now.
2740:M 04 Apr 22:06:42.835 # Internal error in RDB reading function at rdb.c:1666 -> Unexpected EOF reading RDB file

可以使用Redis提供的redis-check-rdb工具檢測RDB文件并獲取對應用的錯誤報告。

[redis@rhel7 ~]$ redis-check-rdb dump.rdb 
[offset 0] Checking RDB file dump.rdb
[offset 27] AUX FIELD redis-ver = '4.0.13'
[offset 41] AUX FIELD redis-bits = '64'
[offset 53] AUX FIELD ctime = '1554386780'
[offset 68] AUX FIELD used-mem = '570072'
[offset 84] AUX FIELD aof-preamble = '0'
[offset 86] Selecting DB ID 0
--- RDB ERROR DETECTED ---
[offset 109] Invalid object type: 209
[additional info] While doing: read-type
[info] 2 keys read
[info] 0 expires
[info] 0 already expired

RDB的優缺點

優點:RDB是一個緊湊壓縮的二進程文件,代表Redis在某個時間點上的數據快照。非常適用于備份,全量復制等場景。比如第6小時執行bgsave備份,并把RDB文件拷貝到遠程機器或者文件系統中(如hdfs),用于災難恢復。Redis加載RDB恢復數據遠遠快于AOF的方式。

缺點:RDB方式數據沒辦法做到實時持久化/秒級持久化。因為bgsave每次運行都要執行fork操作創建子進程,屬于重量級操作,頻繁執行成本過高。RDB文件使用特定二進程格式保存,Redis版本演進過程中有多個格式的RDB版本,存在老版本Redis服務無法兼容新版RDB格式的問題。

針對RDB不短途實時持久化的問題,Redis提供了AOF持久化方式來解決。

AOF

AOF(append only file)持久化:以獨立日志的方式記錄每次寫命令,重啟時再重新執行AOF文件中的命令達到恢復數據的目的。AOF的主要作用是解決了數據持久化的實時性,目前已經是Redis持久化的主流方式。理解掌握好AOF持久化機制對我們兼顧數據安全性和性能非常有幫助。

使用AOF

開啟AOF功能需要設置參數:appendonly yes,默認不開啟。AOF文件名通過appendfilename參數設置,默認文件名是appendonly.aof。保存路徑同RDB持久化方式一致,通過dir配置指定。AOF的工作流程操作:命令寫入(append)、文件同步(sync)、文件重寫(rewrite)、重啟加載(load),如下圖:

學習Redis持久化

流程如下:

1)所有的寫入命令會追加到aof_buf(緩沖區)中。

2)AOF緩沖區根據對應的策略向硬盤做同步操作。

3)隨著AOF文件越來越大,需要定期對AOF文件進行重寫,達到壓縮的目的。

4)當Redis服務器重啟時,可以加載AOF文件進行數據恢復。

了解AOF工作流程之后,下面針對每個步驟做詳細介紹。

命令寫入

AOF命令寫入的內容直接是文本協議格式。例如set hello world這條命令,在AOF緩沖區會追加如下文本

*3
$3
set
$5
hello
$5
world

關于AOF的兩個疑惑:

1)AOF為什么直接采用文本協議格式?可能的理由如下:

文本協議具有很好的兼容性。

開啟AOF后,所有寫入命令都包含追加操作,直接采用協議格式,避免了二次處理開銷。

文本協議具有可讀性,方便直接修改和處理。

2)AOF為什么把命令追加到aof_buf中?Redis使用單線程響應命令,如果每次寫AOF文件命令都直接追加到硬盤,那么性能完全取決于當前硬盤負載。先寫入緩沖區aof_buf中,還有另一個好處,Redis可以提供多種緩沖區同步硬盤的策略,在性能和安全性方面做出平衡。

文件同步

Redis提供了多種AOF緩沖區同步文件策略,由參數appendfsync控制,不同的含義如下:

always:命令寫入aof_buf后調用系統fsync操作同步到AOF文件,fsync完成后線程返回

everysec:命令寫入aof_buf后調用系統write操作,write完成后線程返回。fsync同步文件操作由專門線程每秒調用一次

no:命令寫入aof_buf后調用系統write操作,不對AOF文件做fsync同步,同步硬盤操作由操作系統負責,通常同步周期最長30秒

系統調用write和fsync說明:

write操作會觸發延遲寫(delayed write)機制。Linux在內核操作頁緩沖區用來提高硬盤IO性能。write操作在寫入系統緩沖區后直接返回。同步硬盤操作依賴于系統調度機制,例如:緩沖區頁空間寫滿或達到特定時間周期。同步文件之前,如果此時系統故障宕機,緩沖區內數據將丟失。

fsync針對單個文件操作(比如AOF文件),做強制硬盤同步,fsync將阻塞直到寫入硬盤完成后返回,保證了數據持久化。

除了write、fsync、Linux還提供了sync、fdatasync操作。

配置為always時,每次寫入都要同步AOF文件,在一般的SATA硬盤上,Redis只能支持大約幾百TPS寫入,顯然跟Redis高性能特性背道而馳,不建議配置。

配置為no,由于操作系統每次同步AOF文件的周期不可控,而且會加大每次同步硬盤的數據量,雖然提升了性能,但數據安全性無法保證。

配置為everysec,是建議的同步策略,也是默認配置,做到兼顧性能和數據安全性。理論上只有在系統突然宕機的情況下丟失1秒的數據。(嚴格來說最多丟失1it數據是不準確的)。

重寫機制

隨著命令不斷寫入AOF,文件會越來越大,為了解決這個問題,Redis引入AOF重寫機制壓縮文件體積。AOF文件重寫是把Redis進程內的數據轉化為寫命令同步到新AOF文件的過程。

重寫后的AOF文件為什么可以變小?有如下原因:

1)進程內已經超時的數據不再寫入文件

2)舊的AOF文件含有有效命令,如del key1、hdel key2、srem keys、set a111、set a222等。重寫使用進程內數據直接生成,這樣新的AOF文件只保留最終數據的寫入命令。

3)多條寫命令可以合并為一下,如:lpush list a、lpush list b、lpush list c可以轉化為:lpush list a b c。為了防止單條命令過大造成客戶端緩沖區溢出,對于list、set、hash、zset等類型操作,以64個元素為界拆分為多條。

AOF重寫降低了文件占用空間,除此之外,另一個目的是:更小的AOF文件可以更快被Redis加載。

AOF重寫過程可以手動觸發和自動觸發:

手動觸發:直接調用bgrewriteaof命令

自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數確定自動觸發時機。

auto-aof-rewrite-min-size:表示運行AOF重寫時文件最小體積,默認為64M。

auto-aof-rewrite-percentage:代表當前AOF文件空間(aof_current_size)和上一次重寫后AOF文件(aof_base_size)的比值。

自動觸發時間=aof_current_size>auto-aof-rewrite-min-size && (aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewrite-percentage

其中aof_current_size和aof_base_size可以在info Persistence統計信息中查看。

        自動觸發AOF重寫,會輸出如下日志:

18827:M 04 Apr 23:30:49.519 * Starting automatic rewriting of AOF on 1054% growth
18827:M 04 Apr 23:30:49.520 * Background append only file rewriting started by pid 21365
18827:M 04 Apr 23:30:50.617 * AOF rewrite child asks to stop sending diffs.
21365:C 04 Apr 23:30:50.618 * Parent agreed to stop sending diffs. Finalizing AOF...
21365:C 04 Apr 23:30:50.618 * Concatenating 0.03 MB of AOF diff received from parent.
21365:C 04 Apr 23:30:50.631 * SYNC append only file rewrite performed
21365:C 04 Apr 23:30:50.632 * AOF rewrite: 7 MB of memory used by copy-on-write
18827:M 04 Apr 23:30:50.641 * Background AOF rewrite terminated with success
18827:M 04 Apr 23:30:50.641 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
18827:M 04 Apr 23:30:50.641 * Background AOF rewrite finished successfully

當觸發AOF重寫時,內存做了哪些事呢?結合下圖介紹運行流程

學習Redis持久化

流程說明:

1)執行AOF重寫請示

如果當前進程正在執行AOF重寫,請求不執行并返回如下響應:

(error) ERR Background append only file rewriting already in progress

如果當前進程正在執行bgsave操作,重寫命令延遲到bgsave完成之后再執行,返回如下響應:

Background append only file rewriting scheduled

2) 父進程進程fork創建子進程,開銷等同于bgsave過程。

3.1) 主進程fork操作完成后,繼續響應其他命令。所有修改命令依然寫入AOF緩沖區并根據appendfsync策略同步到硬盤,保證原有AOF機制正確性。

3.2)由于fork操作運用寫時復制技術,子進程只能共享fork操作時的內存數據。由于父進程依然響應命令,Redis使用"AOF重寫緩沖區"保存這部分新數據,防止新AOF文件生成期間丟失這部分數據。

4)子進程根據內存快照,執照命令合并規則寫入到新的AOF文件。每次批量寫入硬盤數據量由配置aof-rewrite-incremental-fsync控制,默認為32MB,防止單次刷盤數據過多造成硬盤阻塞。

5.1)新AOF文件寫入完成后,子進程發送信號給父進程,父進程更新統計信息,具體見info persistence下的aof_*相關統計。

5.2)父進程把AOF重寫緩沖區的數據寫入到新的AOF文件。

5.3)使用新AOF文件替換老文件,完成AOF重寫。

重啟加載

AOF和RDB文件都可以用于服務器重啟時的數據恢復。如下圖所示,表示Redis持久化文件加載流程。

流程說明:

1)AOF持久化開啟且存在AOF文件時,優先加載AOF文件,打印如下日志

18827:M 04 Apr 23:21:01.257 * DB loaded from append only file: 1.207 seconds

2)AOF關閉或AOF文件不存在時,加載RDB文件,打印如下日志:

7792:M 01 Apr 22:33:58.418 * DB loaded from disk: 0.003 seconds

3)加載AOF/RDB文件成功后,Redis啟動成功

4)AOF/RDB文件存在錯誤時,Redistribute啟動失敗并打印錯誤信息。

文件校驗

加載損壞的AOF文件時會拒絕啟動,并打印如下日志:

Bad file format reading the append only file: make a backup of your AOF file,then use ./redis-check-aof --fix <filename>

對于錯誤格式的AOF文件,先進行備份,然后采用redis-check-aof --fix命令進行修復,修復后使用diff -u對比數據的差異,找出丟失的數據,有些可以人工修改補全。

AOF文件可能存在結尾不完整的情況,比如機器突然掉電導致AOF尾部命令寫入不全。Redis為我們提供了aof-load-truncated配置來兼容這種情況,默認開啟。加載AOF時,當遇到此問題時會忽略并繼續啟動,同時打印如下警告日志:

27752:M 04 Apr 23:47:34.655 # !!! Warning: short read while loading the AOF file !!!
27752:M 04 Apr 23:47:34.655 # !!! Truncating the AOF at offset 1377811 !!!
27752:M 04 Apr 23:47:34.655 # AOF loaded anyway because aof-load-truncated is enabled



博文內容摘自《Redis開發與運維》一書。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凭祥市| 伊春市| 乌兰县| 钟山县| 盐亭县| 甘肃省| 绿春县| 佛山市| 临桂县| 航空| 湘潭县| 兴隆县| 万山特区| 子长县| 肥乡县| 双桥区| 隆林| 泰州市| 吉水县| 汉川市| 泽普县| 海原县| 临夏县| 库尔勒市| 凤庆县| 五指山市| 九龙县| 昭觉县| 新余市| 沙田区| 南漳县| 锡林浩特市| 普格县| 梅河口市| 山阳县| 成武县| 潼关县| 东乌珠穆沁旗| 德清县| 阳西县| 红河县|