redis之AOF和RDB持久化
寫在前面
redis數據存儲在內存,為了避免服務器重啟或者是宕機導致數據全部丟失,提供了數據持久化機制,有AOF(Append Only File)和RDB,接下來我們分別看下。
1:AOF
如下是我本地環境生成aof文件:
1.1:AOF日志的實現
首先我們需要配置appendonly yes來打開AOF持久化,之后當我們執行完數據修改命令后,redis就會將命令記錄到aof文件中,這個過程不同于MySQL的WAL 機制(MySQL要解決主要問題數據的安全存儲,而redis要解決的主要問題是高性能的數據存取),在寫數據之前先寫日志,redis是寫數據之后再寫日志,這樣做的其中一個原因是可以不用對命令本身的語法進行校驗了(既然都執行成功了,肯定語法沒有問題),該過程如下圖:
如執行命令set aa bbbb則生成的aof日志如下:
*3 $3 set $2 aa $4 bbbb含義如下:
*3:命令由3部分組成 $數字:代表接下來是命令的一部分,數字代表該部分的長度通過以上信息可以反推出命令set aa bbbb,就可以用來備份和恢復數據了。另外針對aof的寫回策略提供了若干個參數來控制,接下來繼續看下。
1.2:寫回策略
目前redis的寫回策略有三種,通過配置項appendfsync設置,如下:
Always:同步寫回,使用主線程,所以會影響到主線程的性能。 Everysec:每秒寫回,先將命令寫到aof的緩沖區,然后其他線程每隔一秒寫到aof文件。 No:操作系統控制寫回,命令僅僅寫道aof緩沖區,由操作系統控制寫到aof文件。對比如下表:
隨著越來越多的命令寫入到aof文件,aof文件會變得越來越大,而aof文件的不斷增大可能會產生如下的問題:
1:達到了操作系統對單文件大小的限制,從而無法繼續寫入 2:文件增大之后數據寫入的速度會變慢,影響寫入性能 3:文件過大,數據恢復的速度慢為了解決以上可能的問題,redis提供了AOF重寫機制。
1.3:AOF重寫機制
aof重寫機制的原理是多合一,即將多個命令合并成一個命令,因為可能會對一個key重復操作多次,所以同一個key的操作命令會被記錄多次,但是對于恢復數據而言,只需要最終的一個數據狀態就行了,所以根據數據當前的狀態反向生成一條命令即可,這就是多合一的過程,如下圖對一個list的多次操作執行重寫的過程:
為了完成AOF重寫過程,redis會fork處一個新的子進程bgrewriteaof,并將當前內存中的數據拷貝一份,然后使用當前最新的數據生成對應的命令,并寫到一個新的aof文件中,這個過程就是AOF重寫,可以參考下圖:
aof重寫完成后,就可以使用新的aof文件替換舊的aof文件了。
2:RDB
如下是我本地生成rdb文件:
前面我們分析了AOF持久化,但這種方式有一個問題,就是當修改命令變多時會導致文件過大,從而導致數據恢復速度慢。這個問題我們可以通過RDB(redis database)來解決。
2.1:原理和配置
- 原理
Redis通過定時任務掃描數據的變化是否滿足某個規則,如果是滿足了規則則使用操作系統提供的相關機制,則調用fork()創建子進程,對redis當前的內存空間生成dump.rdb快照文件,該文件存儲了內存數據對應的二進制數據,可以直接加載到內存中來恢復redis的數據,恢復速度快。 - 配置策略
redis有兩種配置策略,一種是手動觸發策略,另外一種是自動觸發策略,其中自動觸發策略可以通過save,bgsave命令來手動觸發,前者會使用主線程執行備份,如下:
注意:LASTSAVE 命令用于查看 BGSAVE 命令是否執行成功。
自動觸發策略通過如下配置:
save 900 1 save 300 10 save 60 10000以上配置的格式是save 時長 修改次數,以上配置的含義是如果是在900內發生至少一次更新,或者在300內發生至少10次更新,或者是60秒內發生至少10000次更新,則執行bgsave生成rdb快照文件,并且生成文件后用于觸發策略的計數和計時都會重置。
2.2:復制都有哪些問題
在進行復制的時候,還允許數據更新嗎?如果是允許更新的話,就會有數據一致性的問題,如果是不允許更新的話,則會影響正常的數據更新。當然,影響正常的數據更新肯定是不允許的,因為會嚴重影響業務,甚至可能會出現線上事故,而數據一致性的問題更加不允許了,如果是后續使用其恢復數據的話,問題就更大了,所以只需要解決允許更新時有數據一致性的問題就可以了,redis的做法是使用COW(將要更新的數據copy出一份,直接更新copy的那份)機制,即更新時將更新目標對應的內存頁復制出來一份,對復制的內存頁執行更新,則原始數據不會受到影響,待rdb生成完畢后,再將COW的內存頁重新寫回到原始內存頁就行了(這個過程很快),這樣就能解決數據一致性的問題了,參考下圖:
好了,現在我們已經能夠在不影響客戶端更新的情況下獲取符合數據一致性要求的快照了,但是更新時時刻都在發生的,那么在這次快照生成之后多久之后再次生成呢,如果是頻率過慢,比如十分鐘一次,如果發生宕機,則上次快照到宕機時刻的所有數據都會丟失,如果是過快,比如一秒一次,這樣可以大大減少宕機造成的數據丟失,但是會對系統的IO等資源造成比較大的壓力,而且創建子進程的fork操作也是會阻塞主線程,因此也會影響到正常的數據操作,其實我們只需要處理好兩次快照之間的數據就行了,一種方案是記錄修改日志,即記錄對數據都做了什么修改,如下圖:
這種方案也沒有太大問題,但是在redis4.0中提供了更好的一種方案,即通過rdb和aof混用的方式,就巧妙的將這個問題解決了,即兩次快照空隙的數據修改通過aof日志方式記錄,則就既能使用到rdb恢復速度快的優勢,也能夠規避aof文件過大帶來的問題,發揮其記錄簡單的優勢,此時,rdb就是全量備份,而aof就是增量備份,二者混用執行可能如下圖:
真是一種完美的解決方案,可以在線上起來。
寫在后面
參考文章列表:
Redis RDB持久化詳解(原理+配置策略) 。
總結
以上是生活随笔為你收集整理的redis之AOF和RDB持久化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 好佳居软装十大品牌 掌握新中式软装风格
- 下一篇: python对excel指定数据提取并保