收集Redis16个最常见面试问题
1.什么是redis?
Redis 是一個(gè)基于內(nèi)存的高性能key-value數(shù)據(jù)庫(kù)。
2.Redis的特點(diǎn)
Redis本質(zhì)上是一個(gè)Key-Value類(lèi)型的內(nèi)存數(shù)據(jù)庫(kù),很像memcached,整個(gè)數(shù)據(jù)庫(kù)統(tǒng)統(tǒng)加載在內(nèi)存當(dāng)中進(jìn)行操作,定期通過(guò)異步操作把數(shù)據(jù)庫(kù)數(shù)據(jù)flush到硬盤(pán)上進(jìn)行保存。
因?yàn)槭羌儍?nèi)存操作,Redis的性能非常出色,每秒可以處理超過(guò) 10萬(wàn)次讀寫(xiě)操作,是已知性能最快的Key-Value DB。
Redis的出色之處不僅僅是性能,Redis最大的魅力是支持保存多種數(shù)據(jù)結(jié)構(gòu),此外單個(gè)value的最大限制是1GB,不像 memcached只能保存1MB的數(shù)據(jù)。
因此Redis可以用來(lái)實(shí)現(xiàn)很多有用的功能,比方說(shuō)用他的List來(lái)做FIFO雙向鏈表,實(shí)現(xiàn)一個(gè)輕量級(jí)的高性 能消息隊(duì)列服務(wù),用他的Set可以做高性能的tag系統(tǒng)等等。
另外Redis也可以對(duì)存入的Key-Value設(shè)置expire時(shí)間,因此也可以被當(dāng)作一 個(gè)功能加強(qiáng)版的memcached來(lái)用。
Redis的主要缺點(diǎn)是數(shù)據(jù)庫(kù)容量受到物理內(nèi)存的限制,不能用作海量數(shù)據(jù)的高性能讀寫(xiě),因此Redis適合的場(chǎng)景主要局限在較小數(shù)據(jù)量的高性能操作和運(yùn)算上。
3.使用redis有哪些好處?
速度快:因?yàn)閿?shù)據(jù)存在內(nèi)存中,類(lèi)似于HashMap,HashMap的優(yōu)勢(shì)就是查找和操作的時(shí)間復(fù)雜度都是O(1)
支持豐富數(shù)據(jù)類(lèi)型:支持string,list,set,sorted set,hash
支持事務(wù):操作都是原子性,所謂的原子性就是對(duì)數(shù)據(jù)的更改要么全部執(zhí)行,要么全部不執(zhí)行
豐富的特性:可用于緩存,消息,按key設(shè)置過(guò)期時(shí)間,過(guò)期后將會(huì)自動(dòng)刪除
4.redis相比memcached有哪些優(yōu)勢(shì)?
memcached所有的值均是簡(jiǎn)單的字符串,redis作為其替代者,支持更為豐富的數(shù)據(jù)類(lèi)型
redis的速度比memcached快很多
redis可以持久化其數(shù)據(jù)
5.Memcache與Redis的區(qū)別都有哪些?
存儲(chǔ)方式:Memecache把數(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)方式 以及與客戶(hù)端之間通信的應(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)求。?
6.redis常見(jiàn)性能問(wèn)題和解決方案:
1).Master寫(xiě)內(nèi)存快照,save命令調(diào)度rdbSave函數(shù),會(huì)阻塞主線程的工作,當(dāng)快照比較大時(shí)對(duì)性能影響是非常大的,會(huì)間斷性暫停服務(wù),所以Master最好不要寫(xiě)內(nèi)存快照。
2).Master AOF持久化,如果不重寫(xiě)AOF文件,這個(gè)持久化方式對(duì)性能的影響是最小的,但是AOF文件會(huì)不斷增大,AOF文件過(guò)大會(huì)影響Master重啟的恢復(fù)速度。
Master最好不要做任何持久化工作,包括內(nèi)存快照和AOF日志文件,特別是不要啟用內(nèi)存快照做持久化,如果數(shù)據(jù)比較關(guān)鍵,某個(gè)Slave開(kāi)啟AOF備份數(shù)據(jù),策略為每秒同步一次。
3).Master調(diào)用BGREWRITEAOF重寫(xiě)AOF文件,AOF在重寫(xiě)的時(shí)候會(huì)占大量的CPU和內(nèi)存資源,導(dǎo)致服務(wù)load過(guò)高,出現(xiàn)短暫服務(wù)暫?,F(xiàn)象。
4).Redis主從復(fù)制的性能問(wèn)題,為了主從復(fù)制的速度和連接的穩(wěn)定性,Slave和Master最好在同一個(gè)局域網(wǎng)內(nèi)
7.mySQL里有2000w數(shù)據(jù),redis中只存20w的數(shù)據(jù),如何保證redis中的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)
相關(guān)知識(shí):redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候,就會(huì)施行數(shù)據(jù)淘汰策略(回收策略)。redis 提供 6種數(shù)據(jù)淘汰策略:
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ù)
8.請(qǐng)用Redis和任意語(yǔ)言實(shí)現(xiàn)一段惡意登錄保護(hù)的代碼,限制1小時(shí)內(nèi)每用戶(hù)Id最多只能登錄5次。
具體登錄函數(shù)或功能用空函數(shù)即可,不用詳細(xì)寫(xiě)出。
用列表實(shí)現(xiàn):列表中每個(gè)元素代表登陸時(shí)間,只要最后的第5次登陸時(shí)間和現(xiàn)在時(shí)間差不超過(guò)1小時(shí)就禁止登陸。用Python寫(xiě)的代碼如下:
#!/usr/bin/env?python3 import?redis?? import?sys?? import?time??r?=?redis.StrictRedis(host=’127.0.0.1′,?port=6379,?db=0)?? try:???????id?=?sys.argv[1] except:??????print(‘input?argument?error’)????sys.exit(0)?? if?r.llen(id)?>=?5?and?time.time()?–?float(r.lindex(id,?4))?<=?3600:??????print(“you?are?forbidden?logining”) else:???????print(‘you?are?allowed?to?login’)????r.lpush(id,?time.time())????#?login_func()9.為什么redis需要把所有數(shù)據(jù)放到內(nèi)存中?
Redis為了達(dá)到最快的讀寫(xiě)速度將數(shù)據(jù)都讀到內(nèi)存中,并通過(guò)異步的方式將數(shù)據(jù)寫(xiě)入磁盤(pán)。所以redis具有快速和數(shù)據(jù)持久化的特征。
如果不將數(shù)據(jù)放在內(nèi)存中,磁盤(pán)I/O速度會(huì)嚴(yán)重影響redis的性能。在內(nèi)存越來(lái)越便宜的今天,redis將會(huì)越來(lái)越受歡迎。
如果設(shè)置了最大使用的內(nèi)存,則數(shù)據(jù)已有記錄數(shù)達(dá)到內(nèi)存限值后不能繼續(xù)插入新值。
10.Redis是單進(jìn)程單線程的
redis利用隊(duì)列技術(shù)將并發(fā)訪問(wèn)變?yōu)榇性L問(wèn),消除了傳統(tǒng)數(shù)據(jù)庫(kù)串行控制的開(kāi)銷(xiāo)。
11.redis的并發(fā)競(jìng)爭(zhēng)問(wèn)題如何解決?
Redis為單進(jìn)程單線程模式,采用隊(duì)列模式將并發(fā)訪問(wèn)變?yōu)榇性L問(wèn)。
Redis本身沒(méi)有鎖的概念,Redis對(duì)于多個(gè)客戶(hù)端連接并不存在競(jìng)爭(zhēng),但是在Jedis客戶(hù)端對(duì)Redis進(jìn)行并發(fā)訪問(wèn)時(shí)會(huì)發(fā)生連接超時(shí)、數(shù)據(jù)轉(zhuǎn)換錯(cuò)誤、阻塞、客戶(hù)端關(guān)閉連接等問(wèn)題,這些問(wèn)題均是
由于客戶(hù)端連接混亂造成。對(duì)此有2種解決方法:
客戶(hù)端角度,為保證每個(gè)客戶(hù)端間正常有序與Redis進(jìn)行通信,對(duì)連接進(jìn)行池化,同時(shí)對(duì)客戶(hù)端讀寫(xiě)Redis操作采用內(nèi)部鎖synchronized。
服務(wù)器角度,利用setnx實(shí)現(xiàn)鎖。
注:對(duì)于第一種,需要應(yīng)用程序自己處理資源的同步,可以使用的方法比較通俗,可以使用synchronized也可以使用lock;第二種需要用到Redis的setnx命令,但是需要注意一些問(wèn)題。
12.redis事物的了解CAS(check-and-set 操作實(shí)現(xiàn)樂(lè)觀鎖 )?
和眾多其它數(shù)據(jù)庫(kù)一樣,Redis作為NoSQL數(shù)據(jù)庫(kù)也同樣提供了事務(wù)機(jī)制。在Redis中,MULTI/EXEC/DISCARD/WATCH這四個(gè)命令是我們實(shí)現(xiàn)事務(wù)的基石。
相信對(duì)有關(guān)系型數(shù)據(jù)庫(kù)開(kāi)發(fā)經(jīng)驗(yàn)的開(kāi)發(fā)者而言這一概念并不陌生,即便如此,我們還是會(huì)簡(jiǎn)要的列出Redis中事務(wù)的實(shí)現(xiàn)特征:
在事務(wù)中的所有命令都將會(huì)被串行化的順序執(zhí)行,事務(wù)執(zhí)行期間,Redis不會(huì)再為其它客戶(hù)端的請(qǐng)求提供任何服務(wù),從而保證了事物中的所有命令被原子的執(zhí)行。
和關(guān)系型數(shù)據(jù)庫(kù)中的事務(wù)相比,在Redis事務(wù)中如果有某一條命令執(zhí)行失敗,其后的命令仍然會(huì)被繼續(xù)執(zhí)行。
我們可以通過(guò)MULTI命令開(kāi)啟一個(gè)事務(wù),有關(guān)系型數(shù)據(jù)庫(kù)開(kāi)發(fā)經(jīng)驗(yàn)的人可以將其理解為"BEGIN TRANSACTION"語(yǔ)句。
在該語(yǔ)句之后執(zhí)行的命令都將被視為事務(wù)之內(nèi)的操作,最后我們可以通過(guò)執(zhí)行EXEC/DISCARD命令來(lái)提交/回滾該事務(wù)內(nèi)的所有操作。這兩個(gè)Redis命令可被視為等同于關(guān)系型數(shù)據(jù)庫(kù)中的COMMIT/ROLLBACK語(yǔ)句。
在事務(wù)開(kāi)啟之前,如果客戶(hù)端與服務(wù)器之間出現(xiàn)通訊故障并導(dǎo)致網(wǎng)絡(luò)斷開(kāi),其后所有待執(zhí)行的語(yǔ)句都將不會(huì)被服務(wù)器執(zhí)行。
然而如果網(wǎng)絡(luò)中斷事件是發(fā)生在客戶(hù)端執(zhí)行EXEC命令之后,那么該事務(wù)中的所有命令都會(huì)被服務(wù)器執(zhí)行。
當(dāng)使用Append-Only模式時(shí),Redis會(huì)通過(guò)調(diào)用系統(tǒng)函數(shù)write將該事務(wù)內(nèi)的所有寫(xiě)操作在本次調(diào)用中全部寫(xiě)入磁盤(pán)。
然而如果在寫(xiě)入的過(guò)程中出現(xiàn)系統(tǒng)崩潰,如電源故障導(dǎo)致的宕機(jī),那么此時(shí)也許只有部分?jǐn)?shù)據(jù)被寫(xiě)入到磁盤(pán),而另外一部分?jǐn)?shù)據(jù)卻已經(jīng)丟失。
Redis服務(wù)器會(huì)在重新啟動(dòng)時(shí)執(zhí)行一系列必要的一致性檢測(cè),一旦發(fā)現(xiàn)類(lèi)似問(wèn)題,就會(huì)立即退出并給出相應(yīng)的錯(cuò)誤提示。
此時(shí),我們就要充分利用Redis工具包中提供的redis-check-aof工具,該工具可以幫助我們定位到數(shù)據(jù)不一致的錯(cuò)誤,并將已經(jīng)寫(xiě)入的部分?jǐn)?shù)據(jù)進(jìn)行回滾。修復(fù)之后我們就可以再次重新啟動(dòng)Redis服務(wù)器了。
13.WATCH命令和基于CAS的樂(lè)觀鎖:
在Redis的事務(wù)中,WATCH命令可用于提供CAS(check-and-set)功能。
假設(shè)我們通過(guò)WATCH命令在事務(wù)執(zhí)行之前監(jiān)控了多個(gè)Keys,倘若在WATCH之后有任何Key的值發(fā)生了變化,EXEC命令執(zhí)行的事務(wù)都將被放棄,同時(shí)返回Null multi-bulk應(yīng)答以通知調(diào)用者事務(wù)執(zhí)行失敗。
例如,我們?cè)俅渭僭O(shè)Redis中并未提供incr命令來(lái)完成鍵值的原子性遞增,如果要實(shí)現(xiàn)該功能,我們只能自行編寫(xiě)相應(yīng)的代碼。其偽碼如下:
??val?=?GET?mykeyval?=?val?+?1 SET?mykey?$val以上代碼只有在單連接的情況下才可以保證執(zhí)行結(jié)果是正確的,因?yàn)槿绻谕粫r(shí)刻有多個(gè)客戶(hù)端在同時(shí)執(zhí)行該段代碼,那么就會(huì)出現(xiàn)多線程程序中經(jīng)常出現(xiàn)的一種錯(cuò)誤場(chǎng)景--競(jìng)態(tài)爭(zhēng)用(race condition)。
比如,客戶(hù)端A和B都在同一時(shí)刻讀取了mykey的原有值,假設(shè)該值為10,此后兩個(gè)客戶(hù)端又均將該值加一后set回Redis服務(wù)器,這樣就會(huì)導(dǎo)致mykey的結(jié)果為11,而不是我們認(rèn)為的12。
為了解決類(lèi)似的問(wèn)題,我們需要借助WATCH命令的幫助,見(jiàn)如下代碼:
WATCH?mykeyval?=?GET?mykeyval?=?val?+?1 MULTISET?mykey?$val EXEC和此前代碼不同的是,新代碼在獲取mykey的值之前先通過(guò)WATCH命令監(jiān)控了該鍵,此后又將set命令包圍在事務(wù)中,這樣就可以有效的保證每個(gè)連接在執(zhí)行EXEC之前
如果當(dāng)前連接獲取的mykey的值被其它連接的客戶(hù)端修改,那么當(dāng)前連接的EXEC命令將執(zhí)行失敗。這樣調(diào)用者在判斷返回值后就可以獲悉val是否被重新設(shè)置成功。
14.redis持久化的幾種方式
1、快照(snapshots)
缺省情況情況下,Redis把數(shù)據(jù)快照存放在磁盤(pán)上的二進(jìn)制文件中,文件名為dump。rdb。你可以配置Redis的持久化策略,例如數(shù)據(jù)集中每N秒鐘有超過(guò)M次更新,就將數(shù)據(jù)寫(xiě)入磁盤(pán);或者你可以手工調(diào)用命令SAVE或BGSAVE。
工作原理
Redis forks。
子進(jìn)程開(kāi)始將數(shù)據(jù)寫(xiě)到臨時(shí)RDB文件中。
當(dāng)子進(jìn)程完成寫(xiě)RDB文件,用新文件替換老文件。
這種方式可以使Redis使用copy-on-write技術(shù)。
2、AOF
快照模式并不十分健壯,當(dāng)系統(tǒng)停止,或者無(wú)意中Redis被kill掉,最后寫(xiě)入Redis的數(shù)據(jù)就會(huì)丟失。這對(duì)某些應(yīng)用也許不是大問(wèn)題,但對(duì)于要求高可靠性的應(yīng)用來(lái)說(shuō),Redis就不是一個(gè)合適的選擇。
Append-only文件模式是另一種選擇。你可以在配置文件中打開(kāi)AOF模式。
3、虛擬內(nèi)存方式
當(dāng)你的key很小而value很大時(shí),使用VM的效果會(huì)比較好。因?yàn)檫@樣節(jié)約的內(nèi)存比較大。當(dāng)你的key不小時(shí),可以考慮使用一些非常方法將很大的key變成很大的value,比如你可以考慮將key,value組合成一個(gè)新的value。
vm-max-threads這個(gè)參數(shù),可以設(shè)置訪問(wèn)swap文件的線程數(shù),設(shè)置最好不要超過(guò)機(jī)器的核數(shù),如果設(shè)置為0,那么所有對(duì)swap文件的操作都是串行的。可能會(huì)造成比較長(zhǎng)時(shí)間的延遲,但是對(duì)數(shù)據(jù)完整性有很好的保證。
自己測(cè)試的時(shí)候發(fā)現(xiàn)用虛擬內(nèi)存性能也不錯(cuò)。如果數(shù)據(jù)量很大,可以考慮分布式或者其他數(shù)據(jù)庫(kù)
15.redis的緩存失效策略和主鍵失效機(jī)制
作為緩存系統(tǒng)都要定期清理無(wú)效數(shù)據(jù),就需要一個(gè)主鍵失效和淘汰策略。
在Redis當(dāng)中,有生存期的key被稱(chēng)為volatile。在創(chuàng)建緩存時(shí),要為給定的key設(shè)置生存期,當(dāng)key過(guò)期的時(shí)候(生存期為0),它可能會(huì)被刪除。
1、影響生存時(shí)間的一些操作
生存時(shí)間可以通過(guò)使用 DEL 命令來(lái)刪除整個(gè) key 來(lái)移除,或者被 SET 和 GETSET 命令覆蓋原來(lái)的數(shù)據(jù),也就是說(shuō),修改key對(duì)應(yīng)的value和使用另外相同的key和value來(lái)覆蓋以后,當(dāng)前數(shù)據(jù)的生存時(shí)間不同。
比如說(shuō),對(duì)一個(gè) key 執(zhí)行INCR命令,對(duì)一個(gè)列表進(jìn)行LPUSH命令,或者對(duì)一個(gè)哈希表執(zhí)行HSET命令,這類(lèi)操作都不會(huì)修改 key 本身的生存時(shí)間。另一方面,如果使用RENAME對(duì)一個(gè) key 進(jìn)行改名,那么改名后的 key的生存時(shí)間和改名前一樣。
RENAME命令的另一種可能是,嘗試將一個(gè)帶生存時(shí)間的 key 改名成另一個(gè)帶生存時(shí)間的 another_key ,這時(shí)舊的 another_key (以及它的生存時(shí)間)會(huì)被刪除,然后舊的 key 會(huì)改名為 another_key?
因此,新的 another_key 的生存時(shí)間也和原本的 key 一樣。使用PERSIST命令可以在不刪除 key 的情況下,移除 key 的生存時(shí)間,讓 key 重新成為一個(gè)persistent key 。
2、如何更新生存時(shí)間
可以對(duì)一個(gè)已經(jīng)帶有生存時(shí)間的 key 執(zhí)行EXPIRE命令,新指定的生存時(shí)間會(huì)取代舊的生存時(shí)間。過(guò)期時(shí)間的精度已經(jīng)被控制在1ms之內(nèi),主鍵失效的時(shí)間復(fù)雜度是O(1),EXPIRE和TTL命令搭配使用,TTL可以查看key的當(dāng)前生存時(shí)間。設(shè)置成功返回 1;當(dāng) key 不存在或者不能為 key 設(shè)置生存時(shí)間時(shí),返回 0 。
最大緩存配置
在 redis 中,允許用戶(hù)設(shè)置最大使用內(nèi)存大小,server。maxmemory默認(rèn)為0,沒(méi)有指定最大緩存,如果有新的數(shù)據(jù)添加,超過(guò)最大內(nèi)存,則會(huì)使redis崩潰,所以一定要設(shè)置。redis 內(nèi)存數(shù)據(jù)集大小上升到一定大小的時(shí)候,就會(huì)實(shí)行數(shù)據(jù)淘汰策略。
redis 提供 6種數(shù)據(jù)淘汰策略:
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ù)
注意這里的6種機(jī)制,volatile和allkeys規(guī)定了是對(duì)已設(shè)置過(guò)期時(shí)間的數(shù)據(jù)集淘汰數(shù)據(jù)還是從全部數(shù)據(jù)集淘汰數(shù)據(jù),后面的lru、ttl以及random是三種不同的淘汰策略,再加上一種no-enviction永不回收的策略。
使用策略規(guī)則:
如果數(shù)據(jù)呈現(xiàn)冪律分布,也就是一部分?jǐn)?shù)據(jù)訪問(wèn)頻率高,一部分?jǐn)?shù)據(jù)訪問(wèn)頻率低,則使用allkeys-lru
如果數(shù)據(jù)呈現(xiàn)平等分布,也就是所有的數(shù)據(jù)訪問(wèn)頻率都相同,則使用allkeys-random
三種數(shù)據(jù)淘汰策略:
ttl和random比較容易理解,實(shí)現(xiàn)也會(huì)比較簡(jiǎn)單。主要是Lru最近最少使用淘汰策略,設(shè)計(jì)上會(huì)對(duì)key 按失效時(shí)間排序,然后取最先失效的key進(jìn)行淘汰。
16.redis 最適合的場(chǎng)景
Redis最適合所有數(shù)據(jù)in-momory的場(chǎng)景,雖然Redis也提供持久化功能,但實(shí)際更多的是一個(gè)disk-backed的功能,跟傳統(tǒng)意義上的持久化有比較大的差別
那么可能大家就會(huì)有疑問(wèn),似乎Redis更像一個(gè)加強(qiáng)版的Memcached,那么何時(shí)使用Memcached,何時(shí)使用Redis呢?
如果簡(jiǎn)單地比較Redis與Memcached的區(qū)別,大多數(shù)都會(huì)得到以下觀點(diǎn):
Redis不僅僅支持簡(jiǎn)單的k/v類(lèi)型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的存儲(chǔ)。
Redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份。
Redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保持在磁盤(pán)中,重啟的時(shí)候可以再次加載進(jìn)行使用。
(1)會(huì)話緩存(Session Cache)
最常用的一種使用Redis的情景是會(huì)話緩存(session cache)。
用Redis緩存會(huì)話比其他存儲(chǔ)(如Memcached)的優(yōu)勢(shì)在于:Redis提供持久化。當(dāng)維護(hù)一個(gè)不是嚴(yán)格要求一致性的緩存時(shí),如果用戶(hù)的購(gòu)物車(chē)信息全部丟失,大部分人都會(huì)不高興的,現(xiàn)在,他們還會(huì)這樣嗎?
幸運(yùn)的是,隨著 Redis 這些年的改進(jìn),很容易找到怎么恰當(dāng)?shù)氖褂肦edis來(lái)緩存會(huì)話的文檔。甚至廣為人知的商業(yè)平臺(tái)Magento也提供Redis的插件。
(2)全頁(yè)緩存(FPC)
除基本的會(huì)話token之外,Redis還提供很簡(jiǎn)便的FPC平臺(tái)?;氐揭恢滦詥?wèn)題,即使重啟了Redis實(shí)例,因?yàn)橛写疟P(pán)的持久化,用戶(hù)也不會(huì)看到頁(yè)面加載速度的下降,這是一個(gè)極大改進(jìn),類(lèi)似PHP本地FPC。
再次以Magento為例,Magento提供一個(gè)插件來(lái)使用Redis作為全頁(yè)緩存后端。
此外,對(duì)WordPress的用戶(hù)來(lái)說(shuō),Pantheon有一個(gè)非常好的插件 wp-redis,這個(gè)插件能幫助你以最快速度加載你曾瀏覽過(guò)的頁(yè)面。
(3)隊(duì)列
Reids在內(nèi)存存儲(chǔ)引擎領(lǐng)域的一大優(yōu)點(diǎn)是提供 list 和 set 操作,這使得Redis能作為一個(gè)很好的消息隊(duì)列平臺(tái)來(lái)使用。Redis作為隊(duì)列使用的操作,就類(lèi)似于本地程序語(yǔ)言(如Python)對(duì) list 的 push/pop 操作。
如果你快速的在Google中搜索“Redis queues”,你馬上就能找到大量的開(kāi)源項(xiàng)目,這些項(xiàng)目的目的就是利用Redis創(chuàng)建非常好的后端工具,以滿足各種隊(duì)列需求。例如,Celery有一個(gè)后臺(tái)就是使用Redis作為broker,你可以從這里去查看。
(4)排行榜/計(jì)數(shù)器
Redis在內(nèi)存中對(duì)數(shù)字進(jìn)行遞增或遞減的操作實(shí)現(xiàn)的非常好。集合(Set)和有序集合(Sorted Set)也使得我們?cè)趫?zhí)行這些操作的時(shí)候變的非常簡(jiǎn)單,Redis只是正好提供了這兩種數(shù)據(jù)結(jié)構(gòu)。
所以,我們要從排序集合中獲取到排名最靠前的10個(gè)用戶(hù)–我們稱(chēng)之為“user_scores”。
當(dāng)然,這是假定你是根據(jù)你用戶(hù)的分?jǐn)?shù)做遞增的排序。如果你想返回用戶(hù)及用戶(hù)的分?jǐn)?shù),你需要這樣執(zhí)行:
ZRANGE?user_scores?0?10?WITHSCORESAgora Games就是一個(gè)很好的例子,用Ruby實(shí)現(xiàn)的,它的排行榜就是使用Redis來(lái)存儲(chǔ)數(shù)據(jù)的,你可以在這里看到。
(5)發(fā)布/訂閱
最后(但肯定不是最不重要的)是Redis的發(fā)布/訂閱功能。
發(fā)布/訂閱的使用場(chǎng)景確實(shí)非常多,我已看見(jiàn)人們?cè)谏缃痪W(wǎng)絡(luò)連接中使用,還可作為基于發(fā)布/訂閱的腳本觸發(fā)器,甚至用Redis的發(fā)布/訂閱功能來(lái)建立聊天系統(tǒng)!(不,這是真的,你可以去核實(shí))。
Redis提供的所有特性中,我感覺(jué)這個(gè)是喜歡的人最少的一個(gè),雖然它為用戶(hù)提供如此多功能。
作者:回首笑人間
https://www.cnblogs.com/Survivalist/p/8119891.html
IT技術(shù)分享社區(qū)
文章推薦程序員效率:畫(huà)流程圖常用的工具程序員效率:整理常用的在線筆記軟件遠(yuǎn)程辦公:常用的遠(yuǎn)程協(xié)助軟件,你都知道嗎?51單片機(jī)程序下載、ISP及串口基礎(chǔ)知識(shí)硬件:斷路器、接觸器、繼電器基礎(chǔ)知識(shí)
總結(jié)
以上是生活随笔為你收集整理的收集Redis16个最常见面试问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [软件应用]常用软件名录
- 下一篇: opencv学习笔记2--存取图像元素