理解inode
895
2022-05-28
Redis的持久化存儲策略
redis是一個高性能的緩存數據庫,既然是緩存,它的數據就是存儲在內存中的,如果說服務器斷電了, 或者重啟了,或者redis宕機了,他的數據就一定會丟失,所以為了解決這個問題,在丟失數據之前就將數據給持久化保存到磁盤,這種持久化技術,就是RDB和AOF
什么是RDB
redis Database 的簡寫,是將redis內存中的數據保存為一個快照文件,類似Jmap的dump堆轉儲功能,但rdb是時點性的,只能存儲某一時刻的快照,不能實時存儲,如果單單使用rdb,它的數據就一定會丟失;
以快照的方式存儲,所以恢復速度相對較快,
不支持拉鏈式的快照,也就是說,生成的快照文件永遠只有一個;
因為是時點性的,在持久化時將數據保存到磁盤需要一定的時間,在這段時間內可能會有其他的寫操作,所以容易丟失數據
持久化觸發方式
RDB的持久化觸發方式有2種,分別為手動觸發和自動觸發,手動觸發只需要登陸redis后輸入相應的命令即刻,自動觸發需要配置持久化的規則;
1、手動觸發RDB
手動觸發RDB持久化方式的命令有2種,分別是阻塞和異步:
save:執行save命令后redis進入阻塞狀態,在RDB生成快照期間,redis不能執行其他命令,直到RDB完成方可解除阻塞狀態;
bgsave:執行bgsave命令后,redis會以異步的方式進行持久化操作,以fork的方式創建一個子進程(注意是進程,不是線程);RDB持久化操作由子進程負責,完成后自動結束子進程;在異步持久化期間,redis可以正常執行命令;不會有任何影響;阻塞只發生在fork階段,一般時間很短
注意事項
在命令行登錄redis后輸入save或者bgsave即可持久化存儲;
基本上 Redis 內部所有的RDB操作都是采用 bgsave 命令。
執行執行 flushall 命令,也會產生dump.rdb快照文件,但里面是空的.
2、自動觸發RDB
先進入redis目錄,打開redis.conf配置文件,找到以下幾項配置:
rdbcompression yes :默認值是yes。對于存儲到磁盤中的快照,可以設置是否進行壓縮存儲。如果是的話,redis會采用LZF算法進行壓縮。如果你不想消耗CPU來進行壓縮的話,可以設置為關閉此功能,但是存儲在磁盤上的快照會比較大。
rdbchecksum yes:默認值是yes。在存儲快照后,我們還可以讓redis使用CRC64算法來進行數據校驗,但是這樣做會增加大約10%的性能消耗,如果希望獲取到最大的性能提升,可以關閉此功能。
dbfilename dump.rdb: 設置快照的文件名,默認是 dump.rdb
dir /usr/local/redis/rdb: 設置快照文件的存放路徑,這個配置項一定是個目錄,而不能是文件名。默認是和當前配置文件保存在同一目錄。
自動觸發RDB的持久化條件
save "" :如果不想要使用RDB,可以使用此配置關閉 RDB功能
save 900 1: 900 秒內如果至少有 1 個 key 的值變化,則進行持久化保存
save 300 10: 300 秒內如果至少有 10 個 key 的值變化,則進行持久化保存
save 60 10000:60 秒內如果至少有 10000 個 key 的值變化,則進行持久化保存
bgsave底層原理
前置知識 - linux的fork函數、copy on write(流程圖)
在了解異步RDB原理之前,我們需要先了解fork是個什么玩意;
調用fork函數后,linux會創建一個與原來進程幾乎完全相同的進程,也就是兩個進程可以做完全相同的事,但如果初始參數或者傳入的變量不同,兩個進程也可以做不同的事。
一個進程調用fork()函數后,系統先給新的進程分配資源,例如存儲數據和代碼的空間。然后把原來的進程的所有值都復制到新的新進程中,只有少數值與原來的進程的值不同。相當于克隆了一個自己。
在克隆時,需要滿足2個條件,
速度要快
占用內存空間要小
為了滿足以上2點要求,linux使用了copy on write機制(寫入時復制),也就是說,雖然是克隆了2一個子進程出來,但是父子進程種變量的內存指針還是指向同一個內存空間,比如一開始都父子進程的變量A的值都是123,但我修改子進程變量A的值時,改為456,那么操作系統會先在內存寫入新的值456,然后在將子進程的變量A指向新的內存值456;
克隆后的進程為子進程,常規情況下,子進程和主進程之間的數據完全隔離;互不影響;子進程的修改不會破壞父進程,父進程的修改也不會破壞子進程;
bgsave原理(流程圖)
在輸入bgsave命令后,redis在內部做了以下幾件事
通過fork函數創建一個子進程;此方法會產生阻塞,但時間很短;
redis的增刪改查由父進程負責;
持久化RDB由子進程負責;
持久化完成后,子進程自動結束;
AOF
append only file的簡寫,意思是只會向文件追加,指的是客戶端對redis的增、刪、改操作,會以追加的形式將操作語句保存到文件中;
AOF優點
恢復時丟失數據少
RDB和AOF可同時開啟;在4.0以前恢復時只用aof恢復;4.0以后使用混合型的持久化機制,下文會介紹
AOF缺點
速度較慢,每次寫操作都會寫磁盤;
rewrite機制(重寫)
我們都知道磁盤空間是有限的,但是redis的增刪改的命令卻是無窮無盡的,為了保證磁盤不被占滿,就需要引入rewrite機制;在命令行輸入以下指令即可觸發rewrite重寫AOF文件;
BGREWRITEAOF
1
rewrite機制是自動觸發的,需要設定一個閾值,也就是你的aof文件大小的閾值,比如我設置大小為64M時,當aof文件大小達到64M就會自動觸發rewrite機制,會對aod文件做些優化,去掉一些過程重復的命令;比如我連續執行了下面的命令
set name yexindong set name zhangsan set name lisi
1
2
3
那其實,name最終的結果是lisi,也就是第三個命令,第一個和第二個執不執行都不會影響最終的結果,所以當aof文件叨叨64M時,rewrite原理觸發,就會將下面的語句刪除
set name yexindong set name zhangsan
1
2
最后只保留set name lisi的語句;去掉中間沒用的語句,優化就完成了;經過這一次瘦身,aof文件就會變得更小了;
AOF使用
同樣的,AOF也需要在配置文件中進行相關配置;
appendonly no: 默認值為no,也就是說redis 默認使用的是rdb方式持久化,如果想要開啟 AOF 持久化方式,需要將 appendonly 修改為 yes。
appendfilename "appendonly.aof":AOF文件名稱,配置后,就會將寫指令追加到這個文件內
dir /usr/local/redis/rdb: AOF文件的保存目錄,與RDB一致
appendfsync:aof持久化策略的配置;
no:表示不執行fsync,由操作系統保證數據同步到磁盤,速度最快,但是不太安全;
always:表示每次寫入都執行fsync,以保證數據同步到磁盤,效率很低;
everysec:(默認的)表示每秒執行一次fsync,可能會導致丟失這1s數據。通常選擇 everysec ,兼顧安全性和效率。
no-appendfsync-on-rewrite:在aof重寫或者寫入rdb文件的時候,會執行大量IO,此時對于everysec和always的aof模式來說,執行fsync會造成阻塞過長時間,no-appendfsync-on-rewrite字段設置為默認設置為no。如果對延遲要求很高的應用,這個字段可以設置為yes,否則還是設置為no,這樣對持久化特性來說這是更安全的選擇。 設置為yes表示rewrite期間對新寫操作不fsync,暫時存在內存中,等rewrite完成后再寫入,默認為no,建議yes。Linux的默認fsync策略是30秒。可能丟失30秒數據。默認值為no。
auto-aof-rewrite-percentage:默認值為100。這個值是個百分比的數值,aof自動重寫配置,當目前aof文件大小超過上一次重寫的aof文件大小的百分之多少進行重寫,即當aof文件增長到一定大小的時候,Redis能夠調用bgrewriteaof對日志文件進行重寫(rewrite)。當前AOF文件大小是上次日志重寫得到AOF文件大小的二倍(設置為100)時,自動啟動新的日志重寫(rewrite)過程。
auto-aof-rewrite-min-size:64mb。設置允許重寫(rewrite)的最小aof文件大小,避免了達到約定百分比但尺寸仍然很小的情況還要重寫(rewrite)。
aof-load-truncated:aof文件可能在尾部是不完整的,當redis啟動的時候,aof文件的數據被載入內存。重啟可能發生在redis所在的主機操作系統宕機后,尤其在ext4文件系統沒有加上data=ordered選項,出現這種現象 redis宕機或者異常終止不會造成尾部不完整現象,可以選擇讓redis退出,或者導入盡可能多的數據。如果選擇的是yes,當截斷的aof文件被導入的時候,會自動發布一個log給客戶端然后load。如果是no,用戶必須手動redis-check-aof修復AOF文件才可以。默認值為 yes。
aof使用注意事項
要使用AOF功能,在啟動時不能直接運行redis-server。一定要加配置文件運行./redis-server /etc/redis/redis.conf,加了配置文件后AOF功能才會生效
AOF文件內容說明
首先我們執行下面這個命令,看看aof文件中都保存了哪些東西;
set k1 hello
1
然后通過命令打開aof文件 vim appendonly.aof,可以看到以下內容
*2 // *開頭表示是一個新命令,這個命令有2個元素組成 $6 // $開頭表示下一行命令的字符長度 SELECT // 選擇庫的指令,redis有16個庫:0~15之間 $1 0 // 和上面的命令組成為:SELECT 0,表示選擇0號庫 *3 // 下一個命令,這個命令有3個元素組成 $3 // 下一行的命令長度 set // set命令 $2 k1 // key 的名稱 $5 hello // key的值,和上面2個命令組成:set k1 hello
1
2
3
4
5
6
7
8
9
10
11
12
Redis是如何進行持久化的(流程圖)
在reids4.0的以后,提供了一種混合型的持久化機制,就是RDB + AOF的持久化方式;在配置文件中會有以下配置,設置為yes表示開啟,設置為no表示禁用。默認為yes
aof-use-rdb-preamble yes
1
當開啟混合持久化時,主進程先fork出子進程將現有內存副本全量以RDB方式寫入aof文件中,然后將緩沖區中的增量命令以AOF方式寫入aof文件中,寫入完成后通知主進程更新相關信息,并將新的含有 RDB和AOF兩種格式的aof文件替換舊的aof文件。
也就是說,RDB 和 AOF文件是在同一個文件里面的,在進行備份的時候,比如是2點整進行備份的,先將這個文件先刪除掉,然后將當前的數據以RDB快照的方式保存到aof文件種,最后,以增量的方式將增、刪、改命令追加到AOF文件中;這樣就可以保證重啟或者斷電后,恢復數據會保持和斷電前一致了;
簡單來說:混合持久化方式產生的文件一部分是RDB格式,一部分是AOF格式。
這種方式優點我們很好理解,缺點就是不能兼容Redis4.0之前版本的備份文件了。
數據恢復
啟動redis時,redis會自動加載rbd文件和 aof文件進行數據恢復;前提是得先開啟相應的配置后才會恢復數據,配置如下
# 開啟 AOF 持久化配置 appendonly yes # 開啟 RDB持久化配置 rdbcompression yes
1
2
3
4
5
Redis 任務調度
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。