wordpress表單上傳多個文件濰坊關(guān)鍵詞優(yōu)化軟件
redis系列整體欄目
內(nèi)容 | 鏈接地址 |
---|---|
【一】redis基本數(shù)據(jù)類型和使用場景 | https://zhenghuisheng.blog.csdn.net/article/details/142406325 |
【二】redis的持久化機(jī)制和原理 | https://zhenghuisheng.blog.csdn.net/article/details/142441756 |
如需轉(zhuǎn)載,請輸入:https://blog.csdn.net/zhenghuishengq/article/details/142441756
redis的持久化機(jī)制和原理
- 一,redis的持久化機(jī)制和原理
- 1,RDB持久化
- 1.1,save方式實(shí)現(xiàn)
- 1.2,bgsave的實(shí)現(xiàn)
- 1.3,rdb的優(yōu)缺點(diǎn)
- 2,AOF持久化
- 2.1,aof原生命令
- 2.2,aof重寫
- 3,rdb和aof優(yōu)缺點(diǎn)
- 4,rdb和aof混合持久化
一,redis的持久化機(jī)制和原理
在平常開發(fā)中,redis一般是做為緩存使用,但是在很多大型互聯(lián)網(wǎng)公司中,都是很依賴redis,將數(shù)據(jù)存儲在redis中,如果redis掛了,那么在重啟之后內(nèi)部的數(shù)據(jù)就會丟失,因此在redis層面,需要對內(nèi)部的數(shù)據(jù)進(jìn)行持久化。在redis持久化中,主要有兩種方式:rdb和aof
1,RDB持久化
1.1,save方式實(shí)現(xiàn)
在redis中,默認(rèn)使用的就是rdb這種持久化方式,可以通過redis中安裝的redis.conf配置文件查看。redis配置的策略如下,可以通過配置save命令來實(shí)現(xiàn)持久化的的操作,在一定的時間段,配置一定的閾值,當(dāng)觸發(fā)到閾值時,將內(nèi)存中的數(shù)據(jù)進(jìn)行持久化。
save 900 1 # 在 900 秒內(nèi)至少有 1 次寫操作,進(jìn)行快照
save 300 10 # 在 300 秒內(nèi)至少有 10 次寫操作,進(jìn)行快照
save 60 10000 # 在 60 秒內(nèi)至少有 10000 次寫操作,進(jìn)行快照
接下來通過詳細(xì)案例測試一下,為了測試這個快照,我這邊先修改一下配置,在一分鐘內(nèi),只要有一次寫入,那么就會觸發(fā)這個快照機(jī)制
save 60 1 # 在 60 秒內(nèi)至少有 1 次寫操作,進(jìn)行快照
CONFIG SET save "60 1" //直接在客戶端里面操作,和上面這種方式2選1
隨后先清空原有的dump.rdb文件,此時redis中的rdb文件被清空,或者為了測試的話,可以直接先清空所有的key-value,通過 FLUSHALL 命令即可,但是如果是線上環(huán)境需謹(jǐn)慎操作
truncate -s 0 dump.rbd
隨后執(zhí)行幾條插入操作的命令,插入完之后,最后在執(zhí)行以下save命令。在執(zhí)行命令如果報錯error的話,那是因?yàn)闆]滿足閾值觸發(fā)的條件,最好和我一樣,改成60s有一次寫入就觸發(fā)存儲的機(jī)制
set zhenghuisheng:age 18
set zhenghuisheng:height 18
set zhenghuisheng:sex 18
隨后可以直接查看這個dumo.rdb文件,可以發(fā)現(xiàn)數(shù)據(jù)已經(jīng)全部存進(jìn)rdb文件中
通過數(shù)據(jù)可以得知,rdb文件是一種二進(jìn)制文件,更加的適配與操作系統(tǒng),如果宕機(jī)了想要數(shù)據(jù)恢復(fù)的話,那么使用這種二進(jìn)制文件恢復(fù)肯定是效率最高的。
但是如果是使用這種save的方式進(jìn)行持久化,也會帶來部分性能問題,因?yàn)閟ave這種方式是采用的 同步 的方式進(jìn)行數(shù)據(jù)存儲,安全性高,但是如果來了一個 大key,就是一個大對象,如果存一個大對象就要5s,那么此時整個redis都會被阻塞5s,跟內(nèi)部的反應(yīng)堆模式有關(guān),那么就會嚴(yán)重影響redis的性能
1.2,bgsave的實(shí)現(xiàn)
既然上面的save會由于同步帶來一些性能的問題,因此redis也給出了另一份解決思路,就是通過bgsave異步的方式來實(shí)現(xiàn)這個rdb快照,從而提高整體的性能的吞吐量。bgsave,即background,后臺存儲的意思
接下來依舊先演示一下bgsave的使用,先執(zhí)行三條插入數(shù)據(jù)的命令,隨后執(zhí)行 bgsave 進(jìn)行數(shù)據(jù)存儲
set bgsave:001 test1
set bgsave:002 test2
set bgsave:003 test3
結(jié)果如下圖,此時三條命令也已二進(jìn)制的方式存入到dump.db的配置文件中
bgsave通過 寫時復(fù)制(copy-on-write) 的方式實(shí)現(xiàn)異步操作,就是執(zhí)行bgsave的主線程,在執(zhí)行bgsave命令的那一刻,會fork出一個子線程來copy主線程中的所有數(shù)據(jù),并且此時如果還有數(shù)據(jù)寫入進(jìn)來,會同時操作原主線程中的內(nèi)存數(shù)據(jù)和新fork出現(xiàn)的子線程中的數(shù)據(jù)。
既然是使用異步的方式進(jìn)行數(shù)據(jù)的持久化,那么就有可能會不安全,數(shù)據(jù)丟失等問題。
1.3,rdb的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
使用rdb的優(yōu)點(diǎn)在于,內(nèi)部采用的是二進(jìn)制的方式進(jìn)行數(shù)據(jù)存儲,存儲效率較高,如果宕機(jī)了要進(jìn)行數(shù)據(jù)恢復(fù)的話,那么數(shù)據(jù)恢復(fù)也相對較快
缺點(diǎn)
缺點(diǎn)也很明顯,首先就是選擇存儲的方式,即save和bgsave的方式,就是經(jīng)典的高性能和高可用之間做選擇。采用save方式可用保證高可用,數(shù)據(jù)相對安全,但是可能會出現(xiàn)整個系統(tǒng)出現(xiàn)阻塞問題;采用bgsave方式,通過寫時復(fù)制的異步方式進(jìn)行數(shù)據(jù)的存儲,性能相對較快,但是可能造成數(shù)據(jù)丟失等不安全問題。
還有一個主要的問題,rdb是通過某種閾值觸發(fā)的條件實(shí)現(xiàn)rdb存儲,假設(shè)5分鐘達(dá)到1000條命令存儲一次,那么如果在這5分鐘內(nèi)的數(shù)據(jù)剛好到達(dá)了閾值臨界點(diǎn),但是此時redis宕機(jī)了,導(dǎo)致這5分鐘的數(shù)據(jù)沒有進(jìn)行rbd的持久化,那么就可能會丟失5分鐘的數(shù)據(jù),在重啟redis進(jìn)行數(shù)據(jù)恢復(fù)的時候,這5分鐘的數(shù)據(jù)將不能恢復(fù)
2,AOF持久化
雖然說在redis中默認(rèn)的是使用rdb這種方式進(jìn)行持久化,但是rdb這種方式很明顯,可能會造成數(shù)據(jù)丟失比較多的情況,比如一個1w qps/s的系統(tǒng),假設(shè)丟5分鐘數(shù)據(jù),那么就會丟失掉300萬條數(shù)據(jù),顯然使用默認(rèn)的方式是不太合理的
100000 * 60 * 5 = 300 0000
2.1,aof原生命令
因此redis引入了aof文件日志寫入的這種操作,在redis.conf配置文件中,打開 appendonly 設(shè)置為yes即可
appendonly yes
CONFIG SET appendonly yes //直接在客戶端中操作,和上面這種方式的效果一樣
在開啟完aof命令之后,接下來再往redis中插入幾條數(shù)據(jù)
set aof:test1 aof1
set aof:test2 aof2
set aof:test3 aof3
數(shù)據(jù)插入完成之后,接下來查看這個appendonly.aof文件里面到底存的是什么,由于前期aof一直是開著,因此這里只看后面幾條命令即可,如果直接cat把數(shù)據(jù)直接全部的加載到內(nèi)存里面,把內(nèi)存撐爆,導(dǎo)致線上的redis服務(wù)器宕機(jī)了,那就得不償失了
//查看尾部幾條命令
tail -f appendonly.aof
可以發(fā)現(xiàn)里面就是一些原生執(zhí)行命令。然后加一些redis內(nèi)部的一些識別符,在數(shù)據(jù)進(jìn)行恢復(fù)的時候,可以供內(nèi)部的c++程序所識別,從而實(shí)現(xiàn)數(shù)據(jù)的恢復(fù)。實(shí)現(xiàn)數(shù)據(jù)恢復(fù)也比較簡單,就是把這些命令從上往下的全部的執(zhí)行一遍,然后就能將數(shù)據(jù)恢復(fù)。
aof持久化也有對應(yīng)的策略,其持久化的方式有以下三種,默認(rèn)采用 appendfsync everysec 每秒同步一次數(shù)據(jù)
appendfsync always
:每次寫入操作都會立即將數(shù)據(jù)同步到磁盤。安全性最高,但性能最低。appendfsync everysec
:每秒同步一次數(shù)據(jù),這是默認(rèn)選項,性能和安全性之間的折中。appendfsync no
:由操作系統(tǒng)決定何時同步數(shù)據(jù),這樣性能最好,但在崩潰時可能丟失一些數(shù)據(jù)。
到這里為止,丟失問題的情況依舊存在,比如將1s內(nèi)的數(shù)據(jù)再提交到對應(yīng)的日志文件的時候,rdis宕機(jī)了,這就會導(dǎo)致可能丟失1秒鐘的數(shù)據(jù),相對于上面的rdb,已經(jīng)屬于是優(yōu)化的操作。
但是aof也有屬于自己的缺點(diǎn),rdb采用的是二進(jìn)制的壓縮文件,文件大小相對較小,在做數(shù)據(jù)拷貝或者恢復(fù)的時候相對較快;而aof都是記錄原生的命令,包括記錄一些字符串長度等等,隨著數(shù)據(jù)的增加,aof文件會越來越大,一次其數(shù)據(jù)拷貝或者做數(shù)據(jù)恢復(fù)會相對緩慢
2.2,aof重寫
上面談到了aof的缺點(diǎn),會隨著時間的推移,文件變得很大,甚至可能不小心一個cat命令,直接把服務(wù)器的內(nèi)存打滿,導(dǎo)致redis宕機(jī)這種可能,因此aof內(nèi)部添加了aof重寫功能。
舉個例子,假設(shè)一個減庫存的操作,假設(shè)商品id為1001,數(shù)量有10000件,那么預(yù)扣減內(nèi)存的命令就如下
set 1001:stock 9999
set 1001:stock 9998
set 1001:stock 9997
就是很明顯,這個key不變,但是value在變,如果用aof存的話,可能要存10000條數(shù)據(jù),那么aof重寫的機(jī)制就是,只記錄最終值。比如商品賣了5000件,常規(guī)的aof就存了5000條數(shù)據(jù),但是通過aof重寫優(yōu)化之后,只存最終結(jié)果即可,這樣在日志中只需要存一條,最后數(shù)據(jù)恢復(fù)時也只需要恢復(fù)這條最終的命令即可,其他的數(shù)據(jù)對于整個系統(tǒng)來講都是垃圾數(shù)據(jù)。
set 1001:stock 5000
aof重寫策略如下,如在文件達(dá)到32m時觸發(fā)一次重寫,在64m時又觸發(fā)一次… 依次類推
auto-aof-rewrite-percentage:100% 觸發(fā)AOF重寫時,文件大小相對于上一次重寫時的百分比閾值
auto-aof-rewrite-min-size:32m 觸發(fā)AOF重寫時,AOF文件的最小大小 //可以通過命令方式設(shè)置
CONFIG SET auto-aof-rewrite-percentage 100
CONFIG SET auto-aof-rewrite-min-size 32mb
除了上面的設(shè)置之外,也可以手動的方式觸發(fā)aof重寫,就是通過執(zhí)行這個 BGREWRITEAOF命令
BGREWRITEAOF
通過aof重寫的方式,減少aof存儲文件的大小,從而提高在數(shù)據(jù)做主從架構(gòu)或者恢復(fù)時的效率
3,rdb和aof優(yōu)缺點(diǎn)
通過上面的分析,接下來可以對rdb和aof二者之前做一個全面的對比。
rdb | aof | |
---|---|---|
實(shí)現(xiàn)方式 | save、bgsave | 原生方式、aof重寫 |
存儲方式 | 二進(jìn)制壓縮存儲 | 文本命令存儲 |
宕機(jī)恢復(fù) | 恢復(fù)速度快 | 恢復(fù)速度慢 |
數(shù)據(jù)安全 | 安全性較低 | 安全性高,最多丟1s數(shù)據(jù) |
啟動優(yōu)先級 | 低,優(yōu)先級低 | 高,優(yōu)先使用 |
主從同步 | 不使用,同步數(shù)據(jù)少 | 使用,可以同步更多數(shù)據(jù) |
在實(shí)際開發(fā)中,也是可以優(yōu)先的考慮使用aof的方式來設(shè)計持久化問題,并且不管是在數(shù)據(jù)做同步上,還是數(shù)據(jù)恢復(fù)上,aof的優(yōu)勢還是占優(yōu),都能獲取到更多的數(shù)據(jù),從而保證系統(tǒng)的高可用。
4,rdb和aof混合持久化
在redis4.0之后,引入了一個新的持久化方式,就是可以讓rdb持久化和aof持久化結(jié)合使用。rdb的優(yōu)點(diǎn)是采用二進(jìn)制存儲,存儲內(nèi)容效,aof的優(yōu)點(diǎn)是存儲的數(shù)據(jù)量多,數(shù)據(jù)丟失量少,因此結(jié)合二者優(yōu)點(diǎn),讓rbd和aof混合持久化。
在使用這個混合持久化之前,分別需要開啟aof持久化和混合持久化的命令。
# 啟用AOF持久化
appendonly yes
# 啟用混合持久化
aof-use-rdb-preamble yes
以aof的維度來講,肯定是想減少文件的容量大小,并且恢復(fù)速度快點(diǎn),以rdb的維度來講,肯定是想多存點(diǎn)數(shù)據(jù),因此根據(jù)這二者維度,可以在aof文件重寫之后,將數(shù)據(jù)轉(zhuǎn)成二進(jìn)制的格式存到文件中,通過這種方式,通過aof來解決數(shù)據(jù)丟失問題,又通過rdb文件格式來減少空間存儲,并且能再宕機(jī)之后更快的恢復(fù)數(shù)據(jù)。
還是通過上面的庫存例子詳細(xì)的說明一下到底什么是混合持久化,首先是開啟aof持久化和混合持久化,其次是開啟aof的重寫功能
auto-aof-rewrite-percentage:100 觸發(fā)AOF重寫時,文件大小相對于上一次重寫時的百分比閾值
auto-aof-rewrite-min-size:32m 觸發(fā)AOF重寫時,AOF文件的最小大小
隨后扣減10次庫存,為了演示這個文件中的數(shù)據(jù),先將 appendonly.aof 文件先清空
truncate -s 0 appendonly.aof
隨后執(zhí)行10條扣減庫存的操作,如下圖,每次對庫存進(jìn)行減1的操作
執(zhí)行完成之后,由于此時并沒有觸發(fā)到aof的重寫機(jī)制,因此需要手動命令進(jìn)行觸發(fā)
BGREWRITEAOF
最后直接查看這個 appendonly.aof 文件,可以發(fā)現(xiàn)有部分的二進(jìn)制文件,有部分的原生命令文件。
就是說那1s的數(shù)據(jù)會通過rdb的二進(jìn)制文件進(jìn)行持久化,在持久化的時候依舊有命令進(jìn)來,那么暫時先用aof文件進(jìn)行存儲,在下一秒又將前一秒的數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制文件存儲,通過這種方式最多也只會丟一秒的數(shù)據(jù)。