史上最全Redis面试49题(含答案):哨兵+复制+事务+集群+持久化等
最全面試題答案系列
史上最強(qiáng)多線程面試44題和答案:線程鎖+線程池+線程同步等
最全MySQL面試60題和答案
史上最全memcached面試26題和答案
史上最全Spring面試71題與答案
今天主要分享redis最全答案系列
Redis主要有哪些功能?
1.哨兵(Sentinel)和復(fù)制(Replication)
Redis服務(wù)器毫無(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è)功能來(lái)保證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ù)寫(xiě)入到硬盤中,在redis重新啟動(dòng)的時(shí)候加載這些數(shù)據(jù),從而最大限度的降低緩存丟失帶來(lái)的影響。
5.集群(Cluster)
單臺(tái)服務(wù)器資源的總是有上限的,CPU資源和IO資源我們可以通過(guò)主從復(fù)制,進(jìn)行讀寫(xiě)分離,把一部分CPU和IO的壓力轉(zhuǎn)移到從服務(wù)器上,這也有點(diǎn)類似mysql數(shù)據(jù)庫(kù)的主從同步。
在Redis官方的分布式方案出來(lái)之前,有twemproxy和codis兩種方案,這兩個(gè)方案總體上來(lái)說(shuō)都是依賴proxy來(lái)進(jìn)行分布式的。
Redis支持哪幾種數(shù)據(jù)類型?
支持多種類型的數(shù)據(jù)結(jié)構(gòu)
1.string:最基本的數(shù)據(jù)類型,二進(jìn)制安全的字符串,最大512M。
2.list:按照添加順序保持順序的字符串列表。
3.set:無(wú)序的字符串集合,不存在重復(fù)的元素。
4.sorted set:已排序的字符串集合。
5.hash:key-value對(duì)的一種集合。
Redis是單進(jìn)程單線程的?
Redis是單進(jìn)程單線程的,Redis利用隊(duì)列技術(shù)將并發(fā)訪問(wèn)變?yōu)榇性L問(wèn),消除了傳統(tǒng)數(shù)據(jù)庫(kù)串行控制的開(kāi)銷。
Redis為什么是單線程的?
多線程處理會(huì)涉及到鎖,而且多線程處理會(huì)涉及到線程切換而消耗CPU。因?yàn)镃PU不是Redis的瓶頸,Redis的瓶頸最有可能是機(jī)器內(nèi)存或者網(wǎng)絡(luò)帶寬。單線程無(wú)法發(fā)揮多核CPU性能,不過(guò)可以通過(guò)在單機(jī)開(kāi)多個(gè)Redis實(shí)例來(lái)解決。
其它開(kāi)源軟件采用的模型
Nginx:多進(jìn)程單線程模型
Memcached:單進(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è)置過(guò)期時(shí)間,過(guò)期后將會(huì)自動(dòng)刪除
Redis單點(diǎn)吞吐量
單點(diǎn)TPS達(dá)到8萬(wàn)/秒,QPS達(dá)到10萬(wàn)/秒,補(bǔ)充下TPS和QPS的概念
1.QPS: 應(yīng)用系統(tǒng)每秒鐘最大能接受的用戶訪問(wèn)量
每秒鐘處理完請(qǐng)求的次數(shù),注意這里是處理完,具體是指發(fā)出請(qǐng)求到服務(wù)器處理完成功返回結(jié)果。可以理解在server中有個(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è)置過(guò)期的數(shù)據(jù)集中挑選最近最少使用的淘汰
2.volatile-ttr:從已設(shè)置過(guò)期的數(shù)據(jù)集中挑選將要過(guò)期的數(shù)據(jù)淘汰
3.volatile-random:從已設(shè)置過(guò)期的數(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)。
Redis讀寫(xiě)分離模型
通過(guò)增加Slave DB的數(shù)量,讀的性能可以線性增長(zhǎng)。為了避免Master DB的單點(diǎn)故障,集群一般都會(huì)采用兩臺(tái)Master DB做雙機(jī)熱備,所以整個(gè)集群的讀和寫(xiě)的可用性都非常高。
讀寫(xiě)分離架構(gòu)的缺陷在于,不管是Master還是Slave,每個(gè)節(jié)點(diǎn)都必須保存完整的數(shù)據(jù),如果在數(shù)據(jù)量很大的情況下,集群的擴(kuò)展能力還是受限于單個(gè)節(jié)點(diǎn)的存儲(chǔ)能力,而且對(duì)于Write-intensive類型的應(yīng)用,讀寫(xiě)分離架構(gòu)并不適合。
Redis數(shù)據(jù)分片模型
為了解決讀寫(xiě)分離模型的缺陷,可以將數(shù)據(jù)分片模型應(yīng)用進(jìn)來(lái)。
可以將每個(gè)節(jié)點(diǎn)看成都是獨(dú)立的master,然后通過(guò)業(yè)務(wù)實(shí)現(xiàn)數(shù)據(jù)分片。
結(jié)合上面兩種模型,可以將每個(gè)master設(shè)計(jì)成由一個(gè)master和多個(gè)slave組成的模型。
Redis提供了哪幾種持久化方式?
RDB持久化方式能夠在指定的時(shí)間間隔能對(duì)你的數(shù)據(jù)進(jìn)行快照存儲(chǔ)
AOF持久化方式記錄每次對(duì)服務(wù)器寫(xiě)的操作,當(dāng)服務(wù)器重啟的時(shí)候會(huì)重新執(zhí)行這些命令來(lái)恢復(fù)原始的數(shù)據(jù),AOF命令以Redis協(xié)議追加保存每次寫(xiě)的操作到文件末尾.Redis還能對(duì)AOF文件進(jìn)行后臺(tái)重寫(xiě),使得AOF文件的體積不至于過(guò)大.
如果你只希望你的數(shù)據(jù)在服務(wù)器運(yùn)行的時(shí)候存在,你也可以不使用任何持久化方式.
你也可以同時(shí)開(kāi)啟兩種持久化方式, 在這種情況下, 當(dāng)Redis重啟的時(shí)候會(huì)優(yōu)先載入AOF文件來(lái)恢復(fù)原始的數(shù)據(jù),因?yàn)樵谕ǔG闆r下AOF文件保存的數(shù)據(jù)集要比RDB文件保存的數(shù)據(jù)集要完整.
最重要的事情是了解RDB和AOF持久化方式的不同,讓我們以RDB持久化方式開(kāi)始。
如何選擇合適的持久化方式?
1. Redis主要提供了兩種持久化機(jī)制:RDB和AOF;
2.RDB
默認(rèn)開(kāi)啟,會(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ù)庫(kù)數(shù)據(jù)復(fù)制到子進(jìn)程的內(nèi)存中,然后由子進(jìn)程寫(xiě)入到臨時(shí)文件中,持久化的過(guò)程結(jié)束了,再用這個(gè)臨時(shí)文件替換上次的快照文件,然后子進(jìn)程退出,內(nèi)存釋放。
需要注意的是,每次快照持久化都會(huì)將主進(jìn)程的數(shù)據(jù)庫(kù)數(shù)據(jù)復(fù)制一遍,導(dǎo)致內(nèi)存開(kāi)銷加倍,若此時(shí)內(nèi)存不足,則會(huì)阻塞服務(wù)器運(yùn)行,直到復(fù)制結(jié)束釋放內(nèi)存;都會(huì)將內(nèi)存數(shù)據(jù)完整寫(xiě)入磁盤一次,所以如果數(shù)據(jù)量大的話,而且寫(xiě)操作頻繁,必然會(huì)引起大量的磁盤I/O操作,嚴(yán)重影響性能,并且最后一次持久化后的數(shù)據(jù)可能會(huì)丟失;
3.AOF
以日志的形式記錄每個(gè)寫(xiě)操作(讀操作不記錄),只需追加文件但不可以改寫(xiě)文件,Redis啟動(dòng)時(shí)會(huì)根據(jù)日志從頭到尾全部執(zhí)行一遍以完成數(shù)據(jù)的恢復(fù)工作。包括flushDB也會(huì)執(zhí)行。
主要有兩種方式觸發(fā):有寫(xiě)操作就寫(xiě)、每秒定時(shí)寫(xiě)(也會(huì)丟數(shù)據(jù))。
因?yàn)锳OF采用追加的方式,所以文件會(huì)越來(lái)越大,針對(duì)這個(gè)問(wèn)題,新增了重寫(xiě)機(jī)制,就是當(dāng)日志文件大到一定程度的時(shí)候,會(huì)fork出一條新進(jìn)程來(lái)遍歷進(jìn)程內(nèi)存中的數(shù)據(jù),每條記錄對(duì)應(yīng)一條set語(yǔ)句,寫(xiě)到臨時(shí)文件中,然后再替換到舊的日志文件(類似rdb的操作方式)。默認(rèn)觸發(fā)是當(dāng)aof文件大小是上次重寫(xiě)后大小的一倍且文件大于64M時(shí)觸發(fā)。
當(dāng)兩種方式同時(shí)開(kāi)啟時(shí),數(shù)據(jù)恢復(fù)Redis會(huì)優(yōu)先選擇AOF恢復(fù)。一般情況下,只要使用默認(rèn)開(kāi)啟的RDB即可,因?yàn)橄鄬?duì)于AOF,RDB便于進(jìn)行數(shù)據(jù)庫(kù)備份,并且恢復(fù)數(shù)據(jù)集的速度也要快很多。
開(kāi)啟持久化緩存機(jī)制,對(duì)性能會(huì)有一定的影響,特別是當(dāng)設(shè)置的內(nèi)存滿了的時(shí)候,更是下降到幾百reqs/s。所以如果只是用來(lái)做緩存的話,可以關(guān)掉持久化。
Redis常見(jiàn)性能問(wèn)題和解決方案?
(1) Master最好不要做任何持久化工作,如RDB內(nèi)存快照和AOF日志文件
(2) 如果數(shù)據(jù)比較重要,某個(gè)Slave開(kāi)啟AOF備份數(shù)據(jù),策略設(shè)置為每秒同步一次
(3) 為了主從復(fù)制的速度和連接的穩(wěn)定性,Master和Slave最好在同一個(gè)局域網(wǎng)內(nèi)
(4) 盡量避免在壓力很大的主庫(kù)上增加從庫(kù)
(5) 主從復(fù)制不要用圖狀結(jié)構(gòu),用單向鏈表結(jié)構(gòu)更為穩(wěn)定,即:Master <- Slave1 <- Slave2 <- Slave3…
這樣的結(jié)構(gòu)方便解決單點(diǎn)故障問(wèn)題,實(shí)現(xiàn)Slave對(duì)Master的替換。如果Master掛了,可以立刻啟用Slave1做Master,其他不變。
Redis支持的Java客戶端都有哪些?官方推薦用哪個(gè)?
Redisson、Jedis、lettuce等等,官方推薦使用Redisson。
Redis哈希槽的概念?
Redis集群沒(méi)有使用一致性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)無(wú)法通信的情況下集群仍然可用,所以集群使用了主從復(fù)制模型,每個(gè)節(jié)點(diǎn)都會(huì)有N-1個(gè)復(fù)制品.
Redis集群會(huì)有寫(xiě)操作丟失嗎?為什么?
Redis并不能保證數(shù)據(jù)的強(qiáng)一致性,這意味這在實(shí)際中集群在特定的條件下可能會(huì)丟失寫(xiě)操作。
Redis集群之間是如何復(fù)制的?
異步復(fù)制
Redis如何做內(nèi)存優(yōu)化?
盡可能使用散列表(hashes),散列表(是說(shuō)散列表里面存儲(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)頁(yè)面緩存
3)隊(duì)列
4)排行榜/計(jì)數(shù)器
5)發(fā)布/訂閱
具體可以參考:高并發(fā)架構(gòu)系列:詳解Redis的存儲(chǔ)類型、集群架構(gòu)、以及應(yīng)用場(chǎng)景
你可能也喜歡:
總結(jié)
以上是生活随笔為你收集整理的史上最全Redis面试49题(含答案):哨兵+复制+事务+集群+持久化等的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用Intellij中的Spring I
- 下一篇: 大众点评账号业务高可用进阶之路