引言
今天周末埂息,我在家坐著掐指一算,馬上又要到一年一度的金九銀十招聘季了遥巴,國(guó)內(nèi)今年上半年受到 YQ 沖擊千康,金三銀四泡湯了,這就直接導(dǎo)致很多今年畢業(yè)的同學(xué)會(huì)和明年畢業(yè)的同學(xué)一起參加今年下半年的秋招铲掐,這個(gè)競(jìng)爭(zhēng)就比較激烈了拾弃。
最近后臺(tái)有一些朋友給我留言,希望我能寫寫招聘相關(guān)的內(nèi)容迹炼,畢竟雖然說(shuō)是金九銀十,但是很多大公司的校招從 7 颠毙、 8 月份就開始了斯入。
本來(lái)是想寫點(diǎn)面試技巧和簡(jiǎn)歷技巧的,但我轉(zhuǎn)念一想蛀蜜,大家都是搞技術(shù)的刻两,問(wèn)題的核心還是技術(shù)能力要過(guò)關(guān),面試技巧這東西最多只能用作錦上添花滴某,而技術(shù)能力過(guò)不去磅摹,機(jī)會(huì)送到手里都抓不住。
再說(shuō)簡(jiǎn)歷這件事兒霎奢,說(shuō)實(shí)話户誓,這個(gè)不是短時(shí)間內(nèi)能進(jìn)行彌補(bǔ)的,之前我也有文章分享過(guò)我是怎么挑簡(jiǎn)歷的幕侠,無(wú)外乎先看學(xué)校帝美,再參考下實(shí)習(xí)公司,項(xiàng)目經(jīng)驗(yàn)這一欄就看心情了晤硕。
尤其是校招悼潭,學(xué)校放在第一位庇忌,在金礦里淘金子肯定要比在沙堆上淘金子效率高得多,當(dāng)然舰褪,如有能有大廠的實(shí)習(xí)經(jīng)驗(yàn)皆疹,也會(huì)成為簡(jiǎn)歷上的一個(gè)亮點(diǎn),能去大廠實(shí)習(xí)占拍,不管最后什么原因沒有留下略就,本身已經(jīng)可以說(shuō)明很多問(wèn)題了。
MD 刷喜,老說(shuō)實(shí)話残制,實(shí)話這么講下去得罪的人有點(diǎn)多啊。
當(dāng)然哈掖疮,如果這兩樣都沒有出彩的地方初茶,就只能在項(xiàng)目經(jīng)驗(yàn)上下點(diǎn)功夫了,在 Github 上多找找能拿來(lái)練手的項(xiàng)目浊闪,多動(dòng)動(dòng)手恼布,動(dòng)起來(lái)總比整天怨天尤人要來(lái)的強(qiáng)。
第一份工作可以找的不好搁宾,至少先混口飯吃折汞,在工作中再接著學(xué)習(xí),夯實(shí)自己的基礎(chǔ)盖腿,做個(gè)兩三年工作還是可以換的嘛爽待。
Redis 安裝
扯遠(yuǎn)了,強(qiáng)行扯回來(lái)翩腐,我思來(lái)想去還是用 Redis 開頭鸟款,就是因?yàn)檫@玩意使用頻率以及使用場(chǎng)景太多了,不管什么語(yǔ)言茂卦,做什么方向何什,最終都能和 Redis 扯上關(guān)系(emmm,扯不上的我也能強(qiáng)行扯上)等龙。
先簡(jiǎn)單介紹下我認(rèn)為的本地最簡(jiǎn)安裝方案处渣,這個(gè)方案順便還實(shí)現(xiàn)了跨平臺(tái)(一開始我并沒有想到這個(gè),直到我寫到這才忽然想起來(lái))蛛砰。
Docker + Redis
罐栈,Docker 在各個(gè)平臺(tái)都有自己的安裝包,請(qǐng)各位同學(xué)去官網(wǎng)自行下載安裝,我就不多介紹了, Windows 環(huán)境下官網(wǎng)提供了現(xiàn)成的 exe
程序酣衷,直接雙擊一路 next
到底就完记罚。
Docker
安裝成功后浅妆,不管在哪個(gè)平臺(tái)都是打開命令行模式望迎,或者找個(gè)輸入命令的地方,Windows 平臺(tái)下可以使用 CMD
凌外、 PowerShell
或者 Windows Terminal
等工具辩尊,其他常見平臺(tái)包括 MacOS 、 CentOS 或者 Ubuntu 康辑,就不用我多說(shuō)了吧摄欲,如果自己找不到的話,我估摸著我也找不到疮薇。
然后用下面三個(gè)命令安裝 Redis :
# 下載最新版本 Redis 鏡像
docker pull redis
# 查看當(dāng)前鏡像
docker images
# 啟動(dòng)命令
docker run --name redis -p 6380:6379 -d redis:latest --requirepass "02wKdSs7NvWT5TdlRyN4dxkXvIDnI1uroh5t"
# 查看運(yùn)行容器
docker ps
# 進(jìn)入容器
docker exec -it 013a252b24d6 redis-cli
稍微解釋下容器的啟動(dòng)命令 --name
是對(duì)這個(gè)啟動(dòng)的容器進(jìn)行命名胸墙, -p
是指定映射的端口, -d
是指后臺(tái)運(yùn)行容器按咒,并返回容器的 ID 迟隅, --requirepass
是指定了當(dāng)前啟動(dòng)的 Redis 的訪問(wèn)密碼。
然后一個(gè) Redis 就啟動(dòng)好了励七,我們進(jìn)入容器執(zhí)行幾條命令看下是否正常:
# 使用剛才設(shè)置的密碼登錄
127.0.0.1:6379> auth 02wKdSs7NvWT5TdlRyN4dxkXvIDnI1uroh5t
OK
# 寫入一個(gè) key-value
127.0.0.1:6379> set name geekdigging
OK
# 查詢 key
127.0.0.1:6379> get name
"geekdigging"
# 查詢所有 key
127.0.0.1:6379> keys *
1) "name"
# 刪除 key
127.0.0.1:6379> del name
(integer) 1
# 查詢所有 key
127.0.0.1:6379> keys *
(empty array)
# 退出
127.0.0.1:6379> quit
Redis 入門結(jié)束智袭,看完這一段,在簡(jiǎn)歷上寫個(gè) Redis 達(dá)到了解級(jí)別我覺得木有任何問(wèn)題掠抬。
基礎(chǔ)知識(shí)
既然是從面試出發(fā)吼野,那么接下來(lái)的內(nèi)容將會(huì)以面試題為導(dǎo)向進(jìn)行解答,面試題來(lái)源于網(wǎng)絡(luò)或者我自己的杜撰两波。
為什么在項(xiàng)目中使用 Redis 瞳步?
現(xiàn)在基本上只要問(wèn)到緩存,第一個(gè)問(wèn)題基本上都是哪里用了緩存腰奋?為啥要用单起?不用行不行?用了以后會(huì)不會(huì)有什么風(fēng)險(xiǎn)氛堕?
就是單純的看你背后對(duì)緩存有沒有思考馏臭,還是說(shuō)只是單純的傻乎乎的用野蝇。如果沒辦法給一個(gè)還可以的回答讼稚,那這個(gè)映像分一下就降下來(lái)了。
首先哈绕沈,我們?cè)陧?xiàng)目中使用 Redis 肯定是為了更高的性能和更好的并發(fā)锐想。因?yàn)閭鹘y(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)已經(jīng)無(wú)法滿足現(xiàn)在所有的使用場(chǎng)景了,最常見的秒殺場(chǎng)景乍狐,或者查詢時(shí)的流量洪峰等等赠摇,都很容易把傳統(tǒng)的 MySQL 或者是 Oracle 打崩,所以引入了緩存中間件 Redis 。
高性能:
假設(shè)一個(gè)場(chǎng)景藕帜,一個(gè)請(qǐng)求過(guò)來(lái)烫罩,開始查詢數(shù)據(jù)庫(kù),亂七八糟一頓 SQL 操作洽故,查了個(gè)結(jié)果贝攒,結(jié)果耗時(shí)可能有個(gè) 500ms 左右,就比如商城的首頁(yè)时甚,各種類目的商品信息隘弊,各種推薦信息,如果走數(shù)據(jù)庫(kù)查詢荒适,并且查完了可能接下來(lái)好幾個(gè)小時(shí)都沒什么變化梨熙,那每次請(qǐng)求都走到數(shù)據(jù)庫(kù)里,就有點(diǎn)不大合適了刀诬。
這時(shí)咽扇,我們把查到的結(jié)果放到扔到緩存里面,下次再來(lái)查詢舅列,不走數(shù)據(jù)庫(kù)肌割,直接走緩存查詢,算上網(wǎng)絡(luò)消耗可能 10ms 左右就能響應(yīng)結(jié)果了帐要,性能瞬間提升 50 倍把敞。
這就是說(shuō),對(duì)于一些需要復(fù)雜操作耗時(shí)查出來(lái)的結(jié)果榨惠,且確定后面不怎么變化奋早,但是有很多讀請(qǐng)求,那么直接將查詢出來(lái)的結(jié)果放在緩存中赠橙,后面直接讀緩存就好了耽装。
高并發(fā):
MySQL 或者 Oracle 這種關(guān)系型數(shù)據(jù)庫(kù)壓根就不是用來(lái)玩并發(fā)的,雖然也可以支撐一定的并發(fā)期揪,單機(jī) 8C16G 的 MySQL 優(yōu)化基本上極限能撐到 900 左右的 TPS 掉奄, QPS 極限能撐到 9000 左右。別看這個(gè)數(shù)字不小凤薛,請(qǐng)注意是極限情況姓建,這個(gè)情況下 CPU 全都已經(jīng)爆表,整個(gè)服務(wù)已經(jīng)處于不健康的狀態(tài)缤苫。
這時(shí)業(yè)務(wù)場(chǎng)景如果 1s 有 1w 的請(qǐng)求過(guò)來(lái)速兔,使用一個(gè) MySQL 單機(jī)肯定直接崩掉,但是如果使用 Redis 緩存活玲,把大量的熱點(diǎn)數(shù)據(jù)放在緩存涣狗,因?yàn)槭亲邇?nèi)存的操作谍婉,單機(jī)輕松支撐幾萬(wàn)甚至于幾十萬(wàn)的訪問(wèn)。單機(jī)的并發(fā)承載量是 MySQL 的幾十倍镀钓。
除了 Redis 還有考慮過(guò)其他緩存么穗熬?
這個(gè)問(wèn)題實(shí)際上是在問(wèn)知識(shí)廣度,因?yàn)楝F(xiàn)在市面上比較常見的緩存有兩個(gè)丁溅,一個(gè)是 Redis 還有一個(gè)是 Memcached 死陆,而大家現(xiàn)在基本上都在用 Redis 而逐漸的拋棄掉了 Memcached ,這么做肯定是由原因的唧瘾,說(shuō)明 Memcached 是存在明顯的短板的措译。
- Redis 相比較 Memcached 而言,它支持更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)饰序,能支持更豐富的數(shù)據(jù)操作领虹。
- Redis 在 3.x 版本以后,原生支持了集群模式求豫,而 Memcached 沒有原生的集群模式塌衰,需要依靠客戶端來(lái)實(shí)現(xiàn)往集群中分片寫入數(shù)據(jù)。
- Redis 擁有更加豐富的附加功能蝠嘉,如:pub/sub 功能最疆, Lua 腳本支持, 序列化支持等等蚤告。
- Redis 支持?jǐn)?shù)據(jù)持久化努酸, RDB 和 AOF。
Redis 的線程模型是什么杜恰?為什么 Redis 單線程卻能支撐高并發(fā)获诈?
這兩個(gè)問(wèn)題我放在一起,實(shí)際上是一個(gè)遞進(jìn)的關(guān)系心褐。
首先明確第一點(diǎn)舔涎, Redis 是單線程的模型。
而單線程卻能擁有很好的性能以及支撐高并發(fā)則得益于它自身的另一套機(jī)制「 I/O 多路復(fù)用機(jī)制」逗爹。
Redis 內(nèi)部使用文件事件處理器( file event handler
) 是單線程的亡嫌,所以 Redis 才叫做單線程的模型。
它采用 IO 多路復(fù)用機(jī)制同時(shí)監(jiān)聽多個(gè) socket 掘而,將產(chǎn)生事件的 socket 壓入內(nèi)存隊(duì)列中挟冠,事件分派器根據(jù) socket 上的事件類型來(lái)選擇對(duì)應(yīng)的事件處理器進(jìn)行處理。
盡管多個(gè)文件事件操作可能會(huì)并發(fā)的出現(xiàn)镣屹,但 I/O 多路復(fù)用系統(tǒng)總是會(huì)將所有產(chǎn)生的套接字( Socket ) 放到一個(gè)隊(duì)列里面圃郊,然后通過(guò)這個(gè)隊(duì)列价涝,以有序女蜈、同步、每次一個(gè)套接字的方式向文件分派器傳送套接字。只有當(dāng)上一個(gè)套接字產(chǎn)生的事件被處理完畢之后伪窖, I/O 多路復(fù)用系統(tǒng)才會(huì)繼續(xù)向文件分派器傳送下一個(gè)套接字逸寓。
同時(shí),單線程的模型反而帶來(lái)了另一個(gè)好處是無(wú)需頻繁的切換上下文覆山,預(yù)防了多線程可能產(chǎn)生的競(jìng)爭(zhēng)問(wèn)題竹伸。
注意: Redis 6.0 之后的版本拋棄了單線程模型這一設(shè)計(jì),原本使用單線程運(yùn)行的 Redis 也開始選擇性地使用多線程模型簇宽。
前面還在強(qiáng)調(diào) Redis 單線程模型的高效性勋篓,現(xiàn)在為什么又要引入多線程?這其實(shí)說(shuō)明 Redis 在有些方面魏割,單線程已經(jīng)不具有優(yōu)勢(shì)了譬嚣。因?yàn)樽x寫網(wǎng)絡(luò)的 Read/Write 系統(tǒng)調(diào)用在 Redis 執(zhí)行期間占用了大部分 CPU 時(shí)間,如果把網(wǎng)絡(luò)讀寫做成多線程的方式對(duì)性能會(huì)有很大提升钞它。
Redis 的多線程部分只是用來(lái)處理網(wǎng)絡(luò)數(shù)據(jù)的讀寫和協(xié)議解析拜银,執(zhí)行命令仍然是單線程。 之所以這么設(shè)計(jì)是不想 Redis 因?yàn)槎嗑€程而變得復(fù)雜遭垛,需要去控制 key尼桶、lua、事務(wù)锯仪、LPUSH/LPOP 等等的并發(fā)問(wèn)題泵督。
Redis 的數(shù)據(jù)結(jié)構(gòu)有哪些呀?
首先最基礎(chǔ)的五種數(shù)據(jù)結(jié)構(gòu)必須爛熟于心:String 庶喜、 Hash 幌蚊、 List 、 Set 溃卡、 SortedSet 溢豆。
如果連這五種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)都記不住的話那就真的需要自己多補(bǔ)補(bǔ)課了。
那么瘸羡,是不是只有這五種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)漩仙,答案并不是,比如在 2.8.9 版本添加的 HyperLogLog 犹赖,或者在 3.2 版本提供的 GEO 队他,又或者在 2.2 版本后新增的 Bitmap 以及在比較近的 5.0 版本新增的 Stream 。
- HyperLogLog: 基數(shù)統(tǒng)計(jì)峻村,這個(gè)結(jié)構(gòu)可以非常省內(nèi)存的去統(tǒng)計(jì)各種計(jì)數(shù)麸折,比如注冊(cè) IP 數(shù)、每日訪問(wèn) IP 數(shù)粘昨、頁(yè)面實(shí)時(shí)UV)垢啼、在線用戶數(shù)等窜锯。但是它也有局限性,就是只能統(tǒng)計(jì)數(shù)量芭析,而沒辦法去知道具體的內(nèi)容是什么锚扎。
- GEO: 這個(gè)功能可以將用戶給定的地理位置信息儲(chǔ)存起來(lái), 并對(duì)這些信息進(jìn)行操作馁启。
- Bitmap: BitMap 就是通過(guò)一個(gè) bit 位來(lái)表示某個(gè)元素對(duì)應(yīng)的值或者狀態(tài), 其中的 key 就是對(duì)應(yīng)元素本身驾孔,實(shí)際上底層也是通過(guò)對(duì)字符串的操作來(lái)實(shí)現(xiàn)。
- Stream: 從功能層面來(lái)講惯疙, Streams 加上它的指令實(shí)現(xiàn)了一個(gè)完備的分布式消息隊(duì)列翠勉。
上面這幾種種數(shù)據(jù)結(jié)構(gòu)都不復(fù)雜,大家百度下看看文章就能和面試官吹牛皮了霉颠。
能答出來(lái)后面這幾種數(shù)據(jù)類型眉菱,基本上面試官都會(huì)對(duì)你另眼相看,如果還能接著說(shuō)出來(lái)使用場(chǎng)景以及具體應(yīng)用掉分,那么這道題基本上你的發(fā)揮已經(jīng)超出了面試官的預(yù)期俭缓。
這時(shí)你還可以接著聊下去,比如你還用過(guò)一些 Redis 的第三方模塊酥郭,這個(gè)是 Redis 在 4.0 版本以后提供了插件功能华坦,比如非常常用的一個(gè)插件布隆過(guò)濾器「 BloomFilter 」。
布隆過(guò)濾器主要是用來(lái)去重使用的不从,在空間上可以節(jié)省 90% 以上惜姐,但是稍微有點(diǎn)不精確,有一定的誤判概率椿息〈踉可以簡(jiǎn)單的把布隆過(guò)濾器理解成一個(gè)不怎么精確的 set 結(jié)構(gòu),當(dāng)使用它的 contains 方案判斷某個(gè)對(duì)象是否存在時(shí)寝优,它可能會(huì)誤判条舔。但是布隆過(guò)濾器也不是特別不精確,只要參數(shù)設(shè)置的合理乏矾,它的精確度也可以控制的相對(duì)足夠精確孟抗,只會(huì)有小小的誤判概率。
除了 「BloomFilter」 钻心,還有一些比較常用的凄硼,如: 「RedisSearch」 和 「rediSQL」 。
「RedisSearch」 是一個(gè)強(qiáng)大全文檢索插件而 「rediSQL」 則是一個(gè)使得 Redis 能使用 SQL 做查詢的插件捷沸。
Redis 的持久化有哪幾種方式摊沉?
Redis 數(shù)據(jù)持久化有兩種方式: RDB 和 AOF 。
- RDB:RDB 持久化機(jī)制痒给,是對(duì) Redis 中的數(shù)據(jù)執(zhí)行定期的持久化说墨。
- AOF: AOF 機(jī)制對(duì)每條寫入命令作為日志骏全,以
append-only
的模式寫入一個(gè)日志文件中,在 Redis 重啟的時(shí)候婉刀,可以通過(guò)回放 AOF 日志中的寫入指令來(lái)重新構(gòu)建整個(gè)數(shù)據(jù)集。
通過(guò) RDB 或者 AOF 序仙,都可以將 Redis 內(nèi)存中的數(shù)據(jù)持久化到硬盤上面突颊,如果有需要,還可以將硬盤上的數(shù)據(jù)備份到其他地方去潘悼。
如果 Redis 掛了律秃,這時(shí)止不僅 Redis 服務(wù)掛掉,內(nèi)存數(shù)據(jù)丟失治唤,同時(shí)產(chǎn)生硬件損壞棒动,硬盤上的數(shù)據(jù)也丟失或者復(fù)發(fā)恢復(fù),我們還可以從其他地方將數(shù)據(jù)拷貝回來(lái)進(jìn)行數(shù)據(jù)恢復(fù)宾添。
不同的持久化機(jī)制都有什么優(yōu)缺點(diǎn)船惨?
RDB 的優(yōu)缺點(diǎn):
- RDB 持久化既可以通過(guò)手動(dòng)執(zhí)行,也可以通過(guò)配置文件選項(xiàng)定期執(zhí)行缕陕,它可以使得某個(gè)時(shí)間點(diǎn)上的數(shù)據(jù)庫(kù)的狀態(tài)保存到一個(gè) RDB 文件中粱锐。有兩個(gè)命令可以用于生成 RDB 文件,一個(gè)是
save
扛邑,另一個(gè)是bgsave
怜浅。save
命令會(huì)阻塞當(dāng)前的 Redis 進(jìn)程,直到 RDB 文件創(chuàng)建完畢蔬崩,在這期間恶座,服務(wù)器不能處理任何命令請(qǐng)求。而bgsave
則會(huì)派生出一個(gè)子進(jìn)程沥阳,然后由子進(jìn)程生成 RDB 文件跨琳,服務(wù)進(jìn)程不受干擾,繼續(xù)處理命令請(qǐng)求桐罕。 - RDB 會(huì)生成多個(gè)數(shù)據(jù)文件湾宙,每個(gè)數(shù)據(jù)文件都代表了某一個(gè)時(shí)刻中 Redis 的數(shù)據(jù),這種多個(gè)數(shù)據(jù)文件的方式冈绊,非常適合做冷備侠鳄,可以將這種完整的數(shù)據(jù)文件發(fā)送到一些遠(yuǎn)程的安全存儲(chǔ)上去。
- RDB 對(duì) Redis 對(duì)外提供的讀寫服務(wù)死宣,影響非常小伟恶,可以讓 Redis 保持高性能,因?yàn)?Redis 主進(jìn)程只需要 fork 一個(gè)子進(jìn)程毅该,讓子進(jìn)程執(zhí)行磁盤 IO 操作來(lái)進(jìn)行 RDB 持久化即可博秫。
- 相對(duì)于 AOF 持久化機(jī)制來(lái)說(shuō)潦牛,直接基于 RDB 數(shù)據(jù)文件來(lái)重啟和恢復(fù) Redis 進(jìn)程,更加快速挡育。
- 在 Redis 故障時(shí)巴碗,盡可能少的丟失數(shù)據(jù),那么 RDB 沒有 AOF 好即寒。一般來(lái)說(shuō)橡淆,RDB 數(shù)據(jù)快照文件,都是每隔 5 分鐘母赵,或者更長(zhǎng)時(shí)間生成一次逸爵,這個(gè)時(shí)候就得接受一旦 Redis 進(jìn)程宕機(jī),那么會(huì)丟失最近 5 分鐘的數(shù)據(jù)凹嘲。
- RDB 每次在 fork 子進(jìn)程來(lái)執(zhí)行 RDB 快照數(shù)據(jù)文件生成的時(shí)候师倔,如果數(shù)據(jù)文件特別大,可能會(huì)導(dǎo)致對(duì)客戶端提供的服務(wù)暫停數(shù)毫秒周蹭,或者甚至數(shù)秒趋艘。
AOF 的優(yōu)缺點(diǎn):
- AOF 可以更好的保護(hù)數(shù)據(jù)不丟失,一般 AOF 會(huì)每隔 1 秒凶朗,通過(guò)一個(gè)后臺(tái)線程執(zhí)行一次 fsync 操作致稀,最多丟失 1 秒鐘的數(shù)據(jù)。
- AOF 日志文件以
append-only
模式寫入俱尼,所以沒有任何磁盤尋址的開銷抖单,寫入性能非常高,而且文件不容易破損遇八,即使文件尾部破損矛绘,也很容易修復(fù)。 - AOF 日志文件即使過(guò)大的時(shí)候刃永,出現(xiàn)后臺(tái)重寫操作货矮,也不會(huì)影響客戶端的讀寫。因?yàn)樵?
rewrite log
的時(shí)候斯够,會(huì)對(duì)其中的指令進(jìn)行壓縮囚玫,創(chuàng)建出一份需要恢復(fù)數(shù)據(jù)的最小日志出來(lái)。在創(chuàng)建新日志文件的時(shí)候读规,老的日志文件還是照常寫入抓督。當(dāng)新的merge
后的日志文件ready
的時(shí)候,再交換新老日志文件即可束亏。 - AOF 日志文件的命令通過(guò)可讀較強(qiáng)的方式進(jìn)行記錄铃在,這個(gè)特性非常適合做災(zāi)難性的誤刪除的緊急恢復(fù)。
- 對(duì)于同一份數(shù)據(jù)來(lái)說(shuō),AOF 日志文件通常比 RDB 數(shù)據(jù)快照文件更大定铜。
- AOF 開啟后阳液,支持的寫 QPS 會(huì)比 RDB 支持的寫 QPS 低,因?yàn)?AOF 一般會(huì)配置成每秒 fsync 一次日志文件揣炕,當(dāng)然帘皿,每秒一次 fsync ,性能也還是很高的畸陡。(如果實(shí)時(shí)寫入鹰溜,那么 QPS 會(huì)大降,Redis 性能會(huì)大大降低)
- 以前 AOF 發(fā)生過(guò) bug罩锐,就是通過(guò) AOF 記錄的日志奉狈,進(jìn)行數(shù)據(jù)恢復(fù)的時(shí)候卤唉,沒有恢復(fù)一模一樣的數(shù)據(jù)出來(lái)涩惑。所以說(shuō),類似 AOF 這種較為復(fù)雜的基于命令日志 / merge / 回放的方式桑驱,比基于 RDB 每次持久化一份完整的數(shù)據(jù)快照文件的方式竭恬,更加脆弱一些,容易有 bug熬的。不過(guò) AOF 就是為了避免 rewrite 過(guò)程導(dǎo)致的 bug痊硕,因此每次 rewrite 并不是基于舊的指令日志進(jìn)行 merge 的,而是基于當(dāng)時(shí)內(nèi)存中的數(shù)據(jù)進(jìn)行指令的重新構(gòu)建押框,這樣健壯性會(huì)好很多岔绸。
兩種持久化方式選擇:
- 不要僅僅使用 RDB,因?yàn)槟菢訒?huì)導(dǎo)致你丟失很多數(shù)據(jù)橡伞。
- 也不要僅僅使用 AOF盒揉,因?yàn)槟菢佑袃蓚€(gè)問(wèn)題:第一,你通過(guò) AOF 做冷備兑徘,沒有 RDB 做冷備來(lái)的恢復(fù)速度更快刚盈;第二,RDB 每次簡(jiǎn)單粗暴生成數(shù)據(jù)快照挂脑,更加健壯藕漱,可以避免 AOF 這種復(fù)雜的備份和恢復(fù)機(jī)制的 bug。
- Redis 支持同時(shí)開啟開啟兩種持久化方式崭闲,我們可以綜合使用 AOF 和 RDB 兩種持久化機(jī)制肋联,用 AOF 來(lái)保證數(shù)據(jù)不丟失,作為數(shù)據(jù)恢復(fù)的第一選擇; 用 RDB 來(lái)做不同程度的冷備刁俭,在 AOF 文件都丟失或損壞不可用的時(shí)候牺蹄,還可以使用 RDB 來(lái)進(jìn)行快速的數(shù)據(jù)恢復(fù)。
參考
https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/redis-persistence.md