我們先來看這么一段面試場(chǎng)景——
面試官:你們項(xiàng)目緩存技術(shù)用到了什么緩存技術(shù)?
小帥:Redis
面試官:那么問一下,Redis緩存技術(shù)用到的持久化機(jī)制是哪一種機(jī)制?
小帥:AOF
面試官:好吧,回去等通知吧……
這個(gè)問題,不知道你在面試的時(shí)候有沒有被別人問過,你是怎么回答的?
其實(shí)不管你怎么回答都是錯(cuò)的,為什么?請(qǐng)往下看。
大家都知道,Redis是我們互聯(lián)網(wǎng)公司必用的架構(gòu)技術(shù),在我們業(yè)內(nèi)稱之為高性能緩存數(shù)據(jù)庫(kù),那么既然是緩存,我們的系統(tǒng)、服務(wù)器一斷電或重啟的時(shí)候,它的數(shù)據(jù)一定會(huì)丟失,所以,在丟失的這個(gè)過程中,在丟失之前,Redis做了一套持久化機(jī)制。
我們往Redis插數(shù)據(jù)的時(shí)候,這個(gè)數(shù)據(jù)會(huì)同步一份保存到磁盤,而保存到磁盤有兩種方式,對(duì)應(yīng)兩種數(shù)據(jù)文件格式:AOF和RDB這兩種文件,在Redis從斷電到開機(jī)的瞬間都可以讓我們的數(shù)據(jù)從磁盤恢復(fù)到Redis。那么問題來了,小帥要回答面試官講的這個(gè)問題,其實(shí)是要搞明白AOF和RDB兩者的區(qū)別。RDB是Redis的一個(gè)快照文件,那什么叫快照?比如說現(xiàn)在的時(shí)間是下午14:00,Redis做了一次快照的備份,把這個(gè)數(shù)據(jù)備份到了RDB,那么這個(gè)RDB文件的數(shù)據(jù)就只停留在下午兩點(diǎn),下午兩點(diǎn)以后的數(shù)據(jù)RDB是沒有的,因?yàn)樗喈?dāng)于一個(gè)冷備,備份的時(shí)間只停留在下午兩點(diǎn)鐘這個(gè)時(shí)刻的快照。所以,你如果回答的是RDB,它的數(shù)據(jù)一定會(huì)有丟失。除了RDB,第二個(gè)方式就是剛才小帥回答的AOF,那AOF有什么問題呢?當(dāng)我們往Redis里不斷插入數(shù)據(jù),它會(huì)以日志的方式追加(Append)到AOF文件里,也就是說AOF里面記錄了很多這種原始的操作語(yǔ)句,比如說set、hset等等,當(dāng)我們使用AOF恢復(fù)數(shù)據(jù)到Redis的時(shí)候,它會(huì)重新執(zhí)行一遍我們之前操作的所有操作語(yǔ)句。以上三條語(yǔ)句都追加到了AOF文件里,很明顯,此刻如果我們執(zhí)行g(shù)et name,Redis返回的是“佛波勒”,那么問題來了,AOF存了這么多過程化的數(shù)據(jù),或者說是中間數(shù)據(jù),它的意義在哪里?因?yàn)樽罱KRedis恢復(fù)的時(shí)候最終的數(shù)據(jù)是“佛波勒”,哪怕Redis把前兩條數(shù)據(jù)恢復(fù)了,在最后name被恢復(fù)的時(shí)候,也會(huì)被“佛波勒”覆蓋,所以前兩條數(shù)據(jù)是不可取的,浪費(fèi)了我們的空間,那樣咱們的AOF文件會(huì)越變?cè)酱蟆?/span>所以Redis是怎么做的呢,AOF里還有個(gè)技術(shù)叫Rewrite壓縮重寫,當(dāng)我們的AOF文件不斷變大的時(shí)候,比如我們?cè)O(shè)置的閥值是64M,當(dāng)AOF文件第一次到達(dá)64M的時(shí)候,Redis會(huì)自動(dòng)觸發(fā)一次Rewrite操作,將AOF文件進(jìn)行一次瘦身。接下來,我們?cè)賮韺?duì)比RDB和AOF的優(yōu)缺點(diǎn)。在指定的時(shí)間間隔內(nèi)將內(nèi)存中的數(shù)據(jù)集快照寫入磁盤,實(shí)際操作過程是fork一個(gè)子進(jìn)程,先將數(shù)據(jù)集寫入臨時(shí)文件,寫入成功后,再替換之前的文件,用二進(jìn)制壓縮存儲(chǔ)。- 整個(gè)Redis數(shù)據(jù)庫(kù)將只包含一個(gè)文件 dump.rdb,方便持久化
- 性能最大化,fork子進(jìn)程來完成寫操作,讓主進(jìn)程繼續(xù)處理命令,所以是IO最大化,使用單獨(dú)的子進(jìn)程來進(jìn)行持久化,主進(jìn)程不會(huì)進(jìn)行任何IO操作,保證了Redis的高性能
- 相對(duì)于數(shù)據(jù)集大時(shí),比AOF的啟動(dòng)效率更高
- 數(shù)據(jù)安全性低。RDB 是間隔一段時(shí)間進(jìn)行持久化,如果持久化之間redis 發(fā)生故障,會(huì)發(fā)生數(shù)據(jù)丟失,所以這種方式更適合用于數(shù)據(jù)要求不嚴(yán)謹(jǐn)?shù)膱?chǎng)景
- 由于RDB是通過fork子進(jìn)程來協(xié)助完成數(shù)據(jù)持久化工作的,因此,如果當(dāng)數(shù)據(jù)集較大時(shí),可能會(huì)導(dǎo)致整個(gè)服務(wù)器停止服務(wù)幾百毫秒,甚至是1秒鐘
以日志的形式記錄服務(wù)器所處理的每一個(gè)寫、刪除操作,查詢操作不會(huì)記錄,以文本的方式記錄,可以打開文件看到詳細(xì)的操作記錄。- 數(shù)據(jù)安全,Redis中提供了3種同步策略,即每秒同步、每修改同步和不同步。事實(shí)上,每秒同步也是異步完成的,其效率也是非常高的,所差的是一旦系統(tǒng)出現(xiàn)宕機(jī)現(xiàn)象,那么這一秒鐘之內(nèi)修改的數(shù)據(jù)將會(huì)丟失,而每修改同步,我們可以將其視為同步持久化,即每次發(fā)生的數(shù)據(jù)變化都會(huì)被立即記錄到磁盤中
- 通過append模式寫文件,即使中途服務(wù)器宕機(jī)也不會(huì)破壞已經(jīng)存在的內(nèi)容,可以通過redis-check-aof工具解決數(shù)據(jù)一致性問題
- AOF機(jī)制的rewrite模式。定期對(duì)AOF文件進(jìn)行重寫,以達(dá)到壓縮的目的
- AOF 文件比 RDB 文件大,且恢復(fù)速度慢
- 數(shù)據(jù)集大的時(shí)候,比rdb 啟動(dòng)效率低
AOF文件比RDB更新頻率高,優(yōu)先使用AOF還原數(shù)據(jù)。說到底,面試官是在考察你對(duì)Redis的持久化機(jī)制的掌握程度,只要你了解了RDB與AOF的作用與優(yōu)缺點(diǎn),如何組織語(yǔ)言應(yīng)對(duì)面試就再容易不過了。
從架構(gòu)演進(jìn)的角度看,為了降低單個(gè)系統(tǒng)的復(fù)雜度,我們引入了分布式系統(tǒng)架構(gòu),這樣一來,單個(gè)系統(tǒng)的復(fù)雜度就轉(zhuǎn)移到了系統(tǒng)外部——各種中間件,Redis就是其中一個(gè)。技術(shù)/業(yè)務(wù)復(fù)雜度不會(huì)憑空產(chǎn)生,也不會(huì)憑空消失,只會(huì)從一個(gè)地方轉(zhuǎn)移到另一個(gè)地方(就像物理學(xué)的能量守恒定律一樣),我們稱之為復(fù)雜度轉(zhuǎn)移。
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號(hào)
好文章,我在看??