一、Redis先執(zhí)行指令,再記錄AOF日志的原因
Redis是一種內(nèi)存數(shù)據(jù)庫(kù),對(duì)于大多數(shù)的操作,Redis會(huì)先將請(qǐng)求寫(xiě)入內(nèi)存中的數(shù)據(jù)結(jié)構(gòu),然后再異步地將修改同步到磁盤(pán)上的AOF(Append-Only File)文件中,這就是非常高效的原因。Redis的性能很大程度上取決于CPU的速度和內(nèi)存的大小。因此,Redis選擇將大部分?jǐn)?shù)據(jù)保存在內(nèi)存中,以提高運(yùn)行速度。Redis 的數(shù)據(jù)是存內(nèi)存的,斷電之后就丟了。Redis 的 AOF / RDB 相當(dāng)于有一個(gè)把硬盤(pán)當(dāng)內(nèi)存的 slave。存儲(chǔ)引擎數(shù)據(jù)是存硬盤(pán)的,斷電之后,可能有臟數(shù)據(jù),也可能沒(méi)有,需要 redo log / undo log 來(lái)做原子 commit。保護(hù) commit 的數(shù)據(jù)是不可能在 commit 之后寫(xiě)的。存儲(chǔ)引擎的日志只保護(hù) uncommitted data。
二、Redis 在 Java Web 中的應(yīng)用
1、緩存
在日常對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)中,讀操作的次數(shù)遠(yuǎn)超寫(xiě)操作,比例大概在?1:9?到?3:7,所以需要讀的可能性是比寫(xiě)的可能大得多的。當(dāng)我們使用SQL語(yǔ)句去數(shù)據(jù)庫(kù)進(jìn)行讀寫(xiě)操作時(shí),數(shù)據(jù)庫(kù)就會(huì)去磁盤(pán)把對(duì)應(yīng)的數(shù)據(jù)索引取回來(lái),這是一個(gè)相對(duì)較慢的過(guò)程。
如果我們把數(shù)據(jù)放在 Redis 中,也就是直接放在內(nèi)存之中,讓服務(wù)端直接去讀取內(nèi)存中的數(shù)據(jù),那么這樣速度明顯就會(huì)快上不少,并且會(huì)極大減小數(shù)據(jù)庫(kù)的壓力,但是使用內(nèi)存進(jìn)行數(shù)據(jù)存儲(chǔ)開(kāi)銷(xiāo)也是比較大的,限于成本的原因,一般我們只是使用 Redis 存儲(chǔ)一些常用和主要的數(shù)據(jù),比如用戶登錄的信息等。
一般而言在使用 Redis 進(jìn)行存儲(chǔ)的時(shí)候,我們需要從以下幾個(gè)方面來(lái)考慮:
**業(yè)務(wù)數(shù)據(jù)常用嗎?命中率如何?**如果命中率很低,就沒(méi)有必要寫(xiě)入緩存;**該業(yè)務(wù)數(shù)據(jù)是讀操作多,還是寫(xiě)操作多?**如果寫(xiě)操作多,頻繁需要寫(xiě)入數(shù)據(jù)庫(kù),也沒(méi)有必要使用緩存;**業(yè)務(wù)數(shù)據(jù)大小如何?**如果要存儲(chǔ)幾百兆字節(jié)的文件,會(huì)給緩存帶來(lái)很大的壓力,這樣也沒(méi)有必要。在考慮了這些問(wèn)題之后,如果覺(jué)得有必要使用緩存,那么就使用它。
當(dāng)名列前茅次讀取數(shù)據(jù)的時(shí)候,讀取 Redis 的數(shù)據(jù)就會(huì)失敗,此時(shí)就會(huì)觸發(fā)程序讀取數(shù)據(jù)庫(kù),把數(shù)據(jù)讀取出來(lái),并且寫(xiě)入 Redis 中;當(dāng)?shù)诙我约耙院笮枰x取數(shù)據(jù)時(shí),就會(huì)直接讀取 Redis,讀到數(shù)據(jù)后就結(jié)束了流程,這樣速度就大大提高了。從上面的分析可以知道,讀操作的可能性是遠(yuǎn)大于寫(xiě)操作的,所以使用 Redis 來(lái)處理日常中需要經(jīng)常讀取的數(shù)據(jù),速度提升是顯而易見(jiàn)的,同時(shí)也降低了對(duì)數(shù)據(jù)庫(kù)的依賴,使得數(shù)據(jù)庫(kù)的壓力大大減少。
分析了讀操作的邏輯,下面我們來(lái)看看寫(xiě)操作的流程:
從流程可以看出,更新或者寫(xiě)入的操作,需要多個(gè) Redis 的操作,如果業(yè)務(wù)數(shù)據(jù)寫(xiě)次數(shù)遠(yuǎn)大于讀次數(shù)那么就沒(méi)有必要使用 Redis。
2、高速讀/寫(xiě)的場(chǎng)合
在如今的互聯(lián)網(wǎng)中,越來(lái)越多的存在高并發(fā)的情況,比如天貓雙11、搶紅包、搶演唱會(huì)門(mén)票等,這些場(chǎng)合都是在某一個(gè)瞬間或者是某一個(gè)短暫的時(shí)刻有成千上萬(wàn)的請(qǐng)求到達(dá)服務(wù)器,如果單純的使用數(shù)據(jù)庫(kù)來(lái)進(jìn)行處理,就算不崩,也會(huì)很慢的,輕則造成用戶體驗(yàn)極差用戶量流失,重則數(shù)據(jù)庫(kù)癱瘓,服務(wù)宕機(jī),而這樣的場(chǎng)合都是不允許的。所以我們需要使用 Redis 來(lái)應(yīng)對(duì)這樣的高并發(fā)需求的場(chǎng)合,我們先來(lái)看看一次請(qǐng)求操作的流程圖:
我們來(lái)進(jìn)一步闡述這個(gè)過(guò)程:
當(dāng)一個(gè)請(qǐng)求到達(dá)服務(wù)器時(shí),只是把業(yè)務(wù)數(shù)據(jù)在 Redis 上進(jìn)行讀寫(xiě),而沒(méi)有對(duì)數(shù)據(jù)庫(kù)進(jìn)行任何的操作,這樣就能大大提高讀寫(xiě)的速度,從而滿足高速響應(yīng)的需求;但是這些緩存的數(shù)據(jù)仍然需要持久化,也就是存入數(shù)據(jù)庫(kù)之中,所以在一個(gè)請(qǐng)求操作完 Redis 的讀/寫(xiě)之后,會(huì)去判斷該高速讀/寫(xiě)的業(yè)務(wù)是否結(jié)束,這個(gè)判斷通常會(huì)在秒殺商品為0,紅包金額為0時(shí)成立,如果不成立,則不會(huì)操作數(shù)據(jù)庫(kù);如果成立,則觸發(fā)事件將 Redis 的緩存的數(shù)據(jù)以批量的形式一次性寫(xiě)入數(shù)據(jù)庫(kù),從而完成持久化的工作。三、AOF簡(jiǎn)介
1、AOF持久化方式
AOF持久化方式是將redis的操作日志以追加的方式寫(xiě)入磁盤(pán)文件中。AOF持久化是以日志的形式記錄服務(wù)器所處理的每一個(gè)寫(xiě)、刪除操作,查詢操作不會(huì)記錄,以文本的方式記錄,可以打開(kāi)文件看到詳細(xì)的操作記錄。
2、AOF實(shí)現(xiàn)方式
AOF(append only file)持久化是以獨(dú)立日志的方式記錄每次寫(xiě)命令,重啟時(shí)再重新執(zhí)行AOF文件中命令達(dá)到恢復(fù)數(shù)據(jù)的目的。AOF的主要作用是解決了數(shù)據(jù)持久化的實(shí)時(shí)性,目前已經(jīng)是Redis持久化的主流方式。
3、AOF優(yōu)勢(shì)
該機(jī)制可以帶來(lái)更高的數(shù)據(jù)安全性,即數(shù)據(jù)持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。
每秒同步:事實(shí)上,每秒同步也是異步完成的,其效率也是非常高的,所差的是一旦系統(tǒng)出現(xiàn)宕機(jī)現(xiàn)象,那么這一秒鐘之內(nèi)修改的數(shù)據(jù)將會(huì)丟失。每次修改:而每修改同步,我們可以將其視為同步持久化,即每次發(fā)生的數(shù)據(jù)變化都會(huì)被立即記錄到磁盤(pán)中。不同步:可以預(yù)見(jiàn),這種方式在效率上是最低的。至于無(wú)同步,無(wú)需多言,我想大家都能正確的理解它。由于該機(jī)制對(duì)日志文件的寫(xiě)入操作采用的是append模式,因此在寫(xiě)入過(guò)程中即使出現(xiàn)宕機(jī)現(xiàn)象,也不會(huì)破壞日志文件中已經(jīng)存在的內(nèi)容。如果我們本次操作只是寫(xiě)入了一半數(shù)據(jù)就出現(xiàn)了系統(tǒng)崩潰問(wèn)題,不用擔(dān)心,在Redis下一次啟動(dòng)之前,我們可以通過(guò)redis-check-aof工具來(lái)幫助我們解決數(shù)據(jù)一致性的問(wèn)題。
如果日志過(guò)大,Redis可以自動(dòng)啟用rewrite機(jī)制,壓縮和瘦身相關(guān)的aof文件。Redis以append模式不斷的將修改數(shù)據(jù)寫(xiě)入到老的磁盤(pán)文件中,同時(shí)Redis還會(huì)創(chuàng)建一個(gè)臨時(shí)的新文件用于記錄此期間有哪些修改命令被執(zhí)行。因此在進(jìn)行rewrite切換時(shí)可以更好的保證數(shù)據(jù)安全性。
延伸閱讀1:AOF重寫(xiě)機(jī)制
隨著命令不斷寫(xiě)入AOF,文件會(huì)越來(lái)越大,為了解決這個(gè)問(wèn)題,Redis引入了AOF重寫(xiě)機(jī)制壓縮文件體積。AOF文件重寫(xiě)是把Redis進(jìn)程內(nèi)的數(shù)據(jù)轉(zhuǎn)化為寫(xiě)命令同步到新AOF文件的過(guò)程。