最全Redis49題詳細(xì)答案:線程設(shè)計(jì)+哨兵+復(fù)制+事務(wù)+集群+持久化等

繼續(xù)Java最全面試題答案系列篇,之前分享了mysql、spring、多線程等最全答案,文末有相關(guān)獲取方式哦~

Redis支持哪幾種數(shù)據(jù)類型?

支持多種類型的數(shù)據(jù)結(jié)構(gòu)

1.string:最基本的數(shù)據(jù)類型,二進(jìn)制安全的字符串,最大512M。

2.list:按照添加順序保持順序的字符串列表。

3.set:無序的字符串集合,不存在重復(fù)的元素。

4.sorted set:已排序的字符串集合。

5.hash:key-value對(duì)的一種集合。

Redis主要有哪些功能?

1.哨兵(Sentinel)和復(fù)制(Replication)

Redis服務(wù)器毫無征兆的罷工是個(gè)麻煩事,如何保證備份的機(jī)器是原始服務(wù)器的完整備份呢?這時(shí)候就需要哨兵和復(fù)制。

Sentinel可以管理多個(gè)Redis服務(wù)器,它提供了監(jiān)控,提醒以及自動(dòng)的故障轉(zhuǎn)移的功能,Replication則是負(fù)責(zé)讓一個(gè)Redis服務(wù)器可以配備多個(gè)備份的服務(wù)器。

Redis也是利用這兩個(gè)功能來保證Redis的高可用的

2.事務(wù)

很多情況下我們需要一次執(zhí)行不止一個(gè)命令,而且需要其同時(shí)成功或者失敗。redis對(duì)事務(wù)的支持也是源自于這部分需求,即支持一次性按順序執(zhí)行多個(gè)命令的能力,并保證其原子性。

3.LUA腳本

在事務(wù)的基礎(chǔ)上,如果我們需要在服務(wù)端一次性的執(zhí)行更復(fù)雜的操作(包含一些邏輯判斷),則lua就可以排上用場(chǎng)了

4.持久化

redis的持久化指的是redis會(huì)把內(nèi)存的中的數(shù)據(jù)寫入到硬盤中,在redis重新啟動(dòng)的時(shí)候加載這些數(shù)據(jù),從而最大限度的降低緩存丟失帶來的影響。

5.集群(Cluster)

單臺(tái)服務(wù)器資源的總是有上限的,CPU資源和IO資源我們可以通過主從復(fù)制,進(jìn)行讀寫分離,把一部分CPU和IO的壓力轉(zhuǎn)移到從服務(wù)器上,這也有點(diǎn)類似mysql數(shù)據(jù)庫的主從同步。

在Redis官方的分布式方案出來之前,有twemproxy和codis兩種方案,這兩個(gè)方案總體上來說都是依賴proxy來進(jìn)行分布式的,下面的內(nèi)容有具體集群方案詳解。

Redis是單進(jìn)程單線程的?

Redis是單進(jìn)程單線程的,Redis利用隊(duì)列技術(shù)將并發(fā)訪問變?yōu)榇性L問,消除了傳統(tǒng)數(shù)據(jù)庫串行控制的開銷。

Redis為什么是單線程的?

多線程處理會(huì)涉及到鎖,而且多線程處理會(huì)涉及到線程切換而消耗CPU。因?yàn)镃PU不是Redis的瓶頸,Redis的瓶頸最有可能是機(jī)器內(nèi)存或者網(wǎng)絡(luò)帶寬。單線程無法發(fā)揮多核CPU性能,不過可以通過在單機(jī)開多個(gè)Redis實(shí)例來解決。

其它開源軟件采用的模型

Nginx:多進(jìn)程單線程模型

Memcached:?jiǎn)芜M(jìn)程多線程模型

使用Redis的優(yōu)勢(shì)?

1.速度快,因?yàn)閿?shù)據(jù)存在內(nèi)存中,類似于HashMap,HashMap的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是O(1)

2. 支持豐富數(shù)據(jù)類型,支持string,list,set,sorted set,hash

3.支持事務(wù),操作都是原子性,所謂的原子性就是對(duì)數(shù)據(jù)的更改要么全部執(zhí)行,要么全部不執(zhí)行

4. 豐富的特性:可用于緩存,消息,按key設(shè)置過期時(shí)間,過期后將會(huì)自動(dòng)刪除

Redis單點(diǎn)吞吐量

單點(diǎn)TPS達(dá)到8萬/秒,QPS達(dá)到10萬/秒,補(bǔ)充下TPS和QPS的概念

1.QPS:?應(yīng)用系統(tǒng)每秒鐘最大能接受的用戶訪問量

每秒鐘處理完請(qǐng)求的次數(shù),注意這里是處理完,具體是指發(fā)出請(qǐng)求到服務(wù)器處理完成功返回結(jié)果??梢岳斫庠趕erver中有個(gè)counter,每處理一個(gè)請(qǐng)求加1,1秒后counter=QPS。

2.TPS:?每秒鐘最大能處理的請(qǐng)求數(shù)

每秒鐘處理完的事務(wù)次數(shù),一個(gè)應(yīng)用系統(tǒng)1s能完成多少事務(wù)處理,一個(gè)事務(wù)在分布式處理中,可能會(huì)對(duì)應(yīng)多個(gè)請(qǐng)求,對(duì)于衡量單個(gè)接口服務(wù)的處理能力,用QPS比較合理。

Redis相比memcached有哪些優(yōu)勢(shì)?

1.memcached所有的值均是簡(jiǎn)單的字符串,Redis作為其替代者,支持更為豐富的數(shù)據(jù)類型

2.Redis的速度比memcached快很多

3.Redis可以持久化其數(shù)據(jù)

4.Redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。

Redis有哪幾種數(shù)據(jù)淘汰策略?

在Redis中,允許用戶設(shè)置最大使用內(nèi)存大小server.maxmemory,當(dāng)Redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候,就會(huì)施行數(shù)據(jù)淘汰策略。

1.volatile-lru:從已設(shè)置過期的數(shù)據(jù)集中挑選最近最少使用的淘汰

2.volatile-ttr:從已設(shè)置過期的數(shù)據(jù)集中挑選將要過期的數(shù)據(jù)淘汰

3.volatile-random:從已設(shè)置過期的數(shù)據(jù)集中任意挑選數(shù)據(jù)淘汰

4.allkeys-lru:從數(shù)據(jù)集中挑選最近最少使用的數(shù)據(jù)淘汰

5.allkeys-random:從數(shù)據(jù)集中任意挑選數(shù)據(jù)淘汰

6.noenviction:禁止淘汰數(shù)據(jù)

redis淘汰數(shù)據(jù)時(shí)還會(huì)同步到aof

Redis集群方案應(yīng)該怎么做?都有哪些方案?

1.twemproxy

2.codis,目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在 節(jié)點(diǎn)數(shù)量改變情況下,舊節(jié)點(diǎn)數(shù)據(jù)可恢復(fù)到新hash節(jié)點(diǎn)。

3.Redis cluster3.0自帶的集,特點(diǎn)在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持節(jié)點(diǎn)設(shè)置從節(jié)點(diǎn)。

具體請(qǐng)查看阿里架構(gòu)師進(jìn)階專題:Redis集群的5種使用方式,各自優(yōu)缺點(diǎn)分析

Redis讀寫分離模型

通過增加Slave DB的數(shù)量,讀的性能可以線性增長(zhǎng)。為了避免Master DB的單點(diǎn)故障,集群一般都會(huì)采用兩臺(tái)Master DB做雙機(jī)熱備,所以整個(gè)集群的讀和寫的可用性都非常高。

讀寫分離架構(gòu)的缺陷在于,不管是Master還是Slave,每個(gè)節(jié)點(diǎn)都必須保存完整的數(shù)據(jù),如果在數(shù)據(jù)量很大的情況下,集群的擴(kuò)展能力還是受限于單個(gè)節(jié)點(diǎn)的存儲(chǔ)能力,而且對(duì)于Write-intensive類型的應(yīng)用,讀寫分離架構(gòu)并不適合。

Redis數(shù)據(jù)分片模型

為了解決讀寫分離模型的缺陷,可以將數(shù)據(jù)分片模型應(yīng)用進(jìn)來。

可以將每個(gè)節(jié)點(diǎn)看成都是獨(dú)立的master,然后通過業(yè)務(wù)實(shí)現(xiàn)數(shù)據(jù)分片。

結(jié)合上面兩種模型,可以將每個(gè)master設(shè)計(jì)成由一個(gè)master和多個(gè)slave組成的模型。

Redis提供了哪幾種持久化方式?

1. Redis主要提供了兩種持久化機(jī)制:RDB和AOF;

2.RDB

默認(rèn)開啟,會(huì)按照配置的指定時(shí)間將內(nèi)存中的數(shù)據(jù)快照到磁盤中,創(chuàng)建一個(gè)dump.rdb文件,Redis啟動(dòng)時(shí)再恢復(fù)到內(nèi)存中。

Redis會(huì)單獨(dú)創(chuàng)建fork()一個(gè)子進(jìn)程,將當(dāng)前父進(jìn)程的數(shù)據(jù)庫數(shù)據(jù)復(fù)制到子進(jìn)程的內(nèi)存中,然后由子進(jìn)程寫入到臨時(shí)文件中,持久化的過程結(jié)束了,再用這個(gè)臨時(shí)文件替換上次的快照文件,然后子進(jìn)程退出,內(nèi)存釋放。

需要注意的是,每次快照持久化都會(huì)將主進(jìn)程的數(shù)據(jù)庫數(shù)據(jù)復(fù)制一遍,導(dǎo)致內(nèi)存開銷加倍,若此時(shí)內(nèi)存不足,則會(huì)阻塞服務(wù)器運(yùn)行,直到復(fù)制結(jié)束釋放內(nèi)存;都會(huì)將內(nèi)存數(shù)據(jù)完整寫入磁盤一次,所以如果數(shù)據(jù)量大的話,而且寫操作頻繁,必然會(huì)引起大量的磁盤I/O操作,嚴(yán)重影響性能,并且最后一次持久化后的數(shù)據(jù)可能會(huì)丟失;

3.AOF

以日志的形式記錄每個(gè)寫操作(讀操作不記錄),只需追加文件但不可以改寫文件,Redis啟動(dòng)時(shí)會(huì)根據(jù)日志從頭到尾全部執(zhí)行一遍以完成數(shù)據(jù)的恢復(fù)工作。包括flushDB也會(huì)執(zhí)行。

主要有兩種方式觸發(fā):有寫操作就寫、每秒定時(shí)寫(也會(huì)丟數(shù)據(jù))。

因?yàn)锳OF采用追加的方式,所以文件會(huì)越來越大,針對(duì)這個(gè)問題,新增了重寫機(jī)制,就是當(dāng)日志文件大到一定程度的時(shí)候,會(huì)fork出一條新進(jìn)程來遍歷進(jìn)程內(nèi)存中的數(shù)據(jù),每條記錄對(duì)應(yīng)一條set語句,寫到臨時(shí)文件中,然后再替換到舊的日志文件(類似rdb的操作方式)。默認(rèn)觸發(fā)是當(dāng)aof文件大小是上次重寫后大小的一倍且文件大于64M時(shí)觸發(fā)。

當(dāng)兩種方式同時(shí)開啟時(shí),數(shù)據(jù)恢復(fù)Redis會(huì)優(yōu)先選擇AOF恢復(fù)。一般情況下,只要使用默認(rèn)開啟的RDB即可,因?yàn)橄鄬?duì)于AOF,RDB便于進(jìn)行數(shù)據(jù)庫備份,并且恢復(fù)數(shù)據(jù)集的速度也要快很多。

開啟持久化緩存機(jī)制,對(duì)性能會(huì)有一定的影響,特別是當(dāng)設(shè)置的內(nèi)存滿了的時(shí)候,更是下降到幾百reqs/s。所以如果只是用來做緩存的話,可以關(guān)掉持久化。

Redis常見性能問題和解決方案?

(1) Master最好不要做任何持久化工作,如RDB內(nèi)存快照和AOF日志文件

(2) 如果數(shù)據(jù)比較重要,某個(gè)Slave開啟AOF備份數(shù)據(jù),策略設(shè)置為每秒同步一次

(3) 為了主從復(fù)制的速度和連接的穩(wěn)定性,Master和Slave最好在同一個(gè)局域網(wǎng)內(nèi)

(4) 盡量避免在壓力很大的主庫上增加從庫

(5) 主從復(fù)制不要用圖狀結(jié)構(gòu),用單向鏈表結(jié)構(gòu)更為穩(wěn)定,即:Master <- Slave1 <- Slave2 <- Slave3...

這樣的結(jié)構(gòu)方便解決單點(diǎn)故障問題,實(shí)現(xiàn)Slave對(duì)Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。

Redis支持的Java客戶端都有哪些?官方推薦用哪個(gè)?

Redisson、Jedis、lettuce等等,官方推薦使用Redisson。

Redis哈希槽的概念?

Redis集群沒有使用一致性hash,而是引入了哈希槽的概念,當(dāng)需要在 Redis 集群中放置一個(gè) key-value 時(shí),根據(jù) CRC16(key) mod 16384的值,決定將一個(gè)key放到哪個(gè)桶中。

Redis集群最大節(jié)點(diǎn)個(gè)數(shù)是多少?

Redis集群預(yù)分好16384個(gè)桶(哈希槽)

Redis集群的主從復(fù)制模型是怎樣的?

為了使在部分節(jié)點(diǎn)失敗或者大部分節(jié)點(diǎn)無法通信的情況下集群仍然可用,所以集群使用了主從復(fù)制模型,每個(gè)節(jié)點(diǎn)都會(huì)有N-1個(gè)復(fù)制品.

Redis集群會(huì)有寫操作丟失嗎?為什么?

Redis并不能保證數(shù)據(jù)的強(qiáng)一致性,這意味這在實(shí)際中集群在特定的條件下可能會(huì)丟失寫操作。

Redis集群之間是如何復(fù)制的?

異步復(fù)制

Redis如何做內(nèi)存優(yōu)化?

盡可能使用散列表(hashes),散列表(是說散列表里面存儲(chǔ)的數(shù)少)使用的內(nèi)存非常小,所以你應(yīng)該盡可能的將你的數(shù)據(jù)模型抽象到一個(gè)散列表里面。比如你的web系統(tǒng)中有一個(gè)用戶對(duì)象,不要為這個(gè)用戶的名稱,姓氏,郵箱,密碼設(shè)置單獨(dú)的key,而是應(yīng)該把這個(gè)用戶的所有信息存儲(chǔ)到一張散列表里面.

Redis回收進(jìn)程如何工作的?

一個(gè)客戶端運(yùn)行了新的命令,添加了新的數(shù)據(jù)。

Redi檢查內(nèi)存使用情況,如果大于maxmemory的限制, 則根據(jù)設(shè)定好的策略進(jìn)行回收。

Redis回收使用的是什么算法?

LRU算法

Redis有哪些適合的場(chǎng)景?

1)Session共享(單點(diǎn)登錄)

2)頁面緩存

3)隊(duì)列

4)排行榜/計(jì)數(shù)器

5)發(fā)布/訂閱

以上就是最全Redis詳細(xì)答案總結(jié)。

覺得不錯(cuò)請(qǐng)點(diǎn)贊支持,歡迎留言或進(jìn)我的個(gè)人群179961551領(lǐng)取【架構(gòu)資料專題目合集90期】、【BATJTMD大廠JAVA面試真題1000+】,本群專用于學(xué)習(xí)交流技術(shù)、分享面試機(jī)會(huì),拒絕廣告,我也會(huì)在群內(nèi)不定期答題、探討。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容