nodejs redis 过期时间_别在为Redis面试而烦恼了?看完暴答【面试管】
Redis面試官喜歡問(wèn)的,小伙伴們看完暴答面試官!!!
?Redis 是什么?都有哪些使用場(chǎng)景?Redis 是一個(gè)使用 C 語(yǔ)言開(kāi)發(fā)的高性能鍵值對(duì)(key-value)的內(nèi)存數(shù)據(jù)庫(kù),性能優(yōu)秀,數(shù)據(jù)在內(nèi)存中,讀寫(xiě)速度非常快,支持并發(fā) 10W QPS。單進(jìn)程單線程,是線程安全的,采用 IO 多路復(fù)用機(jī)制。豐富的數(shù)據(jù)類(lèi)型,支持字符串(strings)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。支持?jǐn)?shù)據(jù)持久化。可以將內(nèi)存中數(shù)據(jù)保存在磁盤(pán)中,重啟時(shí)加載。主從復(fù)制,哨兵,高可用。可以用作分布式鎖。可以作為消息中間件使用,支持發(fā)布訂閱。??? Redis 使用場(chǎng)景:
記錄帖子點(diǎn)贊數(shù)、點(diǎn)擊數(shù)、評(píng)論數(shù);
緩存近期熱帖;
緩存文章詳情信息;
記錄用戶會(huì)話信息。
Redis 有哪些功能?
數(shù)據(jù)緩存功能
分布式鎖的功能
支持?jǐn)?shù)據(jù)持久化
支持事務(wù)
支持消息隊(duì)列
存儲(chǔ)方式不同:memcache 把數(shù)據(jù)全部存在內(nèi)存之中,斷電后會(huì)掛掉,數(shù)據(jù)不能超過(guò)內(nèi)存大小;Redis 有部份存在硬盤(pán)上,這樣能保證數(shù)據(jù)的持久性。
數(shù)據(jù)支持類(lèi)型:memcache 對(duì)數(shù)據(jù)類(lèi)型支持相對(duì)簡(jiǎn)單;Redis 有復(fù)雜的數(shù)據(jù)類(lèi)型。
使用底層模型不同:它們之間底層實(shí)現(xiàn)方式,以及與客戶端之間通信的應(yīng)用協(xié)議不一樣,Redis 自己構(gòu)建了 vm 機(jī)制,因?yàn)橐话愕南到y(tǒng)調(diào)用系統(tǒng)函數(shù)的話,會(huì)浪費(fèi)一定的時(shí)間去移動(dòng)和請(qǐng)求。
value 值大小不同:Redis 最大可以達(dá)到 512mb;memcache 只有 1mb。
Redis 為什么是單線程的?
因?yàn)?cpu 不是 Redis 的瓶頸,Redis 的瓶頸最有可能是機(jī)器內(nèi)存或者網(wǎng)絡(luò)帶寬。既然單線程容易實(shí)現(xiàn),而且 cpu 又不會(huì)成為瓶頸,那就順理成章地采用單線程的方案了。關(guān)于 Redis 的性能,官方網(wǎng)站也有,普通筆記本輕松處理每秒幾十萬(wàn)的請(qǐng)求。而且單線程并不代表就慢 nginx 和 nodejs 也都是高性能單線程的代表。Redis 支持的數(shù)據(jù)類(lèi)型有哪些以及應(yīng)用場(chǎng)景總結(jié)?
Redis 支持的數(shù)據(jù)類(lèi)型:string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。
數(shù)據(jù)類(lèi)型應(yīng)用場(chǎng)景:什么是緩存穿透,緩存擊穿,緩存雪崩,緩存失效,緩存并發(fā)及解決方案?一. 緩存擊穿
緩存擊穿是指緩存中沒(méi)有,但數(shù)據(jù)庫(kù)中有的數(shù)據(jù)(一般是緩存時(shí)間到期),這時(shí)由于并發(fā)用戶特別多,同時(shí)讀緩存沒(méi)有讀到的數(shù)據(jù),又同時(shí)區(qū)數(shù)據(jù)庫(kù)讀取,引起數(shù)據(jù)庫(kù)壓力瞬間增大,造成的過(guò)的壓力。解決方案:
設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過(guò)期。
加互斥鎖,互斥鎖參考代碼如下
二. 緩存穿透
緩存穿透是指緩存和數(shù)據(jù)庫(kù)中都沒(méi)有的數(shù)據(jù),而用戶不斷發(fā)起請(qǐng)求,如發(fā)起為id為“-1”的數(shù)據(jù)或id為特別大不存在的數(shù)據(jù)。這時(shí)的用戶很可能是攻擊者,攻擊會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大。解決方案:
接口層增加校驗(yàn),如用戶鑒權(quán)校驗(yàn),id做基礎(chǔ)校驗(yàn),id<=0的直接攔截;從緩存取
的數(shù)據(jù),在數(shù)據(jù)庫(kù)中也沒(méi)有取到,這時(shí)也可以將key-value對(duì)寫(xiě)為key-null,緩存有效時(shí)間可以設(shè)置短點(diǎn),如30秒(設(shè)置太長(zhǎng)會(huì)導(dǎo)致正常情況也沒(méi)法使用)。這樣可以防止攻擊用戶反復(fù)用同一個(gè)id暴力攻擊
三. 緩存雪崩
緩存雪崩是指緩存中數(shù)據(jù)大批量到過(guò)期時(shí)間,而查詢數(shù)據(jù)量巨大,引起數(shù)據(jù)庫(kù)壓力過(guò)大甚至down機(jī)。和緩存擊穿不同的是,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過(guò)期了,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫(kù)。解決方案:
緩存數(shù)據(jù)的過(guò)期時(shí)間設(shè)置隨機(jī),防止同一時(shí)間大量數(shù)據(jù)過(guò)期現(xiàn)象發(fā)生。
如果緩存數(shù)據(jù)庫(kù)是分布式部署,將熱點(diǎn)數(shù)據(jù)均勻分布在不同搞得緩存數(shù)據(jù)庫(kù)中。
設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過(guò)期。
四. 緩存失效
引起這個(gè)原因的主要因素是高并發(fā)下,我們一般設(shè)定一個(gè)緩存的過(guò)期時(shí)間時(shí),可能有一些會(huì)設(shè)置5分鐘啊,10分鐘這些;并發(fā)很高時(shí)可能會(huì)出在某一個(gè)時(shí)間同時(shí)生成了很多的緩存,并且過(guò)期時(shí)間在同一時(shí)刻,這個(gè)時(shí)候就可能引發(fā),當(dāng)過(guò)期時(shí)間到后,這些緩存同時(shí)失效,請(qǐng)求全部轉(zhuǎn)發(fā)到DB,DB可能會(huì)壓力過(guò)重解決方案:
一個(gè)簡(jiǎn)單方案就是將緩存失效時(shí)間分散開(kāi),不要所以緩存時(shí)間長(zhǎng)度都設(shè)置成5分鐘或者10分鐘;比如我們可以在原有的失效時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值,比如1-5分鐘隨機(jī),這樣每一個(gè)緩存的過(guò)期時(shí)間的重復(fù)率就會(huì)降低,就很難引發(fā)集體失效的事件。
緩存失效時(shí)產(chǎn)生的雪崩效應(yīng),將所有請(qǐng)求全部放在數(shù)據(jù)庫(kù)上,這樣很容易就達(dá)到數(shù)據(jù)庫(kù)的瓶頸,導(dǎo)致服務(wù)無(wú)法正常提供。盡量避免這種場(chǎng)景的發(fā)生。
五. 緩存并發(fā)
當(dāng)網(wǎng)站并發(fā)訪問(wèn)高,一個(gè)緩存如果失效,可能出現(xiàn)多個(gè)進(jìn)程同時(shí)查詢DB,同時(shí)設(shè)置緩存的情況,如果并發(fā)確實(shí)很大,這也可能造成DB壓力過(guò)大,還有緩存頻繁更新的問(wèn)題。解決方案:
對(duì)緩存查詢加鎖,如果KEY不存在,就加鎖,然后查DB入緩存,然后解鎖;其他進(jìn)程如果發(fā)現(xiàn)有鎖就等待,然后等解鎖后返回?cái)?shù)據(jù)或者進(jìn)入DB查詢。
Redis 支持的 Java 客戶端都有哪些?
支持的 Java 客戶端有 Redisson、jedis、lettuce 等。jedis 和 Redisson 有哪些區(qū)別?
jedis:提供了比較全面的 Redis 命令的支持。
Rdisson:實(shí)現(xiàn)了分布式和可擴(kuò)展的 Java 數(shù)據(jù)結(jié)構(gòu),與 jedis 相比 Redisson 的功能相對(duì)簡(jiǎn)單,不支持排序、事務(wù)、管道、分區(qū)等 Redis 特性。
怎么保證緩存和數(shù)據(jù)庫(kù)數(shù)據(jù)的一致性?
合理設(shè)置緩存的過(guò)期時(shí)間。
新增、更改、刪除數(shù)據(jù)庫(kù)操作時(shí)同步更新 Redis,可以使用事物機(jī)制來(lái)保證數(shù)據(jù)的一致性。
Redis 持久化有幾種方式?
? ? ?Redis 的持久化有兩種方式,或者說(shuō)有兩種策略:
RDB(Redis Database):在指定的時(shí)間隔內(nèi)生成數(shù)據(jù)集快照寫(xiě)入到磁盤(pán)中(就是將redis內(nèi)存中數(shù)據(jù)庫(kù)記錄定時(shí)寫(xiě)入到磁盤(pán)中)
AOF(Append Only File):以日志的形式記錄每一個(gè)操作,并進(jìn)行追加。
Redis RDB和AOF兩種持久化區(qū)別及優(yōu)缺點(diǎn)?
RDB
在指定的時(shí)間隔內(nèi)生成數(shù)據(jù)集快照寫(xiě)入到磁盤(pán)中優(yōu)點(diǎn):一旦采用該方式,那么你的redis數(shù)據(jù)庫(kù)只包含一個(gè)文件,這對(duì)于文件備份而已非常完美,比如:你可能打算每個(gè)小時(shí)歸檔一次最近24小時(shí)數(shù)據(jù),同時(shí)還要每天歸檔一次最近30天數(shù)據(jù)。通過(guò)這樣的備份,策略,一旦系統(tǒng)出現(xiàn)災(zāi)難性故障,我們可以非常容易的進(jìn)行恢復(fù).
缺點(diǎn):更新過(guò)程中出現(xiàn)宕機(jī)情況下,數(shù)據(jù)持久性會(huì)丟失
AOF
以日志的形式記錄每一個(gè)操作,并進(jìn)行追加。優(yōu)點(diǎn):該方式可以對(duì)數(shù)據(jù)持久安全性更高,因?yàn)樗峁┝?種同步策略,每種策略效率都不是一樣的。
缺點(diǎn):運(yùn)行效率慢與RDB,雖然AOF有不同的策略,也沒(méi)有RDB效率快,并且RDB在恢復(fù)大數(shù)據(jù)集時(shí)速度也比AOF快
Redis 怎么實(shí)現(xiàn)分布式鎖?
Redis 分布式鎖其實(shí)就是在系統(tǒng)里面占一個(gè)“坑”,其他程序也要占“坑”的時(shí)候,占用成功了就可以繼續(xù)執(zhí)行,失敗了就只能放棄或稍后重試。占坑一般使用 setnx(set if not exists)指令,只允許被一個(gè)程序占有,使用完調(diào)用 del 釋放鎖。Redis 分布式鎖有什么缺陷?
Redis 分布式鎖不能解決超時(shí)的問(wèn)題,分布式鎖有一個(gè)超時(shí)時(shí)間,程序的執(zhí)行如果超出了鎖的超時(shí)時(shí)間就會(huì)出現(xiàn)問(wèn)題。Redis 淘汰策略有哪些?
volatile-lru:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server. db[i]. expires)中挑選最近最少使用的數(shù)據(jù)淘汰。
volatile-ttl:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server. db[i]. expires)中挑選將要過(guò)期的數(shù)據(jù)淘汰。
volatile-random:從已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集(server. db[i]. expires)中任意選擇數(shù)據(jù)淘汰。
allkeys-lru:從數(shù)據(jù)集(server. db[i]. dict)中挑選最近最少使用的數(shù)據(jù)淘汰。
allkeys-random:從數(shù)據(jù)集(server. db[i]. dict)中任意選擇數(shù)據(jù)淘汰。
no-enviction(驅(qū)逐):禁止驅(qū)逐數(shù)據(jù)。
Redis 常見(jiàn)的性能問(wèn)題有哪些?該如何解決?
主服務(wù)器寫(xiě)內(nèi)存快照,會(huì)阻塞主線程的工作,當(dāng)快照比較大時(shí)對(duì)性能影響是非常大的,會(huì)間斷性暫停服務(wù),所以主服務(wù)器最好不要寫(xiě)內(nèi)存快照。Redis 主從復(fù)制的性能問(wèn)題,為了主從復(fù)制的速度和連接的穩(wěn)定性,主從庫(kù)最好在同一個(gè)局域網(wǎng)內(nèi)。Redis 事務(wù)了解過(guò)嗎?
Redis 通過(guò) MULTI、EXEC、WATCH 等命令來(lái)實(shí)現(xiàn)事務(wù)(transaction)功能。事務(wù)提供了一種將多個(gè)命令請(qǐng)求打包,然后一次性、按順序地執(zhí)行多個(gè)命令的機(jī)制,并且在事務(wù)執(zhí)行期間,服務(wù)器不會(huì)中斷事務(wù)而改去執(zhí)行其他客戶端的命令請(qǐng)求,它會(huì)將事務(wù)中的所有命令都執(zhí)行完畢,然后才去處理其他客戶端的命令請(qǐng)求。在傳統(tǒng)的關(guān)系式數(shù)據(jù)庫(kù)中,常常用 ACID 性質(zhì)來(lái)檢驗(yàn)事務(wù)功能的可靠性和安全性。在 Redis 中,事務(wù)總是具有原子性(Atomicity)、一致性(Consistency)和隔離性(Isolation),并且當(dāng) Redis 運(yùn)行在某種特定的持久化模式下時(shí),事務(wù)也具有持久性(Durability)。如何解決 Redis 的并發(fā)競(jìng)爭(zhēng) Key 問(wèn)題
所謂 Redis 的并發(fā)競(jìng)爭(zhēng) Key 的問(wèn)題也就是多個(gè)系統(tǒng)同時(shí)對(duì)一個(gè) key 進(jìn)行操作,但是最后執(zhí)行的順序和我們期望的順序不同,這樣也就導(dǎo)致了結(jié)果的不同!推薦一種方案:分布式鎖(zookeeper 和 redis 都可以實(shí)現(xiàn)分布式鎖)。(如果不存在 Redis 的并發(fā)競(jìng)爭(zhēng) Key 問(wèn)題,不要使用分布式鎖,這樣會(huì)影響性能)基于zookeeper臨時(shí)有序節(jié)點(diǎn)可以實(shí)現(xiàn)的分布式鎖。大致思想為:每個(gè)客戶端對(duì)某個(gè)方法加鎖時(shí),在zookeeper上的與該方法對(duì)應(yīng)的指定節(jié)點(diǎn)的目錄下,生成一個(gè)唯一的瞬時(shí)有序節(jié)點(diǎn)。判斷是否獲取鎖的方式很簡(jiǎn)單,只需要判斷有序節(jié)點(diǎn)中序號(hào)最小的一個(gè)。當(dāng)釋放鎖的時(shí)候,只需將這個(gè)瞬時(shí)節(jié)點(diǎn)刪除即可。同時(shí),其可以避免服務(wù)宕機(jī)導(dǎo)致的鎖無(wú)法釋放,而產(chǎn)生的死鎖問(wèn)題。完成業(yè)務(wù)流程后,刪除對(duì)應(yīng)的子節(jié)點(diǎn)釋放鎖。如何保證緩存與數(shù)據(jù)庫(kù)雙寫(xiě)時(shí)的數(shù)據(jù)一致性?
你只要用緩存,就可能會(huì)涉及到緩存與數(shù)據(jù)庫(kù)雙存儲(chǔ)雙寫(xiě),你只要是雙寫(xiě),就一定會(huì)有數(shù)據(jù)一致性的問(wèn)題,那么你如何解決一致性問(wèn)題?一般來(lái)說(shuō),就是如果你的系統(tǒng)不是嚴(yán)格要求緩存+數(shù)據(jù)庫(kù)必須一致性的話,緩存可以稍微的跟數(shù)據(jù)庫(kù)偶爾有不一致的情況,最好不要做這個(gè)方案,讀請(qǐng)求和寫(xiě)請(qǐng)求串行化,串到一個(gè)內(nèi)存隊(duì)列里去,這樣就可以保證一定不會(huì)出現(xiàn)不一致的情況串行化之后,就會(huì)導(dǎo)致系統(tǒng)的吞吐量會(huì)大幅度的降低,用比正常情況下多幾倍的機(jī)器去支撐線上的一個(gè)請(qǐng)求。還有一種方式就是可能會(huì)暫時(shí)產(chǎn)生不一致的情況,但是發(fā)生的幾率特別小,就是先更新數(shù)據(jù)庫(kù),然后再刪除緩存。這種情況不存在并發(fā)問(wèn)題么?
不是的。假設(shè)這會(huì)有兩個(gè)請(qǐng)求,一個(gè)請(qǐng)求A做查詢操作,一個(gè)請(qǐng)求B做更新操作,那么會(huì)有如下情形產(chǎn)生
(1)緩存剛好失效
(2)請(qǐng)求A查詢數(shù)據(jù)庫(kù),得一個(gè)舊值
(3)請(qǐng)求B將新值寫(xiě)入數(shù)據(jù)庫(kù)
(4)請(qǐng)求B刪除緩存
(5)請(qǐng)求A將查到的舊值寫(xiě)入緩存
ok,如果發(fā)生上述情況,確實(shí)是會(huì)發(fā)生臟數(shù)據(jù)。
然而,發(fā)生這種情況的概率又有多少呢?
發(fā)生上述情況有一個(gè)先天性條件,就是步驟(3)的寫(xiě)數(shù)據(jù)庫(kù)操作比步驟(2)的讀數(shù)據(jù)庫(kù)操作耗時(shí)更短,才有可能使得步驟(4)先于步驟(5)。可是,大家想想,數(shù)據(jù)庫(kù)的讀操作的速度遠(yuǎn)快于寫(xiě)操作的(不然做讀寫(xiě)分離干嘛,做讀寫(xiě)分離的意義就是因?yàn)樽x操作比較快,耗資源少),因此步驟(3)耗時(shí)比步驟(2)更短,這一情形很難出現(xiàn)。總結(jié)
以上是生活随笔為你收集整理的nodejs redis 过期时间_别在为Redis面试而烦恼了?看完暴答【面试管】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 阿里云对象存储OSS与文件存储NAS的区
- 下一篇: mysql查看binlog日志内容