關(guān)于Redis持久化需要了解的
AI全套:Python3+TensorFlow打造人臉識別智能小程序
最新人工智能資料-Google工程師親授 Tensorflow-入門到進(jìn)階
黑馬頭條項目 - Java Springboot2.0(視頻、資料、代碼和講義)14天完整版
Redis是一個鍵值對數(shù)據(jù)庫服務(wù)器,由于Redis是內(nèi)存數(shù)據(jù)庫,那么有很多內(nèi)存的特點,例如掉電易失,或者進(jìn)程退出,服務(wù)器中的數(shù)據(jù)也將消失不見,所以需要一種方法將數(shù)據(jù)從內(nèi)存中寫到磁盤,這一過程稱之為數(shù)據(jù)持久化。
RDB持久化
SAVE,另一個是BGSAVE。bgsave與save不同,bgsave會創(chuàng)建一個子線程來完成數(shù)據(jù)持久化的任務(wù),主服務(wù)器依舊對外提供服務(wù)。def save():rdbSave()
def BGSAVE():# 創(chuàng)建子進(jìn)程pid = fork()if pid == 0:# 子進(jìn)程創(chuàng)建RDB文件rdbSave()# 完成之后向父進(jìn)程發(fā)送信號signal_parent()if pid > 0# 父進(jìn)程繼續(xù)處理請求,并通過輪詢等待子進(jìn)程的信號handle_request_and_wait_signal()else:# 處理出錯情況handle_fork_error()
那么只要滿足以下三個條件中的任意一個,BGSAVE命令就會被執(zhí)行:
服務(wù)器在900秒之內(nèi),對數(shù)據(jù)庫進(jìn)行了至少1次修改。
RDB文件結(jié)構(gòu)

db_version長度為4字節(jié),它的值是一個字符串表示的整數(shù),這個整數(shù)記錄了RDB文件的版本號,比如"0006"就代表RDB文件的版本為第六版。本章只介紹第六版RDB文件的結(jié)構(gòu)。
databases部分包含著零個或任意多個數(shù)據(jù)庫,以及各個數(shù)據(jù)庫中的鍵值對數(shù)據(jù):如果服務(wù)器的數(shù)據(jù)庫狀態(tài)為空(所有數(shù)據(jù)庫都是空的),那么這個部分也為空,長度為0字節(jié)。·如果服務(wù)器的數(shù)據(jù)庫狀態(tài)為非空(有至少一個數(shù)據(jù)庫非空),那么這個部分也為非空,根據(jù)數(shù)據(jù)庫所保存鍵值對的數(shù)量、類型和內(nèi)容不同,這個部分的長度也會有所不同。
EOF常量的長度為1字節(jié),這個常量標(biāo)志著RDB文件正文內(nèi)容的結(jié)束,當(dāng)讀入程序遇到這個值的時候,它知道所有數(shù)據(jù)庫的所有鍵值對都已經(jīng)載入完畢了。
AOF持久化

如果我們對空白的數(shù)據(jù)庫執(zhí)行以下寫命令,那么數(shù)據(jù)庫中將包含三個鍵值對:
redis>?SET?msg?"hello"?OK?redis>?SADD?fruits?"apple"?"banana"?"cherry"?(integer)?3?redis>?RPUSH?numbers?128?256?512?(integer)?3
*2\r\n$6\r\nSELECT\r\n$1\r\n0\r\n?*3\r\n$3\r\nSET\r\n$3\r\nmsg\r\n$5\r\nhello\r\n?*5\r\n$4\r\nSADD\r\n$6\r\nfruits\r\n$5\r\napple\r\n$6\r\nbanana\r\n$6\r\ncherry\r\n?*5\r\n$5\r\nRPUSH\r\n$7\r\nnumbers\r\n$3\r\n128\r\n$3\r\n256\r\n$3\r\n512\r\n
在這個AOF文件里面,除了用于指定數(shù)據(jù)庫的SELECT命令是服務(wù)器自動添加的之外,其他都是我們之前通過客戶端發(fā)送的命令。服務(wù)器在啟動時,可以通過載入和執(zhí)行AOF文件中保存的命令來還原服務(wù)器關(guān)閉之前的數(shù)據(jù)庫狀態(tài),以下就是服務(wù)器載入AOF文件并還原數(shù)據(jù)庫狀態(tài)時打印的日志:
[8321] 05 Sep 11:58:50.448 # Server started, Redisversion 2.9.11[8321] 05 Sep 11:58:50.449 * DB loaded from append only file: 0.000 seconds[8321]?05?Sep?11:58:50.449?*?The?server?is?now?ready?to?accept?connections?on?port?6379
AOF持久化流程
def eventLoop():while True:# 處理文件事件,接收命令請求以及發(fā)送命令回復(fù)# 處理命令請求時可能會有新內(nèi)容被追加到 aof_buf 緩沖區(qū)中processFileEvents()# 處理時間事件processTimeEvents()# 考慮是否要將 aof_buf 中的內(nèi)容寫入和保存到 AOF 文件里面flushAppendOnlyFile()
flushAppendOnlyFile函數(shù)的行為由服務(wù)器配置的appendfsync選項的值來決定,各個不同值產(chǎn)生的行為如下表所示:
| always | 將?aof_buf?緩沖區(qū)中的所有內(nèi)容寫入并同步到 AOF 文件。 |
| everysec | 將?aof_buf?緩沖區(qū)中的所有內(nèi)容寫入到 AOF 文件, 如果上次同步 AOF 文件的時間距離現(xiàn)在超過一秒鐘, 那么再次對 AOF 文件進(jìn)行同步, 并且這個同步操作是由一個線程專門負(fù)責(zé)執(zhí)行的。 |
| no | 將?aof_buf?緩沖區(qū)中的所有內(nèi)容寫入到 AOF 文件, 但并不對 AOF 文件進(jìn)行同步, 何時同步由操作系統(tǒng)來決定。 |
如果用戶沒有主動為appendfsync選項設(shè)置值,那么appendfsync選項的默認(rèn)值為everysec
AOF存在的問題
write?函數(shù), 將一些數(shù)據(jù)寫入到文件的時候, 操作系統(tǒng)通常會將寫入數(shù)據(jù)暫時保存在一個內(nèi)存緩沖區(qū)里面, 等到緩沖區(qū)的空間被填滿、或者超過了指定的時限之后, 才真正地將緩沖區(qū)中的數(shù)據(jù)寫入到磁盤里面。fsync?和?fdatasync?兩個同步函數(shù), 它們可以強制讓操作系統(tǒng)立即將緩沖區(qū)中的數(shù)據(jù)寫入到硬盤里面, 從而確保寫入數(shù)據(jù)的安全性。AOF 持久化的效率和安全性
appendfsync?選項的值直接決定 AOF 持久化功能的效率和安全性。appendfsync?的值為?always?時, 服務(wù)器在每個事件循環(huán)都要將?aof_buf?緩沖區(qū)中的所有內(nèi)容寫入到 AOF 文件, 并且同步 AOF 文件, 所以?always?的效率是?appendfsync?選項三個值當(dāng)中最慢的一個, 但從安全性來說,?always?也是最安全的, 因為即使出現(xiàn)故障停機, AOF 持久化也只會丟失一個事件循環(huán)中所產(chǎn)生的命令數(shù)據(jù)。appendfsync?的值為?everysec?時, 服務(wù)器在每個事件循環(huán)都要將?aof_buf?緩沖區(qū)中的所有內(nèi)容寫入到 AOF 文件, 并且每隔超過一秒就要在子線程中對 AOF 文件進(jìn)行一次同步:從效率上來講,?everysec?模式足夠快, 并且就算出現(xiàn)故障停機, 數(shù)據(jù)庫也只丟失一秒鐘的命令數(shù)據(jù)。appendfsync?的值為?no?時, 服務(wù)器在每個事件循環(huán)都要將?aof_buf?緩沖區(qū)中的所有內(nèi)容寫入到 AOF 文件, 至于何時對 AOF 文件進(jìn)行同步, 則由操作系統(tǒng)控制。no?模式下的?flushAppendOnlyFile?調(diào)用無須執(zhí)行同步操作, 所以該模式下的 AOF 文件寫入速度總是最快的, 不過因為這種模式會在系統(tǒng)緩存中積累一段時間的寫入數(shù)據(jù), 所以該模式的單次同步時長通常是三種模式中時間最長的:從平攤操作的角度來看,?no?模式和?everysec?模式的效率類似, 當(dāng)出現(xiàn)故障停機時, 使用?no?模式的服務(wù)器將丟失上次同步 AOF 文件之后的所有寫命令數(shù)據(jù)。AOF重寫
全棧架構(gòu)社區(qū)交流群
?「全棧架構(gòu)社區(qū)」建立了讀者架構(gòu)師交流群,大家可以添加小編微信進(jìn)行加群。歡迎有想法、樂于分享的朋友們一起交流學(xué)習(xí)。
看完本文有收獲?請轉(zhuǎn)發(fā)分享給更多人
Flutter 移動應(yīng)用開發(fā)實戰(zhàn) 視頻(開發(fā)你自己的抖音APP) Java面試進(jìn)階訓(xùn)練營 第2季(分布式篇) Java高級 - 分布式系統(tǒng)開發(fā)技術(shù)視頻
